I have a kvm host. Defined a bridge, kvm guest joined to the bridge. Everything seems to work.
However, I would like to filter traffic to/from guest on the host, but for the life of me, cannot figure out if nwfilter works on rocky at all.
I assign a filter on the guest VM network interface in XML: <filterref filter="testing"/>. As soon as i start the guest VM with this, there is no traffic in or out. Even though the filter testing currently contains:
One potential thing is nftables. Kernel of Rocky has nftables. At least the âiptablesâ is just a wrapper that translates iptables-syntax rules into nftables (and back). I have no idea whether libvirtd&co use iptables-syntax or do they use nftables directly for some rules.
As @jlehtone said, Rocky 8.5 like RHEL 8.x uses firewalld with nftables, this behaviour can be changed though by editing /etc/firewalld/firewalld.conf:
the backend can be reverted to iptables like it was in RHEL7. If you are unable to get it to work with firewalld or libvirt forces uses of iptables, then you can always revert firewalld by editing that file and restarting it. You may wish to completely reboot the server though as Iâve had issues before under Debian/Ubuntu when changing firewalld from iptables to nftables as they default to iptables.
Yes and no, AFAIK. Yes, the firewalld.service can call âiptablesâ instead of directly using the nftables-library that nft uses. That is, firewalld can generate rules in âiptables syntaxâ or in ânftables syntaxâ.
However, the âiptablesâ is not the iptables-legacy that talks to netfilter subsystem within kernel. The âiptablesâ is a disguised version of nft that takes âiptables syntaxâ and talks to nftables subsystem within kernel in ânftables syntaxâ just like the nft does. Granted, nftables subsystem does use some features of netfilter subsystem, rather than reimplementing everything.
Where does this show, if anywhere? Logical scenarios are that (A) libvirt talks to firewalld and (B) both libvirtd and firewalld talk to kernel. In case A access to kernel is consistent. In case B there are âtwo chefs on the soupâ. In both cases all communication could be in one syntax (iptables?), or there is a mix that parts of ruleset mimics âgood oldâ netfilter chains and part are âplain nftâ.
There is an extra twist: bridged traffic is not filtered by default. (It has never been filtered by default in RHEL systems). There was time, when it was not possible at all. Then there was third-party kernel module that made bridged traffic visit the netfilter. Module like that became native, but RHEL explicitly disabled it in config. Now the module is no longer loaded automatically when you create a bridge.
By that, KVM must load the kernel module and re-enable the filtering in config (after default disable), if nwfilter is defined. That is the only explanation why anything (bridged) gets filtered.
@jlehtone very informative. It would be good to get to a situation where everything talks via firewalld, that way it doesnât matter what the backend would be, be it nftables or iptables or whatever else may appear in the future. Iâve seen this for example with docker, it would create itself iptables rules even when firewalld was active with nftables. Had it used firewalld syntax for adding rules, it wouldnât have mattered which was being used. Didnât dig any further to see if I could change it, but did notice it at least.
Again, yes and no. The firewalld.service is indeed the default, but there is also nftables.service that Red Hat recommends for âserious useâ (since FirewallD still lacks support for some âusual scenariosâ).
If I donât use firewalld and service xyz talks only to FirewallD, then what do I do?
In earlier EL (6 or 7) the libvirtd injects rules directly to backend, into âINPUT/FORWARDâ chains. At least once I did modify libvirtd-scripts (point of rule insertion) so that my unrelated custom rule remained first in chain. In EL8 libvirtd creates named chains that are more controllable? (I have mainly bridged setups without any VM filter on host-side.)
I admit I am a bit overwhelmed at the nft ruleset I am seeing (more familiar with iptables). Rules seem to be created in nftables, but they seem to have no effect.
For instance, want to allow port 3389 to a guest VM. In guest bridged network conf i have:
nft ruleset could be very compact. Alas, firewalld tends to be very verbose, with intricate hierarchies of chains. That is for achieving machine actionability, I presume.
POSTROUTING is after all filtering steps. Where are rules that could write to logs?
(I donât recall any âlogâ rules in the default ruleset.)
The default/final filter rule is typically:
reject with icmpx type admin-prohibited
Furthermore, there can be multiple chains on same hook with different priorities and the effective result takes a lot to grok.
Furthermore, dumping just the firewalldâs ruleset an the firewalld+libvirt ruleset ⌠getting diff of those is not easy, not to mention that the reject could be in plain firewalld part.
As a test, I decided to forget the nwfilter side of things and try to create rules for bridge directly according to this: Bridge filtering - nftables wiki
However (no doubt resulting from some mistake or assumption i made), when i do:
# nft add table bridge filter
# nft add chain bridge filter forward '{type filter hook forward priority 0; }'
# nft add rule bridge filter forward ct state established,related accept
Error: Could not process rule: Protocol error
add rule bridge filter forward ct state established,related accept
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
can anyone shed a light on the last error (google is not my friend)?
Replying to myself here, in case someone else stumbles upon the same issue. nft ct state rules are not supported by the 4.8 kernel that is shipped with Rocky Linux 8 by default. Installing kernel-lt 5.4 from EPEL repo fixes it.