Troubleshooting Firewalld Rules Not Appearing in iptables After CentOS 7 to 8 Upgrade


2 views

When performing a clean upgrade from CentOS 7 to CentOS 8, some users report firewalld services appearing active but no corresponding iptables rules being generated. This occurs even after:

systemctl enable firewalld
systemctl start firewalld
firewall-cmd --add-service http --permanent
firewall-cmd --add-service ssh --permanent
firewall-cmd --reload

The system shows firewalld as active with services listed:

firewall-cmd --list-all
public (active)
  target: default
  services: http ssh

Yet iptables remains empty:

iptables -nvL
Chain INPUT (policy ACCEPT)
Chain FORWARD (policy ACCEPT)  
Chain OUTPUT (policy ACCEPT)

In CentOS 8/RHEL 8, firewalld defaults to using nftables backend instead of iptables. The conversion occurs through these components:

firewalld (frontend) → nftables (backend) → kernel netfilter

To verify the actual firewall rules, use:

nft list ruleset

Option 1: Use nftables directly

View current rules with:

nft list table inet firewalld
nft list table ip firewalld
nft list table ip6 firewalld

Option 2: Switch to legacy iptables

If you specifically need iptables output:

update-alternatives --set iptables /usr/sbin/iptables-legacy
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
update-alternatives --set arptables /usr/sbin/arptables-legacy  
update-alternatives --set ebtables /usr/sbin/ebtables-legacy
systemctl restart firewalld

After making changes, verify with:

firewall-cmd --list-all
iptables -nvL
nft list ruleset
journalctl -u firewalld --no-pager -n 50

To persist the iptables-legacy setting across reboots:

echo 'IPTABLES_MODULES="iptable_filter iptable_nat"' > /etc/sysconfig/iptables-config
echo 'IP6TABLES_MODULES="ip6table_filter ip6table_nat"' > /etc/sysconfig/ip6tables-config

For deeper investigation:

firewall-cmd --debug
setenforce 0
systemctl stop firewalld
firewalld --debug

After upgrading from CentOS 7 to CentOS 8, many administrators notice that while firewalld appears to be functioning normally (showing services as added in firewall-cmd --list-all), no corresponding rules appear in iptables -nvL. This creates a potential security gap as traffic isn't being filtered as expected.

CentOS 8/RHEL 8 introduced a significant backend change:

# Check current firewall backend
firewall-cmd --get-backend

You'll likely see nftables instead of iptables. This explains why traditional iptables commands show empty rulesets - firewalld is now using nftables as its default backend.

To inspect the effective firewall rules, use these alternatives:

# Method 1: View nftables rules directly
nft list ruleset

# Method 2: Use firewalld's debug mode
firewall-cmd --debug=10 --reload
journalctl -xe -u firewalld

# Method 3: Check kernel logs
dmesg | grep -i firewall

You have several options to address this:

# Option 1: Switch back to iptables backend (not recommended long-term)
dnf install iptables-services
firewall-cmd --set-backend=iptables
systemctl restart firewalld

# Option 2: Work with nftables natively (recommended)
nft add table inet firewalld
nft add chain inet firewalld input { type filter hook input priority 0 \; }
nft add rule inet firewalld input tcp dport {22, 80} accept

# Option 3: Verify firewalld's zone configuration
firewall-cmd --get-active-zones
firewall-cmd --zone=public --list-all

If services still aren't working after verifying the rules:

# Check SELinux context
ausearch -m avc -ts recent

# Verify kernel modules
lsmod | grep nf_tables

# Test raw connectivity
nc -zv localhost 22
tcpdump -i eth0 port 80

For deeper investigation, check these log files:

  • /var/log/firewalld
  • /var/log/messages
  • journalctl -u firewalld --no-pager -n 50