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