Sitemap
Lumenyx

Lumenyx

Firewalld — Basics for Fedora / RHEL

7 min readJul 22, 2026

--

Firewalld is the default firewall for CentOS, Red Hat and Fedora distributions.

Firewalld is a high level frontend that interfaces with nftables (or iptables for older versions) which then interfaces with netfilter.

Press enter or click to view image in full size

ZONES

Firewalld utilises ‘zones’.

Zones allow you to dynamically change your entire firewall profile based on how much you trust the specific network your system is connected to.

Press enter or click to view image in full size

ZONE PRIORITY CHECKS

traffic arrives → firewalld picks the zone using the priority order (shown below) → within that zone, checks services/ports/rich rules top to bottom → if nothing matches, falls through to the zone’s ‘target’ (default, ACCEPT, REJECT or DROP).

  1. Source binding: If the traffic’s source IP/subnet matches a source bound to a zone, that zone takes precedence.
  2. Interface binding: If no source match, whichever zone the interface is bound to applies.
  3. NetworkManager connection zone: If neither of the above is set, and NM manages the interface.
    For example, a connection profile can have a zone attached to it, and then NetworkManager gives that zone to Firewalld.
    nmcli connection modify <CONNECTION_NAME> connection.zone <ZONE_NAME>
    <CONNECTION_NAME> could be the SSID.
  4. Default zone: the fallback if nothing else matched.

UPDATING ZONE BINDINGS

SOURCE BINDINGS

sudo firewall-cmd --zone=< ZONE > --add-source=< NETWORK > --permanent
sudo firewall-cmd --zone=trusted --add-source=192.168.15.0/24 --permanent

INTERFACE BINDINGS

Get Lumenyx’s stories in your inbox

Join Medium for free to get updates from this writer.

You can also set up interface binding so that when traffic comes in on a certain interface, it is then checked against the zone that uses that interface:

sudo firewall-cmd --zone=< ZONE > --change-interface=< INTERFACE > --permanent
sudo firewall-cmd --zone=trusted --change-interface=eth1 --permanent

The zone stock configuration files are stored in /usr/lib/firewalld/zones/.

Press enter or click to view image in full size

When changes are written, they are applied to /etc/firewalld/zones:

Press enter or click to view image in full size

DIFFERENT ZONES

We can list the different available zones by running:

firewall-cmd --get-zones
Press enter or click to view image in full size

Copied from this article:

- FedoraServer zone is the default zone on Fedora Server installations, suitable for a server environment where you trust the surrounding network to a moderate degree. It comes with a slightly wider set of default services (ssh, dhcpv6-client, cockpit) enabled out of the box. Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system.

- FedoraWorkstation zone is the default zone on Fedora Workstation installations, suitable for a desktop/laptop environment where you have a reasonable degree of trust in the local network. It ships with desktop-oriented default services (ssh, mdns, samba-client, dhcpv6-client) enabled. Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system.

- block zone is suitable for incoming connections/traffic that is not trusted, this zone blocks all incoming traffic with “ICMP prohibited message”. Only the network traffic that meets the specified firewall rules condition on this zone can be allowed into the system.

- dmz zone (demilitarize zone) is suitable for public network or internet–facing systems with limited access. Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system.

- Docker zone is used internally by Docker’s integration with firewalld, suitable for traffic passing over Docker’s bridge network between containers and the host. It is not meant to be assigned to a real network interface manually — Docker manages it automatically as containers are created. Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system.

- drop zone is also suitable for incoming connections/traffic that is not trusted at all, this zone also blocks all incoming traffic but with no message. This zone makes intruding hard because no error or a particular message can be traced. Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system.

- External zone is suitable for external network and masquerading, it is very suitable for a network that is used for routers. Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system.

- Home zone is suitable for a home network, that is, network within your home environment. network within this sphere can be trusted. However, Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system.

