
firewalld Guide: Zones, Services, Ports and Troubleshooting
firewalld is a Linux firewall manager used on many RHEL-style distributions, including AlmaLinux, Rocky Linux, CentOS Stream, Fedora and Red Hat Enterprise Linux. This guide explains the practical parts: zones, services, ports, permanent rules, reloads and troubleshooting with firewall-cmd.

What is firewalld?
firewalld manages firewall rules using zones and services. Instead of manually writing raw nftables or iptables rules, you usually use firewall-cmd to allow or remove services and ports.
Zones
Zones describe trust levels, such as public, home, internal or trusted.
Services
Services are named presets like ssh, http, https and smtp.
Ports
Ports are explicit openings such as 8080/tcp or 8443/tcp.
Check whether firewalld is running
systemctl status firewalld
firewall-cmd --state
running● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
Active: active (running) since Sun 2026-05-03 09:12:41 BST; 5h ago
Docs: man:firewalld(1)
Main PID: 812 (firewalld)If the service is inactive, start it with:
sudo systemctl enable --now firewalld
firewalld zones explained
Zones control which rules apply to an interface or source. Most simple servers use the public zone, but you should always check rather than assume.
firewall-cmd --get-default-zone
firewall-cmd --get-active-zones
firewall-cmd --list-all
public
interfaces: eth0public (active)
target: default
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
forward: no
masquerade: no
rich rules:If a command does not specify a zone, firewalld normally uses the default zone.
Allow services with firewalld
Where possible, allow named services instead of raw ports. It is clearer to read later.
sudo firewall-cmd --add-service=http
sudo firewall-cmd --add-service=https
successCheck allowed services:
firewall-cmd --list-services
cockpit dhcpv6-client http https sshUseful services include ssh, http, https, smtp, imap, imaps, pop3, pop3s and mysql, depending on what the server should expose.
Allow a custom port
Use --add-port when there is no suitable service preset, or when an application uses a custom port.
sudo firewall-cmd --add-port=8080/tcp
sudo firewall-cmd --add-port=8443/tcp
successList open ports:
firewall-cmd --list-ports
8080/tcp 8443/tcpss -tulpn to confirm.Runtime vs permanent rules
By default, many firewall-cmd changes apply to the runtime configuration only. They work immediately, but disappear after reload or reboot unless saved permanently.
| Type | Command style | Behaviour |
|---|---|---|
| Runtime | --add-service=https | Applies now, but may not survive reload/reboot. |
| Permanent | --permanent --add-service=https | Saved permanently, but normally needs reload to apply. |
| Runtime to permanent | --runtime-to-permanent | Saves current runtime rules permanently. |
Common workflow:
# Test now
sudo firewall-cmd --add-service=https
# If it works, save it
sudo firewall-cmd --runtime-to-permanent
Or add a permanent rule and reload:
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
successRemove services or ports
sudo firewall-cmd --remove-service=http
sudo firewall-cmd --remove-port=8080/tcp
For permanent rules:
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --permanent --remove-port=8080/tcp
sudo firewall-cmd --reload
Always list the current config afterwards:
firewall-cmd --list-all
Rich rules: allow only one IP
Rich rules let you create more specific rules, such as allowing SSH only from one IP address.
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.10" service name="ssh" accept'
rule family="ipv4" source address="203.0.113.10" service name="ssh" acceptfirewalld troubleshooting workflow
- Check firewalld is running:
firewall-cmd --state - Check the active zone:
firewall-cmd --get-active-zones - List the zone:
firewall-cmd --list-all - Confirm the service is listening:
ss -tulpn - Check service logs:
journalctl -u firewalld - Check the application service:
systemctl status nginx
tcp LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=1256,fd=7))If the firewall allows https but nothing is listening on port 443, the problem is not firewalld. Check the web server.
Common firewalld mistakes
| Mistake | Problem | Better |
|---|---|---|
Forgetting --permanent | The rule disappears later. | Use --runtime-to-permanent after testing. |
| Opening a port but no service is listening | The connection still fails. | Check with ss -tulpn. |
| Editing the wrong zone | The rule does not apply to the active interface. | Check --get-active-zones. |
| Reloading before saving runtime changes | Your tested changes disappear. | Save with --runtime-to-permanent. |
| Blocking SSH without testing | You can lock yourself out. | Keep an active session open and test carefully. |
Keep learning Linux networking and troubleshooting
A safer firewalld change workflow
# Check active zones
firewall-cmd --get-active-zones
# Check current rules
firewall-cmd --list-all
# Add a service permanently
firewall-cmd --permanent --add-service=https
# Reload to apply permanent changes
firewall-cmd --reload
# Confirm the change
firewall-cmd --list-services
Frequently Asked Questions
What is a firewalld zone?
A zone is a firewalld trust level that controls which services and ports are allowed for matching interfaces or sources.
What does --permanent do in firewalld?
--permanent saves a rule so it persists after reloads and reboots.
Do I need firewall-cmd --reload?
Yes, after permanent changes you generally reload firewalld to apply them to the running configuration.
How do I list open services in firewalld?
Use firewall-cmd --list-services for the active zone.