On Sat, Jul 25, 2020 at 10:31:01PM -0400, Gunnar Niels wrote:
I've been continuing to experiment with firewalld and learn the
underlying
userspace tools like iptables and nft for expressing firewall rules, but from
what I've been reading, it seems like nftables is intended to replace iptables,
which is possibly heading towards deprecation (if anyone can shed some light
on that, would be much appreciated)?
Yes. That's accurate.
Maybe this blog will help:
https://firewalld.org/2018/07/nftables-backend
If that's true, it appears that firewalld whever it is in use
still
needs to work on top of *both* iptables and nftables. When I add a
direct rule, that gets added directly to the cooresponding iptables
chain, while rich rules look like they are added to nftable chains.
Also correct. With the nftables backend all the firewalld primitives:
services, ports, forward-ports, masquerade, etc use nftables. But direct
rules will still use iptables. The --direct feature is really a thin
wrapper around iptables/ebtables. firewalld will _not_ translate
iptables into nftables. That's a task doomed for failure as it would
never be 100% correct.
I'm working on my Arch Linux workstation, but I'm also
responsible for
a number RHEL/CentOS boxes that I'd like to upgrade to their respective
v8 editions, but I'd really like a rock solid understanding of
firewalld and the systems underneath before I'm comfortable in
productions.
So how do iptables and nftables work in conjunction with one another when they
seem like they potentially could hold conflicting rules? Is there some order
of precedence where these are ultiately boiled down to a single golden
source of rules within the kernel?
I think the "Behavioral Changes" section of the above blog post covers
this. It's also covered in the CAVEATS section of man page
firewalld.direct(5).
Below is copy/pasted from the man page.
-->8--
CAVEATS
Depending on the value of FirewallBackend (see firewalld.conf(5)) direct
rules behave differently in some scenarios.
Packet accept/drop precedence
Due to implementation details of netfilter inside the kernel, if
FirewallBackend=nftables is used direct rules that ACCEPT packets
don't actually cause the packets to be immediately accepted by
the system. Those packets are still be subject to firewalld's
nftables ruleset. This basically means there are two independent
firewalls and packets must be accepted by both (iptables and
nftables). As an aside, this scenario also occurs inside of
nftables (again due to netfilter) if there are multiple chains
attached to the same hook - it's not as simple as iptables vs
nftables.
There are a handful of options to workaround the ACCEPT issue:
1. Rich Rules
If a rich rule can be used, then they should always be
preferred over direct rules. Rich Rules will be converted to
the enabled FirewallBackend. See firewalld.richlanguage(5).
2. Blanket Accept
Users can add an explicit accept to the nftables ruleset.
This can be done by adding the interface or source to the
trusted zone.
This strategy is often employed by things that perform their
own filtering such as: libvirt, podman, docker.
Warning: This means firewalld will do no filtering on these
packets. It must all be done via direct rules or out-of-band
iptables rules.
3. Selective Accept
Alternatively, enable only the relevant service, port,
address, or otherwise in the appropriate zone.
4. Revert to the iptables backend
A last resort is to revert to the iptables backend by setting
FirewallBackend=iptables. Users should be aware that
firewalld development focuses on the nftables backend.
For direct rules that DROP packets the packets are immediately
dropped regardless of the value of FirewallBackend. As such,
there is no special consideration needed.
Firewalld guarantees the above ACCEPT/DROP behavior by
registering nftables hooks with a lower precedence than iptables
hooks.
Direct interface precedence
With FirewallBackend=iptables firewalld's top-level internal
rules apply before direct rules are executed. This includes rules
to accept existing connections. In the past this has surprised
users. As an example, if a user adds a direct rule to drop
traffic on destination port 22 existing SSH sessions would
continue to function, but new connections would be denied.
With FirewallBackend=nftables direct rules were deliberately
given a higher precedence than all other firewalld rules. This
includes rules to accept existing connections.