firewalld direct rules with ACCEPT not working on RHEL 8, 9 and 10
Environment
- Red Hat Enterprise Linux 8
- Red Hat Enterprise Linux 9
- Red Hat Enterprise Linux 10
- firewalld (with default
nftablesbackend) - Direct firewall rule with
-j ACCEPTto allow traffic
Issue
- Direct rules with ACCEPT verdict not working with nftables backend
-
Even though
httpd.serviceandfirewalld.serviceare running, allowing port 80 through direct rules does not provide access to the webserver:systemctl start httpd.service systemctl start firewalld.service firewall-cmd --direct --add-rule ipv4 filter INPUT 1 -p tcp --dport 80 -j ACCEPT -
Client can't accesss, gets
No route to hosterror. -
Changing from
FirewallBackend=nftablestoFirewallBackend=iptablesthe direct rule works. -
Connectivity not working between servers when firewall getting started in RHEL8
-
firewalld
direct.xmlfrom RHEL 7 no longer works on RHEL 8 -
How do direct rules work with firewalld when firewalld uses nftables?
Resolution
This is expected behaviour due to the way the nftables firewall works, as explained in the below Root Cause section.
It is necessary to change the firewall rules to match the behaviour of the firewall.
The following options are recommended ways to resolve this:
- Any traffic with a direct
-j ACCEPTrule should also be allowed in the firewalld firewall - Don't use
-j ACCEPTin direct rules, make sure allowed traffic is handled by firewalld - Change to use the nftables service directly, instead of firewalld plus direct rules
The following options are possible but not recommended:
- Change firewalld to use the iptables backend, with
FirewallBackend=iptablesinfirewalld.conf - Change to use the iptables service only, instead of firewalld plus direct rules
Root Cause
The man 5 firewalld.direct manual page contains the following explanation:
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.
The nftables wiki page Content from wiki.nftables.org is not included.Base chain priority also explains the behavior:
If a packet is accepted and there is another chain, bearing the same hook type and with a later priority, then the packet will subsequently traverse this other chain. Hence, an accept verdict - be it by way of a rule or the default chain policy - isn't necessarily final. However, the same is not true of packets that are subjected to a drop verdict. Instead, drops take immediate effect, with no further rules or chains being evaluated.
This was discusssed with Fedora development on This content is not included.Red Hat Bug 1837129 - Direct rules with ACCEPT verdict not working with nftables backend and CLOSED CANTFIX a known documented behaviour change between iptables and nftables.
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.