This episode covers the Rocky Linux firewall: the firewalld zones concept, services and ports, runtime and permanent rule management, rich rules, masquerade and NAT, plus the nftables backend for inspecting the ruleset at a lower level.

In the previous episode 12, you recorded the system's traces and time. Now it's time to build the first line of defense protecting the server from the network: the firewall. Rocky Linux uses firewalld — a dynamic firewall daemon that manages traffic based on the concept of zones — with nftables as the rule-processing backend at the kernel level.
Many new sysadmins turn the firewall off the moment they hit a problem: "just disable the firewall, it'll be faster". In this episode you'll learn the opposite — understanding how firewalld thinks, so you can open the right path without lowering the whole wall.
The main idea of firewalld is zones: groups of rules applied to network interfaces. A trusted interface (internal network) sits in an open zone; an internet-facing interface sits in a strict zone. This echoes episode 6 — giving the right access in the right context.
firewall-cmd --get-active-zonesfirewall-cmd --get-default-zone| Zone | Character |
|---|---|
public | Default, strictest — only explicitly opened services |
internal | For trusted internal networks |
trusted | All traffic accepted — only for highly secure segments |
firewall-cmd --zone=public --list-allpublic rejects almost all incoming traffic except what's listed. trusted is the opposite — and should be used very carefully.
Firewalld simplifies opening access via services — named collections of ports. Instead of remembering "TCP 22", you write ssh:
firewall-cmd --permanent --zone=public --add-service=ssh
firewall-cmd --reloadfirewall-cmd --get-servicesFor custom applications that don't have a built-in service, open the port directly:
firewall-cmd --permanent --add-port=9090/tcp
firewall-cmd --reloadfirewall-cmd --permanent --remove-port=9090/tcp
firewall-cmd --reloadThis is a command you'll use often — for example, opening Cockpit's port 9090 from episode 11.
The most important firewalld concept is the separation between runtime and permanent changes:
firewall-cmd --add-service=httpfirewall-cmd --permanent --add-service=http
firewall-cmd --reloadWarning
Without --permanent, rules vanish on reboot. And remember: always test runtime changes first before making them permanent — avoid locking yourself out of the server you're operating.
A classic admin mistake: adding a permanent rule that blocks the SSH you're currently using. Safe habit: add the runtime change first, confirm the connection still works, then make it permanent.
For logic more complex than simply "open a port", use rich rules — a syntax resembling a rule language:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" \
source address="203.0.113.5" reject'firewall-cmd --permanent --add-rich-rule='rule family="ipv4" \
source address="10.0.0.0/8" port port="3306" protocol="tcp" accept'firewall-cmd --reload
firewall-cmd --list-rich-rulesRich rules give granular control: access to a specific port only from a specific IP or subnet — a pattern very useful for databases and admin panels.
NAT (Network Address Translation) lets many hosts share one public address going out, or forwards traffic from one port to an internal service. Firewalld provides this through masquerade:
firewall-cmd --permanent --zone=public --add-masquerade
firewall-cmd --reloadsysctl net.ipv4.ip_forwardMasquerade works together with net.ipv4.ip_forward — the same setting you saw in episode 10. This is the foundation of a simple router and container gateway.
nftables is the kernel-level filtering framework that replaced iptables. Firewalld translates its rules into an nftables ruleset. Understanding its basic syntax helps you read what's actually happening:
nft list rulesetIts basic structure: tables contain chains, and each chain contains rules. A simple example showing the syntax:
nft add table inet example
nft add chain inet example input { type filter hook input priority 0; }
nft add rule inet example input tcp dport 22 acceptnft flush table inet exampleIn daily practice you won't write nft manually — firewalld does it for you. But when debugging, nft list ruleset becomes a window into the actual rules:
nft list ruleset | grep -A5 9090firewall-cmd --reload
nft list rulesetThis integration means your rules are handled by one consistent kernel pipeline — and you can always verify what firewalld is applying.
For systems not using firewalld, nft can stand alone with a ruleset script:
nft -f /etc/nftables.confcat /etc/nftables.confThe rules in this file are executed when the nftables service is enabled — a more manual approach but with full control.
In this episode 13, you mastered the Rocky Linux firewall: the concept of public, internal, and trusted zones, the difference between services and ports, runtime and permanent rule management with firewall-cmd, rich rules for granular control, masquerade and NAT, and the nftables backend with table, chain, and rule syntax for inspection and debugging.
Key takeaways:
nft list ruleset shows what firewalld is actually applying in the kernel.In the next episode 14, we will discuss SELinux and Mandatory Access Control — the difference between DAC and MAC, the Enforcing, Permissive, and Disabled modes, file contexts, booleans, and troubleshooting with ausearch and sealert. The firewall protects from outside; now it's time to build security from within!