- internal zone is suitable for an internal network, incoming network within this environment can also be trusted. However, Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system.

- nm-shared zone is used by NetworkManager when it sets up connection sharing, such as a Wi-Fi hotspot or sharing one interface’s internet connection with another. It enables DHCP and DNS so shared clients can get an address and resolve names, and masquerades their traffic out through the shared connection. Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system.

- Public zone is suitable for public network or internet-facing systems. Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system. This zone is an active and the often is the default zone in Linux.

- Trusted Zone is suitable for a trusted network, this zone allows all incoming connections without filtering anything. This zone should only be used if you trust every incoming connection without any doubt.

- work zone is suitable for a work network, that is, a network within an office or workplace environment where you mostly trust the other machines around you but not to the same degree as your own home. Only the network traffic that meets the firewall rules condition on this zone can be allowed into the system.

When you run a firewalld command allowing or removing a service/port, it is applied to the default zone, which you can find out by running:

firewall-cmd --get-active-zones
Press enter or click to view image in full size
Notice how it says ‘default’.

Change the default zone:

sudo firewall-cmd --set-default-zone=< ZONE NAME >

LISTING RULES

List all rules for the current zone:

sudo firewall-cmd --list-all

List all rules for a specific zone:

sudo firewall-cmd --list-all --zone=<ZONE>

List all rules for all zones:

sudo firewall-cmd --list-all-zones

List rich rules only:

sudo firewall-cmd --zone=<ZONE> --list-rich-rules

MODIFYING RULES

Add a service permanently to the default zone:

sudo firewall-cmd --add-service=http --permanent

Add a port permanently to the default zone:

sudo firewall-cmd --add-port=80/tcp --permanent

Remove a service permanently from the default zone:

sudo firewall-cmd --remove-service=http --permanent

Remove a port permanently from the default zone:

sudo firewall-cmd --remove-port=80/tcp --permanent

Modify changes to a specific zone (that is not the default):

sudo firewall-cmd --zone=<ZONE> <RULE_CHANGE> --permanent

Apply the changes:

sudo firewall-cmd --reload

RICH RULES

Sometimes we need something more granular than just services and ports. We may need to allow a service only from a specific IP address, or log connections, or set a time-limited rule. That’s where rich rules come in.

Rich rules allow you to write more complex and granular rules that combine sources, services, ports, logging and actions (accept/reject/drop) into a single rule.

SYNTAX:

sudo firewall-cmd --zone=<ZONE>
--add-rich-rule='rule priority="[ -32768 to 32767 ]" family="[ ipv4 | ipv6 ]" source address="[ SOURCE ]"
port port="[ PORT ]" protocol="[ PROTOCOL ]" log prefix="[ PREFIX ]"
level="[ DEBUG LEVEL ]" [ accept | reject | drop ]' --permanent

Example:

firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" 
source address="192.168.1.100" port port="80" protocol="tcp"
log prefix="http_access" level="info" accept' --permanent
  • A rich rule doesn’t need al these pieces, just use what you need.
  • The rule priority range is between -32768 (checked first) and 32767. The default priority is 0.
  • The ‘log prefix’ is basically a one-word comment. However unlike a regular comment (which only stays in the config), it also tags the output that the rule produces.

To remove rich rules, we must first list them out:

firewall-cmd --zone=<ZONE> --list-all-rules
firewall-cmd --permanent --zone=<ZONE> --list-all-rules

Actually removing the rich rule (for temporary and permanent rules):

firewall-cmd --zone=<ZONE> --remove-rich-rule='<EXACT RICH RULE>'
firewall-cmd --permanent --zone=<ZONE> --remove-rich-rule='<EXACT RICH RULE>'

Example:

firewall-cmd --permanent --zone=<ZONE> --remove-rich-rule='rule family="ipv4" source address="1.2.3.4" accept'

If you removed it from the permanent configuration, reload firewalld:

firewall-cmd --reload

--

--