firewalld Cheat Sheet: firewall-cmd Rules, Commands and Examples

firewalld Cheat Sheet: firewall-cmd Rules, Commands and Examples

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.

Taskfirewall-cmd Command
Check firewalld statusfirewall-cmd --state
Start firewalld servicesystemctl start firewalld
Enable firewalld on bootsystemctl enable firewalld
Restart firewalld servicesystemctl restart firewalld
Reload firewall rulesfirewall-cmd --reload
List all zonesfirewall-cmd --get-zones
Show active zonesfirewall-cmd --get-active-zones
Check default zonefirewall-cmd --get-default-zone
Change default zonefirewall-cmd --set-default-zone=public
List firewall rules for default zonefirewall-cmd --list-all
List firewall rules for specific zonefirewall-cmd --list-all --zone=public
List allowed services in a zonefirewall-cmd --list-services
List open portsfirewall-cmd --list-ports
Show configuration for all zonesfirewall-cmd --list-all-zones
Allow a service (example: HTTP)firewall-cmd --add-service=http
Allow HTTPS trafficfirewall-cmd --add-service=https
Allow SSH servicefirewall-cmd --add-service=ssh
Remove a servicefirewall-cmd --remove-service=http
Allow a service permanentlyfirewall-cmd --add-service=http --permanent
Allow port 8080 TCPfirewall-cmd --add-port=8080/tcp
Allow port 53 UDPfirewall-cmd --add-port=53/udp
Remove open portfirewall-cmd --remove-port=8080/tcp
Allow port permanentlyfirewall-cmd --add-port=8080/tcp --permanent
Allow traffic from specific IPfirewall-cmd --add-source=192.168.1.100
Allow traffic from subnetfirewall-cmd --add-source=192.168.1.0/24
Remove allowed IPfirewall-cmd --remove-source=192.168.1.100
Assign interface to zonefirewall-cmd --zone=public --add-interface=eth0
Check interface zonefirewall-cmd --get-zone-of-interface=eth0
Move interface to different zonefirewall-cmd --zone=internal --change-interface=eth0
Create a new zonefirewall-cmd --permanent --new-zone=myzone
Delete a zonefirewall-cmd --permanent --delete-zone=myzone
Enable masquerading (NAT)firewall-cmd --add-masquerade
Enable NAT permanentlyfirewall-cmd --add-masquerade --permanent
Forward port 80 to 8080firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080
Forward traffic to another hostfirewall-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 requestsfirewall-cmd --add-icmp-block=echo-request
Enable logging of dropped packetsfirewall-cmd --set-log-denied=all
Create new IP setfirewall-cmd --permanent --new-ipset=myset --type=hash:ip
Add IP to IP setfirewall-cmd --permanent --ipset=myset --add-entry=10.0.0.1
List IP set entriesfirewall-cmd --permanent --ipset=myset --get-entries
Create rich rule allowing specific IPfirewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.50 accept'
Block IP using rich rulefirewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.50 drop'
Allow port for specific IPfirewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.1.50 port port=22 protocol=tcp accept'
List rich rulesfirewall-cmd --list-rich-rules
Show direct rulesfirewall-cmd --direct --get-all-rules
Reset runtime rules to permanent rulesfirewall-cmd --runtime-to-permanent
Restore firewalld default configurationfirewall-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:

ZonePurpose
publicDefault zone for untrusted networks such as the internet
internalUsed for internal networks where systems are trusted
homeIntended for home networks
workUsed for office networks
trustedAccepts all network traffic
dmzUsed for servers exposed to external networks
dropSilently drops all incoming packets
blockRejects incoming traffic with an error response

To list all available zones:

bash
firewall-cmd --get-zones

To check the default zone currently used by the system:

bash
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:

bash
firewall-cmd --get-active-zones

To check which zone an interface belongs to:

bash
firewall-cmd --get-zone-of-interface=eth0

Runtime vs Permanent Firewall Rules

Firewalld maintains two types of configurations:

ConfigurationDescription
RuntimeTemporary rules active immediately but lost after reboot
PermanentRules stored on disk and preserved after reboot

Example of adding a temporary rule:

bash
firewall-cmd --add-service=http

Example of adding a permanent rule:

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

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

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

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

Verify open ports and services

Check which services and ports are currently allowed through the firewall.

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

bash
firewall-cmd --runtime-to-permanent

Open and Close Firewall Ports

Open a TCP port using firewall-cmd

To allow TCP traffic on port 8080:

bash
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):

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

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

List all open firewall ports

To display all currently open ports:

bash
firewall-cmd --list-ports

Check which zone contains the open port

To view detailed firewall configuration for a specific zone:

bash
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:

bash
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:

bash
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:

bash
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:

bash
firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.50" drop' --permanent
firewall-cmd --reload

Verify the rule:

