Fedora Account System
Red Hat Associate
Red Hat Customer
Description of problem: After upgrading to Fedora 32, firewalld uses nftables backend by default. I've switched iptables command line utilities to use alternative provided by iptables-nft. Unfortunately, firewalld doesn't support packet forwarding rules, so the only way to allow packet forwarding is using direct rules. However, when I add a direct rule to FORWARD chain with ACCEPT verdict, it's not honoured. Version-Release number of selected component (if applicable): 0.8.2 How reproducible: Always. Steps to Reproduce: 1. Configure firewalld with at least two zones (say, external and internal). 2. Add direct rule using FORWARD chain allowing connections to some host in internal zone: firewall-cmd --direct --add-rule ipv6 filter FORWARD -200 -d XXXX:XXXX:XXXX:1::1 -p tcp -m tcp --dport 22 -j ACCEPT (where XXXX:XXXX:XXXX:1::1 is IPv6 address of a host behind an interface in internal zone). 3. Try to connect to this IPv6 address from outside. Actual results: telnet: connect to address XXXX:XXXX:XXXX:1::1: Permission denied Expected results: Successful connection. Additional info: nft -y list ruleset shows the following: table ip6 filter { ... chain FORWARD { type filter hook forward priority 0; policy accept; meta l4proto tcp ip6 daddr XXXX:XXXX:XXXX:1::1 tcp dport 22 counter packets 4 bytes 320 accept } ... } ... table inet firewalld { ... chain filter_FORWARD { type filter hook forward priority 10; policy accept; ct state { established, related } accept ct status dnat accept iifname "lo" accept ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } log prefix "RFC3964_IPv4_REJECT: " reject with icmpv6 type addr-unreachable jump filter_FORWARD_IN_ZONES jump filter_FORWARD_OUT_ZONES ct state { invalid } log prefix "STATE_INVALID_DROP: " ct state { invalid } drop log prefix "FINAL_REJECT: " reject with icmpx type admin-prohibited } ... } ... This means that firewalld adds rules it generates to firewalld table, whereas direct rules are added to filter table. And although FORWARD chain of filter table has higher priority than filter_FORWARD chain of firewalld table, accept statement finishes just FORWARD chain of filter table, not all chains. This is documented behaviour. From https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains : > *NOTE:* if a packet gets accepted and there is another base chain in the same hook which is ordered with a later priority, the packet will be evaluated *again*. That is, packets will traverse chains in a given hook, until it is dropped or no more base chains exist. Drops take instant effect, no further rules or chains are evaluated. In order to make direct rules with ACCEPT verdict work, they should be added to a chain inside firewalld table that is jumped to from filter_FORWARD chain, not to a separate base chain in a separate table.
This is known. See the Change [1]. It explains the behavior. See also the firewalld.direct(5) man page CAVEATS section [2]. firewalld upstream is working on full forward/output support [3]. But it's not ready yet. Your workaround options are: 1) revert to the iptables backend by setting FirewallBackend=iptables in /etc/firewalld/firewalld.conf 2) Add the relevant interfaces/sources to the trusted zone and do all your filtering in the direct interface. [1]: https://fedoraproject.org/wiki/Changes/firewalld_default_to_nftables#Upgrade.2Fcompatibility_impact [2]: https://firewalld.org/documentation/man-pages/firewalld.direct.html [3]: https://github.com/orgs/firewalld/projects/1#card-25963208