-
Bug
-
Resolution: Can't Do
-
Undefined
-
None
-
rhel-10.0
-
None
-
No
-
None
-
rhel-net-firewall
-
None
-
False
-
False
-
-
None
-
None
-
None
-
None
-
Unspecified
-
Unspecified
-
Unspecified
-
-
All
-
None
What were you trying to do that didn't work?
Using direct rules in firewalld to allow traffic
What is the impact of this issue to you?
firewalld uses nftables are default backend. So it can severity impact customer once they migrate to firewalld. Services can stop.
Please provide the package NVR for which the bug is seen:
firewalld-2.3.0-2.el10.noarch
But I guess all previous versions of firewalld are affected. We even have a KCS which suggest use 'FirewallBackend=iptables' in firewalld.conf as workaround.
Ref:
--> firewalld direct rules with ACCEPT not working on RHEL 8, 9 and 10
https://access.redhat.com/solutions/6982051
So fixing this is important.
How reproducible is this bug?:
Always
Steps to reproduce
- Add a direct rule using firewalld
- firewalld uses 'FirewallBackend=nftables' in /etc/firewalld.conf (default).
- Check for service availability
Expected results
Firewalld allow traffic based on 'direct' rule added.
Actual results
Traffic blocked.
Test done:
==========
I have a direct rule in firewalld :
- firewall-cmd --direct --get-all-rules
ipv4 filter INPUT 1 -p tcp --dport 80 -j ACCEPT
The 'firewalld' add below nftable rules:
# nft list table 'ip filter'
table ip filter {
chain INPUT {
type filter hook input priority filter; policy accept;
tcp dport 80 counter packets 18 bytes 1000 accept
}
}
But traffic is still blocked. If I check 'inet firewalld' table, we can confirm the packet is dropped at below chain:
# nft insert rule 'inet firewalld filter_INPUT_POLICIES position 311 counter tcp dport 80 accept'
# nft -a list chain 'inet firewalld filter_INPUT_POLICIES'
table inet firewalld {
chain filter_INPUT_POLICIES { # handle 124
iifname "enp1s0" counter packets 38 bytes 4511 jump filter_IN_policy_allow-host-ipv6 # handle 307
iifname "enp1s0" counter packets 32 bytes 4079 jump filter_IN_public # handle 296
iifname "enp1s0" counter packets 32 bytes 4079 reject with icmpx admin-prohibited # handle 285
iifname "enp7s0" counter packets 45 bytes 4714 jump filter_IN_policy_allow-host-ipv6 # handle 341
iifname "enp7s0" counter packets 39 bytes 4282 jump filter_IN_public # handle 326
counter packets 2 bytes 120 tcp dport 80 accept # handle 344
iifname "enp7s0" counter packets 37 bytes 4162 reject with icmpx admin-prohibited # handle 311 <---- here
counter packets 0 bytes 0 jump filter_IN_policy_allow-host-ipv6 # handle 281
counter packets 0 bytes 0 jump filter_IN_public # handle 237
counter packets 0 bytes 0 reject with icmpx admin-prohibited # handle 230
}
}
I have added a counter for 'tcp dport 80' to confirm this.
If I add a 'accept' rule inside this chain, the connections are accepted:
table inet firewalld {
chain filter_INPUT_POLICIES { # handle 124
iifname "enp1s0" counter packets 38 bytes 4511 jump filter_IN_policy_allow-host-ipv6 # handle 307
iifname "enp1s0" counter packets 32 bytes 4079 jump filter_IN_public # handle 296
iifname "enp1s0" counter packets 32 bytes 4079 reject with icmpx admin-prohibited # handle 285
iifname "enp7s0" counter packets 45 bytes 4714 jump filter_IN_policy_allow-host-ipv6 # handle 341
iifname "enp7s0" counter packets 39 bytes 4282 jump filter_IN_public # handle 326
counter packets 2 bytes 120 tcp dport 80 accept # handle 344 <--------------- connections accepted.
iifname "enp7s0" counter packets 37 bytes 4162 reject with icmpx admin-prohibited # handle 311
counter packets 0 bytes 0 jump filter_IN_policy_allow-host-ipv6 # handle 281
counter packets 0 bytes 0 jump filter_IN_public # handle 237
counter packets 0 bytes 0 reject with icmpx admin-prohibited # handle 230
}
}
and no more drop seen for the clients trying to accept port 80 here.
So I guess the way 'firewalld' created table for 'direct' rule is the issue here. May be we can add a new set of chains (like filter_INPUT_DIRECT) inside 'inet firewalld' instead of a new table.