bash
firewall-cmd --list-rich-rules

Block a network range using firewalld

To block an entire network range:

bash
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:

bash
firewall-cmd --add-service=http --permanent
firewall-cmd --reload

Allow HTTPS service:

bash
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:

bash
firewall-cmd --remove-service=http --permanent
firewall-cmd --reload

List allowed services in a zone

To view services allowed in the default zone:

bash
firewall-cmd --list-services

To check services allowed in a specific zone:

bash
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:

bash
/etc/firewalld/services/myapp.xml

Example contents:

bash
<?xml version="1.0" encoding="utf-8"?>
<service>
    <short>MyApp</short>
    <description>Custom application service</description>
    <port protocol="tcp" port="9000"/>
bash
</service>

Reload firewalld and enable the service:

bash
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:

bash
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:

bash
firewall-cmd --set-default-zone=internal

Create a custom zone for application traffic

Create a new zone for a specific application environment.

Create zone:

bash
firewall-cmd --permanent --new-zone=appzone
firewall-cmd --reload

Add an interface to this zone:

bash
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:

bash
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:

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

View configuration of the internal zone:

bash
firewall-cmd --list-all --zone=internal

View configuration of the trusted zone:

bash
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:

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

bash
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:

bash
firewall-cmd --add-service=nfs --permanent
firewall-cmd --reload

Verify services:

bash
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:

bash
firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.10.10.0/24" accept' --permanent

Drop other external traffic:

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

bash
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:

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

bash
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:

bash
firewall-cmd --zone=public --add-masquerade --permanent
firewall-cmd --reload

Verify masquerading status:

bash
firewall-cmd --zone=public --query-masquerade

Verify port forwarding configuration

To confirm the port forwarding rules:

bash
firewall-cmd --list-forward-ports

You can also inspect the complete zone configuration:

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

bash
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:

bash
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:

bash
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:

bash
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:

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

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

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

bash
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:

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

bash
firewall-cmd --set-default-zone=drop

Disable unnecessary services

Remove services that are not required.

Example removing FTP service:

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

Restrict ICMP ping requests

Blocking ICMP requests can reduce exposure to certain scanning tools.

bash
firewall-cmd --add-icmp-block=echo-request --permanent
firewall-cmd --reload

Enable firewall logging for security monitoring

Enable logging for dropped packets.

bash
firewall-cmd --set-log-denied=all

Implement default deny policy

Allow only required services and block everything else.

Example allowing only SSH and HTTP:

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

bash
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:

bash
firewall-cmd --get-zone-of-interface=eth0

If needed, inspect all zones and their configurations:

bash
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:

bash
firewall-cmd --list-services

Check open ports:

bash
firewall-cmd --list-ports

Check rich rules:

bash
firewall-cmd --list-rich-rules

Debug firewalld configuration

If firewall behavior is unclear, enable debugging for the firewalld service.

Edit the firewalld configuration file:

bash
vi /etc/sysconfig/firewalld

Add debug argument:

bash
FIREWALLD_ARGS=--debug=10

Restart firewalld:

bash
systemctl restart firewalld

You can then inspect system logs:

bash
journalctl -xe | grep firewalld

Reset firewalld configuration to default

If the firewall configuration becomes inconsistent, you may reset it.

Stop firewalld:

bash
systemctl stop firewalld

Remove custom configuration:

bash
rm -rf /etc/firewalld/*

Reload default configuration:

bash
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:

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

bash
firewall-cmd --runtime-to-permanent

Reload firewall configuration safely

After adding permanent rules, reload the firewall configuration so that the changes become active.

bash
firewall-cmd --reload

Convert runtime rules to permanent rules

If rules were applied during testing, convert them to permanent configuration.

Example workflow:

bash
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:

bash
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:

bash
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:

bash
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:

bash
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Equivalent firewalld command:

bash
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:

bash
firewall-cmd --add-port=6443/tcp --permanent

Allow kubelet communication:

bash
firewall-cmd --add-port=10250/tcp --permanent

Reload firewall:

bash
firewall-cmd --reload

Allow traffic for Docker containers

Docker networking may require certain ports to be open.

Example allowing container traffic:

bash
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:

bash
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:

bash
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:

bash
firewall-cmd --list-all-zones

Show active firewall rules

Check services, ports, and rich rules currently active.

bash
firewall-cmd --list-all

Export firewalld configuration

Firewalld configuration files are stored in the following directories:

bash
/etc/firewalld/
/usr/lib/firewalld/

You can back them up:

bash
tar -czvf firewalld-backup.tar.gz /etc/firewalld

Audit firewall security settings

Review open ports and services regularly.

Check services:

bash
firewall-cmd --list-services

Check open ports:

bash
firewall-cmd --list-ports

Check IP sources allowed:

bash
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

External Documentation

Deepak Prasad

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.