firewalld is the default firewall management tool used on modern Linux distributions such as RHEL, Rocky Linux, AlmaLinux, Fedora, and CentOS. It provides a dynamic way to manage firewall rules without restarting the firewall service, which means existing network connections remain uninterrupted when rules are modified.
The primary command used to manage firewalld is firewall-cmd, which allows administrators to configure firewall zones, open or close ports, enable services, add rich rules, perform port forwarding, and inspect the current firewall configuration.
Unlike traditional firewall management tools such as iptables, firewalld introduces the concept of zones. Zones allow administrators to apply different security rules depending on the network environment (public, internal, trusted, etc.). This makes it easier to manage firewall configurations on systems with multiple interfaces or varying security requirements.
firewall-cmd Quick Cheat Sheet
The following quick reference table lists the most commonly used firewall-cmd commands, covering tasks such as managing services, opening ports, configuring zones, troubleshooting firewall rules, and applying advanced rules.
| Task | firewall-cmd Command |
|---|---|
| Check firewalld status | firewall-cmd --state |
| Start firewalld service | systemctl start firewalld |
| Enable firewalld on boot | systemctl enable firewalld |
| Restart firewalld service | systemctl restart firewalld |
| Reload firewall rules | firewall-cmd --reload |
| List all zones | firewall-cmd --get-zones |
| Show active zones | firewall-cmd --get-active-zones |
| Check default zone | firewall-cmd --get-default-zone |
| Change default zone | firewall-cmd --set-default-zone=public |
| List firewall rules for default zone | firewall-cmd --list-all |
| List firewall rules for specific zone | firewall-cmd --list-all --zone=public |
| List allowed services in a zone | firewall-cmd --list-services |
| List open ports | firewall-cmd --list-ports |
| Show configuration for all zones | firewall-cmd --list-all-zones |
| Allow a service (example: HTTP) | firewall-cmd --add-service=http |
| Allow HTTPS traffic | firewall-cmd --add-service=https |
| Allow SSH service | firewall-cmd --add-service=ssh |
| Remove a service | firewall-cmd --remove-service=http |
| Allow a service permanently | firewall-cmd --add-service=http --permanent |
| Allow port 8080 TCP | firewall-cmd --add-port=8080/tcp |
| Allow port 53 UDP | firewall-cmd --add-port=53/udp |
| Remove open port | firewall-cmd --remove-port=8080/tcp |
| Allow port permanently | firewall-cmd --add-port=8080/tcp --permanent |
| Allow traffic from specific IP | firewall-cmd --add-source=192.168.1.100 |
| Allow traffic from subnet | firewall-cmd --add-source=192.168.1.0/24 |
| Remove allowed IP | firewall-cmd --remove-source=192.168.1.100 |
| Assign interface to zone | firewall-cmd --zone=public --add-interface=eth0 |
| Check interface zone | firewall-cmd --get-zone-of-interface=eth0 |
| Move interface to different zone | firewall-cmd --zone=internal --change-interface=eth0 |
| Create a new zone | firewall-cmd --permanent --new-zone=myzone |
| Delete a zone | firewall-cmd --permanent --delete-zone=myzone |
| Enable masquerading (NAT) | firewall-cmd --add-masquerade |
| Enable NAT permanently | firewall-cmd --add-masquerade --permanent |
| Forward port 80 to 8080 | firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080 |
| Forward traffic to another host | firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.10 |
| Allow ping requests (ICMP) | firewall-cmd --add-icmp-block-inversion |
| Block ICMP ping requests | firewall-cmd --add-icmp-block=echo-request |
| Enable logging of dropped packets | firewall-cmd --set-log-denied=all |
| Create new IP set | firewall-cmd --permanent --new-ipset=myset --type=hash:ip |
| Add IP to IP set | firewall-cmd --permanent --ipset=myset --add-entry=10.0.0.1 |
| List IP set entries | firewall-cmd --permanent --ipset=myset --get-entries |
| Create rich rule allowing specific IP | firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.50 accept' |
| Block IP using rich rule | firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.50 drop' |
| Allow port for specific IP | firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.50 port port=22 protocol=tcp accept' |
| List rich rules | firewall-cmd --list-rich-rules |
| Show direct rules | firewall-cmd --direct --get-all-rules |
| Reset runtime rules to permanent rules | firewall-cmd --runtime-to-permanent |
| Restore firewalld default configuration | firewall-cmd --complete-reload |
Basic Firewalld Concepts Every Linux User Should Know
Firewalld Zones
A zone is a group of firewall rules that define the trust level for network connections. Each zone has its own rules regarding which services or ports are allowed.
Common firewalld zones include:
| Zone | Purpose |
|---|---|
| public | Default zone for untrusted networks such as the internet |
| internal | Used for internal networks where systems are trusted |
| home | Intended for home networks |
| work | Used for office networks |
| trusted | Accepts all network traffic |
| dmz | Used for servers exposed to external networks |
| drop | Silently drops all incoming packets |
| block | Rejects incoming traffic with an error response |
To list all available zones:
firewall-cmd --get-zones
To check the default zone currently used by the system:
firewall-cmd --get-default-zone
Network Interfaces
A network interface (for example eth0, ens33, or enp0s8) is assigned to a firewall zone. All traffic arriving through that interface is filtered according to the rules defined in the associated zone.
To list active zones and the interfaces assigned to them:
firewall-cmd --get-active-zones
To check which zone an interface belongs to:
firewall-cmd --get-zone-of-interface=eth0
Runtime vs Permanent Firewall Rules
Firewalld maintains two types of configurations:
| Configuration | Description |
|---|---|
| Runtime | Temporary rules active immediately but lost after reboot |
| Permanent | Rules stored on disk and preserved after reboot |
Example of adding a temporary rule:
firewall-cmd --add-service=http
Example of adding a permanent rule:
firewall-cmd --add-service=http --permanent
firewall-cmd --reload
Configure a Basic Firewall for a Linux Server
Allow SSH access safely
Before applying restrictive firewall rules, ensure that SSH access is allowed so that remote administration is not blocked.
firewall-cmd --add-service=ssh --permanent
firewall-cmd --reload
Allow HTTP and HTTPS for a web server
If the system is hosting a web server such as Apache or Nginx, open HTTP and HTTPS services.
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
firewall-cmd --reload
Block all other incoming traffic
You can enforce stricter security by using the default public zone and allowing only necessary services.
firewall-cmd --set-default-zone=public
Verify open ports and services
Check which services and ports are currently allowed through the firewall.
firewall-cmd --list-services
firewall-cmd --list-ports
Make rules persistent across reboot
If runtime rules were applied during testing, they can be saved permanently.
firewall-cmd --runtime-to-permanent
Open and Close Firewall Ports
Open a TCP port using firewall-cmd
To allow TCP traffic on port 8080:
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload
Open a UDP port using firewall-cmd
To allow UDP traffic on port 53 (commonly used for DNS):
firewall-cmd --add-port=53/udp --permanent
firewall-cmd --reload
Remove an open port from firewall
If a port is no longer needed, remove it from the firewall configuration.
firewall-cmd --remove-port=8080/tcp --permanent
firewall-cmd --reload
List all open firewall ports
To display all currently open ports:
firewall-cmd --list-ports
Check which zone contains the open port
To view detailed firewall configuration for a specific zone:
firewall-cmd --list-all --zone=public
Allow Access from Specific IP Address
Allow SSH access only from a trusted IP
Sometimes you may want to allow SSH access only from a trusted IP address instead of opening SSH access to the entire internet. This improves security by restricting administrative access.
Allow SSH only from a specific IP address:
firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept' --permanent
firewall-cmd --reload
Verify the rule:
firewall-cmd --list-rich-rules
Allow access from a subnet
If multiple systems in a network need access to a service, it is easier to allow access for the entire subnet.
Allow HTTP access from a subnet:
firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="http" accept' --permanent
firewall-cmd --reload
Block access from a malicious IP address
You can explicitly block traffic from a known malicious IP using rich rules.
Block a specific IP address:
firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.50" drop' --permanent
firewall-cmd --reload
Verify the rule:
firewall-cmd --list-rich-rules
Block a network range using firewalld
To block an entire network range:
firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" drop' --permanent
firewall-cmd --reload
This prevents all hosts from that subnet from accessing the server.
Managing Services Instead of Ports
Allow a predefined service in firewalld
Firewalld includes predefined services for many applications, which automatically open the required ports.
Example: Allow HTTP service:
firewall-cmd --add-service=http --permanent
firewall-cmd --reload
Allow HTTPS service:
firewall-cmd --add-service=https --permanent
firewall-cmd --reload
Remove an allowed service
If a service is no longer required, remove it from the firewall configuration.
Example: Remove HTTP service:
firewall-cmd --remove-service=http --permanent
firewall-cmd --reload
List allowed services in a zone
To view services allowed in the default zone:
firewall-cmd --list-services
To check services allowed in a specific zone:
firewall-cmd --list-services --zone=public
Create a custom firewalld service definition
Sometimes an application uses a non-standard port that does not exist in predefined services. In such cases, create a custom service definition.
Example service file:
/etc/firewalld/services/myapp.xml
Example contents:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>MyApp</short>
<description>Custom application service</description>
<port protocol="tcp" port="9000"/>
</service>
Reload firewalld and enable the service:
firewall-cmd --reload
firewall-cmd --add-service=myapp --permanent
firewall-cmd --reload
Working with Firewalld Zones in Real Environments
Assign interface to a specific zone
You can bind a network interface to a specific firewall zone.
Example: Assign interface eth0 to the public zone:
firewall-cmd --zone=public --add-interface=eth0 --permanent
firewall-cmd --reload
Change the default firewall zone
If most network interfaces should follow a different security policy, change the default zone.
Example:
firewall-cmd --set-default-zone=internal
Create a custom zone for application traffic
Create a new zone for a specific application environment.
Create zone:
firewall-cmd --permanent --new-zone=appzone
firewall-cmd --reload
Add an interface to this zone:
firewall-cmd --zone=appzone --add-interface=eth1 --permanent
firewall-cmd --reload
Move network interface between zones
If the network role changes, move an interface to a different zone.
Example:
firewall-cmd --zone=internal --change-interface=eth0 --permanent
firewall-cmd --reload
Compare public vs internal vs trusted zones
You can inspect configuration differences between zones.
View configuration of the public zone:
firewall-cmd --list-all --zone=public
View configuration of the internal zone:
firewall-cmd --list-all --zone=internal
View configuration of the trusted zone:
firewall-cmd --list-all --zone=trusted
Allow Traffic Between Internal Servers
Allow traffic from internal subnet
If servers communicate within a private network, allow traffic from that subnet.
Example:
firewall-cmd --add-source=10.10.10.0/24 --zone=internal --permanent
firewall-cmd --reload
Allow database communication between servers
Example: Allow MySQL access from internal subnet.
firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.10.10.0/24" port port="3306" protocol="tcp" accept' --permanent
firewall-cmd --reload
Allow NFS or shared storage traffic
For NFS servers, allow the NFS service:
firewall-cmd --add-service=nfs --permanent
firewall-cmd --reload
Verify services:
firewall-cmd --list-services
Restrict access to internal network only
You may want to expose services only to internal networks while blocking external access.
Allow internal subnet:
firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.10.10.0/24" accept' --permanent
Drop other external traffic:
firewall-cmd --set-default-zone=drop
firewall-cmd --reload
Configure Port Forwarding with Firewalld
Forward traffic from one port to another
Port forwarding allows incoming traffic on one port to be redirected to another port on the same server. This is useful when an application runs on a non-standard port.
Example: Forward traffic from port 80 to port 8080.
firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080 --permanent
firewall-cmd --reload
Make sure the destination port is also open:
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload
Redirect traffic to a different server
You can forward incoming traffic to another server in the network.
Example: Forward HTTP traffic to internal server 192.168.1.50.
firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.50 --permanent
firewall-cmd --reload
Use masquerading with NAT
Masquerading enables Network Address Translation (NAT) so that internal servers can access external networks through a gateway server.
Enable masquerading:
firewall-cmd --zone=public --add-masquerade --permanent
firewall-cmd --reload
Verify masquerading status:
firewall-cmd --zone=public --query-masquerade
Verify port forwarding configuration
To confirm the port forwarding rules:
firewall-cmd --list-forward-ports
You can also inspect the complete zone configuration:
firewall-cmd --list-all --zone=public
Advanced Firewalld Rich Rules
Allow access based on source IP and port
Rich rules allow more granular control over firewall behavior.
Example: Allow SSH access only from a specific IP.
firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.10" port port="22" protocol="tcp" accept' --permanent
firewall-cmd --reload
Reject specific traffic using rich rules
Instead of silently dropping packets, you can reject them so that the sender receives a response.
Example:
firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.10" reject' --permanent
firewall-cmd --reload
Log packets using rich rules
Logging rules help in monitoring suspicious traffic.
Example:
firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" log prefix="BLOCKED_TRAFFIC " level="info" drop' --permanent
firewall-cmd --reload
Limit connections using rich rules
You can restrict the number of connections from a source to mitigate brute-force attacks.
Example limiting SSH connections:
firewall-cmd --add-rich-rule='rule service name="ssh" limit value="5/m" accept' --permanent
firewall-cmd --reload
Allow traffic based on protocol
Instead of allowing ports, allow traffic based on a protocol.
Example allowing GRE protocol:
firewall-cmd --add-protocol=gre --permanent
firewall-cmd --reload
Managing Firewall Using IP Sets
IP sets allow you to manage large lists of IP addresses efficiently.
Create an IP set in firewalld
Create a new IP set named blocked_ips.
firewall-cmd --permanent --new-ipset=blocked_ips --type=hash:ip
firewall-cmd --reload
Add multiple IP addresses to IP set
Add entries to the IP set.
firewall-cmd --permanent --ipset=blocked_ips --add-entry=203.0.113.10
firewall-cmd --permanent --ipset=blocked_ips --add-entry=203.0.113.20
firewall-cmd --permanent --ipset=blocked_ips --add-entry=203.0.113.30
firewall-cmd --reload
Block all IP addresses in IP set
Attach the IP set to a restrictive zone such as drop.
firewall-cmd --permanent --zone=drop --add-source=ipset:blocked_ips
firewall-cmd --reload
Use IP set with rich rules
You can reference the IP set inside rich rules.
Example:
firewall-cmd --permanent --add-rich-rule='rule source ipset="blocked_ips" drop'
firewall-cmd --reload
Firewall Hardening Best Practices
Drop all unused incoming traffic
Using a restrictive default zone prevents unwanted access.
firewall-cmd --set-default-zone=drop
Disable unnecessary services
Remove services that are not required.
Example removing FTP service:
firewall-cmd --remove-service=ftp --permanent
firewall-cmd --reload
Restrict ICMP ping requests
Blocking ICMP requests can reduce exposure to certain scanning tools.
firewall-cmd --add-icmp-block=echo-request --permanent
firewall-cmd --reload
Enable firewall logging for security monitoring
Enable logging for dropped packets.
firewall-cmd --set-log-denied=all
Implement default deny policy
Allow only required services and block everything else.
Example allowing only SSH and HTTP:
firewall-cmd --add-service=ssh --permanent
firewall-cmd --add-service=http --permanent
firewall-cmd --set-default-zone=public
firewall-cmd --reload
Troubleshooting Firewalld Issues
Check active firewall zones
When troubleshooting connectivity issues, first verify which zones are currently active and which interfaces are assigned to them.
firewall-cmd --get-active-zones
This command shows active zones along with their associated network interfaces.
Check which zone a network interface belongs to
If traffic is not behaving as expected, check which zone an interface belongs to.
Example checking interface eth0:
firewall-cmd --get-zone-of-interface=eth0
If needed, inspect all zones and their configurations:
firewall-cmd --list-all-zones
Verify if a firewall rule is applied
To confirm that a rule is active, list services, ports, or rich rules configured in the firewall.
Check allowed services:
firewall-cmd --list-services
Check open ports:
firewall-cmd --list-ports
Check rich rules:
firewall-cmd --list-rich-rules
Debug firewalld configuration
If firewall behavior is unclear, enable debugging for the firewalld service.
Edit the firewalld configuration file:
vi /etc/sysconfig/firewalld
Add debug argument:
FIREWALLD_ARGS=--debug=10
Restart firewalld:
systemctl restart firewalld
You can then inspect system logs:
journalctl -xe | grep firewalld
Reset firewalld configuration to default
If the firewall configuration becomes inconsistent, you may reset it.
Stop firewalld:
systemctl stop firewalld
Remove custom configuration:
rm -rf /etc/firewalld/*
Reload default configuration:
systemctl start firewalld
Runtime vs Permanent Firewall Configuration
Understanding runtime firewall rules
Runtime rules are temporary rules applied immediately but not stored permanently. These rules are removed after reboot or service restart.
Example runtime rule:
firewall-cmd --add-service=http
Save runtime rules permanently
If runtime rules are working correctly and should persist across reboot, save them to the permanent configuration.
firewall-cmd --runtime-to-permanent
Reload firewall configuration safely
After adding permanent rules, reload the firewall configuration so that the changes become active.
firewall-cmd --reload
Convert runtime rules to permanent rules
If rules were applied during testing, convert them to permanent configuration.
Example workflow:
firewall-cmd --add-port=8080/tcp
firewall-cmd --runtime-to-permanent
Firewalld vs iptables vs nftables
How firewalld manages iptables rules
Firewalld is a high-level firewall manager that dynamically manages underlying firewall frameworks like iptables or nftables.
To inspect underlying iptables rules:
iptables -L -n -v
Firewalld dynamically updates these rules without restarting the firewall service.
firewalld backend change in RHEL 8 and newer
Earlier versions of RHEL used iptables as the backend. Newer versions such as RHEL 8, Rocky Linux 8, and AlmaLinux 8 use nftables as the backend.
To check the backend used by firewalld:
firewall-cmd --info-zone=public
When to use direct rules in firewalld
Direct rules allow administrators to apply raw iptables rules when advanced control is required.
Example:
firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 25 -j ACCEPT
Migrating from iptables to firewalld
Instead of manually writing iptables rules, use firewalld services, ports, and rich rules.
Example replacing an iptables rule:
iptables rule:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
Equivalent firewalld command:
firewall-cmd --add-service=http --permanent
firewall-cmd --reload
Firewalld for Cloud and DevOps Environments
Configure firewall for Kubernetes nodes
Kubernetes nodes require specific ports to communicate with the control plane.
Example allowing Kubernetes API server:
firewall-cmd --add-port=6443/tcp --permanent
Allow kubelet communication:
firewall-cmd --add-port=10250/tcp --permanent
Reload firewall:
firewall-cmd --reload
Allow traffic for Docker containers
Docker networking may require certain ports to be open.
Example allowing container traffic:
firewall-cmd --add-port=2375/tcp --permanent
firewall-cmd --reload
Configure firewall for cloud VM instances
Cloud instances often expose web applications.
Example opening web server ports:
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
firewall-cmd --reload
Restrict public access to internal services
Expose services only to private networks.
Example allowing internal subnet:
firewall-cmd --add-source=10.0.0.0/24 --zone=internal --permanent
firewall-cmd --reload
Verify and Audit Firewall Configuration
List complete firewall configuration
To review the full firewall configuration:
firewall-cmd --list-all-zones
Show active firewall rules
Check services, ports, and rich rules currently active.
firewall-cmd --list-all
Export firewalld configuration
Firewalld configuration files are stored in the following directories:
/etc/firewalld/
/usr/lib/firewalld/
You can back them up:
tar -czvf firewalld-backup.tar.gz /etc/firewalld
Audit firewall security settings
Review open ports and services regularly.
Check services:
firewall-cmd --list-services
Check open ports:
firewall-cmd --list-ports
Check IP sources allowed:
firewall-cmd --list-sources
Frequently Asked Questions
1. What is firewalld in Linux?
Firewalld is a dynamic firewall management tool in Linux that allows administrators to configure firewall rules using zones and services without restarting the firewall.2. What is firewall-cmd used for?
The firewall-cmd command is the command-line interface for managing firewalld. It allows administrators to add or remove ports, services, and rules, as well as list and manage firewall configurations.3. How do I list firewalld rules?
You can list firewalld rules using the firewall-cmd command. For example, run firewall-cmd –list-all to display all active firewall rules for the current zone.4. How do I allow a port in firewalld?
To allow a port using firewalld, run firewall-cmd –add-port=80/tcp. This opens the specified port in the active firewall zone.5. What is a rich rule in firewalld?
Rich rules in firewalld allow advanced firewall configuration such as allowing or blocking traffic based on source address, port, protocol, and logging rules.Conclusion
firewalld provides a modern and flexible way to manage firewall rules in Linux systems. Unlike traditional firewall tools that require service restarts when rules change, firewalld allows administrators to dynamically modify firewall configurations without interrupting existing network connections.
In this guide, we explored the most important firewall-cmd commands, including how to manage zones, services, ports, rich rules, and IP sets. We also covered practical scenarios such as configuring firewall rules for web servers, restricting access to specific IP addresses, implementing port forwarding, and hardening firewall security. These examples demonstrate how firewalld can be used to build secure and manageable firewall configurations for both standalone servers and enterprise environments.
Understanding the difference between runtime and permanent rules, using zones effectively, and applying rich rules for advanced filtering are key skills for system administrators managing Linux servers. By following the best practices discussed in this article, you can create firewall policies that improve system security while still allowing necessary network access for applications and services.
Whether you are managing a single Linux server, a cloud VM instance, or a containerized infrastructure environment, mastering the commands in this firewalld cheat sheet will help you quickly configure and troubleshoot firewall rules using firewall-cmd.
Further Reading
If you want to explore more topics related to Linux networking and firewall configuration, the following resources may be helpful.
Internal Tutorials
- How to Disable ICMP Redirects in Linux
- How to Prevent ICMP Ping Flood Attacks
- Disable ICMP Timestamp Responses in Linux
- netstat Command Examples in Linux
External Documentation

