Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-99480

firewalld: direct rules created does not work when firewalld used nftables as default backend

Linking RHIVOS CVEs to...Migration: Automation ...RHELPRIO AssignedTeam ...SWIFT: POC ConversionSync from "Extern...XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Can't Do
    • Icon: Undefined Undefined
    • None
    • rhel-10.0
    • firewalld
    • None
    • No
    • None
    • rhel-net-firewall
    • None
    • False
    • False
    • Hide

      None

      Show
      None
    • 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

      1. Add a direct rule using firewalld
      2. firewalld uses 'FirewallBackend=nftables' in /etc/firewalld.conf (default).
      3. 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 :

      1. 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.

       

              egarver Eric Garver
              rhn-support-surkumar Suresh Kumar
              Eric Garver Eric Garver
              Tomas Dolezal Tomas Dolezal
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: