firewalld — Dynamic Firewall Management on Linux

Practical guide to firewalld — zones, services, ports and rich rules with firewall-cmd, runtime and permanent rules on RHEL, Fedora and CentOS.

firewalld is the dynamic firewall daemon of RHEL, Fedora and CentOS, driven from the command line with firewall-cmd. Under the hood it builds on nftables (formerly iptables) and organises rules into zones – trust levels such as public or trusted that you assign interfaces, services and ports to. The crucial distinction is between runtime and permanent: changes without --permanent apply instantly but are lost on --reload or a reboot. This guide walks you through the commands you reach for daily, from zone status through services and ports to rich rules and NAT.

Status & Zones

firewall-cmd --state — Check if firewalld is running.

firewall-cmd --state

firewall-cmd --get-active-zones — Show active zones and their interfaces.

firewall-cmd --get-active-zones

firewall-cmd --get-default-zone — Show the default zone.

firewall-cmd --get-default-zone

firewall-cmd --set-default-zone=<zone> — Change the default zone. It affects every interface without an explicit zone, so check the current default before switching.

firewall-cmd --set-default-zone=public

firewall-cmd --list-all — List all settings for the default zone.

firewall-cmd --list-all

firewall-cmd --zone=<zone> --list-all — List all settings for a specific zone.

firewall-cmd --zone=public --list-all

firewall-cmd --get-zones — List all available zones.

firewall-cmd --get-zones

Services

firewall-cmd --add-service=<service> — Allow a service. Runtime only: lost on --reload or reboot. Use the trusted zone and broad --add-service rules sparingly.

firewall-cmd --add-service=http

firewall-cmd --add-service=<service> --permanent — Allow a service permanently.

firewall-cmd --add-service=https --permanent

firewall-cmd --remove-service=<service> --permanent — Remove a service permanently.

firewall-cmd --remove-service=ftp --permanent

firewall-cmd --list-services — List currently allowed services.

firewall-cmd --list-services

firewall-cmd --get-services — List all available predefined services.

firewall-cmd --get-services

firewall-cmd --info-service=<service> — Show details about a service (ports, protocols).

firewall-cmd --info-service=ssh

Ports

firewall-cmd --add-port=<port>/<proto> --permanent — Open a port permanently.

firewall-cmd --add-port=8080/tcp --permanent

firewall-cmd --add-port=<start>-<end>/<proto> --permanent — Open a range of ports permanently.

firewall-cmd --add-port=3000-3100/tcp --permanent

firewall-cmd --remove-port=<port>/<proto> --permanent — Close a port permanently.

firewall-cmd --remove-port=8080/tcp --permanent

firewall-cmd --list-ports — List all open ports.

firewall-cmd --list-ports

Rich Rules

firewall-cmd --add-rich-rule='rule family=ipv4 source address=<ip> accept' --permanent — Allow all traffic from a specific IP.

firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.5 accept' --permanent

firewall-cmd --add-rich-rule='rule family=ipv4 source address=<ip> drop' --permanent — Block all traffic from a specific IP.

firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.100 drop' --permanent

firewall-cmd --add-rich-rule='rule family=ipv4 source address=<ip> port port=<port> protocol=tcp accept' --permanent — Allow a specific IP to access a port.

firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.0/24 port port=3306 protocol=tcp accept' --permanent

firewall-cmd --list-rich-rules — List all rich rules.

firewall-cmd --list-rich-rules

firewall-cmd --remove-rich-rule='<rule>' --permanent — Remove a rich rule.

firewall-cmd --remove-rich-rule='rule family=ipv4 source address=10.0.0.5 accept' --permanent

Masquerade & Forwarding

firewall-cmd --add-masquerade --permanent — Enable masquerading (NAT).

firewall-cmd --add-masquerade --permanent

firewall-cmd --add-forward-port=port=<src>:proto=tcp:toport=<dest> --permanent — Forward a local port to another local port.

firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080 --permanent

firewall-cmd --add-forward-port=port=<src>:proto=tcp:toaddr=<ip>:toport=<dest> --permanent — Forward a port to a remote host.

firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.10:toport=8080 --permanent

firewall-cmd --query-masquerade — Check if masquerading is enabled.

firewall-cmd --query-masquerade

Runtime vs. Permanent

firewall-cmd --reload — Reload the firewall to apply permanent changes. Unsaved runtime changes are dropped in the process – to make a rule stick, combine --permanent with a following --reload.

firewall-cmd --reload

firewall-cmd --runtime-to-permanent — Save current runtime rules as permanent.

firewall-cmd --runtime-to-permanent

firewall-cmd --panic-on — Enable panic mode (block all traffic). Cuts existing connections immediately – on a remote server this locks out your own SSH session.

firewall-cmd --panic-on

firewall-cmd --panic-off — Disable panic mode.

firewall-cmd --panic-off

firewall-cmd --complete-reload — Complete reload that drops all runtime rules.

firewall-cmd --complete-reload

Conclusion

firewalld hides the nftables syntax and turns firewall management into a game of zones, services and ports. The most common pitfall remains the difference between runtime and permanent: feel free to test a rule at runtime first, but commit it with --permanent and reload the firewall once it works – otherwise it is gone after the next reboot.

Further Reading

  • age – modern, simple file encryption
  • clamav – open-source antivirus scanner
  • fail2ban – ban IPs after failed login attempts