firewalld (RHEL) and ufw (Ubuntu)
Two different front-ends, one underlying kernel packet-filtering framework. · 11 min
Both `firewalld` (the default on RHEL-family systems) and `ufw` — Uncomplicated Firewall (the default front-end on Ubuntu) — are front-ends that generate and manage rules for the kernel's actual packet-filtering framework, `nftables` (the modern successor to the older `iptables`, though iptables-style syntax and thinking still appears constantly in older documentation and habits). You rarely write raw nftables rules directly in day-to-day administration — these two tools exist specifically to make firewall management less error-prone than hand-writing low-level rules.
`firewalld` organizes rules around zones — named trust levels (`public`, `internal`, `trusted`, etc.) that a network interface is assigned to, each with its own set of allowed services and ports. This models a real-world scenario well: a laptop's Wi-Fi interface on a coffee-shop network might be in the restrictive `public` zone, while its Ethernet interface on a trusted office LAN is in a more permissive zone — the same machine, different trust levels per interface.
`ufw` takes a simpler, more direct approach without zones: you allow or deny specific ports or services directly, and rules apply globally rather than per-interface-trust-level. `sudo ufw allow 22`, `sudo ufw allow http`, `sudo ufw enable` — the entire mental model is closer to a straightforward allow-list, which is exactly why Ubuntu calls it "uncomplicated": it deliberately trades firewalld's more granular zone model for something faster to reason about on a typical single-purpose server.
| Command | Purpose | Example |
|---|---|---|
| sudo firewall-cmd --state | Check whether firewalld is running | — |
| sudo firewall-cmd --list-all | Show the active zone's current rules | — |
| sudo firewall-cmd --add-service=http --permanent | Allow HTTP traffic permanently (survives reboot) | — |
| sudo firewall-cmd --reload | Apply --permanent changes without restarting the whole service | — |
| sudo ufw status verbose | Show ufw's current status and rules | — |
| sudo ufw allow 22/tcp | Allow a specific port and protocol | — |
| sudo ufw enable | Turn on ufw (make sure SSH is allowed FIRST if managing remotely) | — |
Common Mistakes
- ⚠ Running `firewall-cmd --add-service` without `--permanent` and being confused when the rule disappears after a reboot — without --permanent, changes only apply to the current running state
- ⚠ Enabling ufw on a remote server before confirming SSH (port 22) is allowed — this can instantly lock you out with no way back in except console access
- ⚠ Assuming firewalld and ufw rules are compatible or interchangeable — they are different tools with different rule syntax on top of the same kernel framework
Hands-On Lab
Configure a basic web-server firewall
Objectives
- ✓ Allow SSH, HTTP, and HTTPS traffic
- ✓ Block a specific test port
- ✓ Verify the resulting rule set
Instructions
- On Ubuntu: `sudo ufw allow 22/tcp`, `sudo ufw allow 80/tcp`, `sudo ufw allow 443/tcp`, then `sudo ufw enable` — confirm with `sudo ufw status verbose`.
- On RHEL/Rocky: `sudo firewall-cmd --add-service=ssh --permanent`, `sudo firewall-cmd --add-service=http --permanent`, `sudo firewall-cmd --add-service=https --permanent`, then `sudo firewall-cmd --reload` — confirm with `sudo firewall-cmd --list-all`.
- Start a test service on port 8888 (e.g. `python3 -m http.server 8888`) and confirm it is NOT reachable from another machine, since that port was never explicitly allowed.
- From the server itself, confirm `curl -I http://localhost:8888` still works locally — a firewall governs traffic between hosts, not access from a machine to itself.
Hints (1)
- If you're testing over SSH and lose connection after enabling the firewall, you likely forgot to allow port 22 first — this is exactly the mistake this lab is designed to make you feel once, safely, in a lab environment.
Quick Check
On RHEL/Rocky, you run `firewall-cmd --add-port=8080/tcp` without the `--permanent` flag, then reboot the server. What happens to that rule?
Takeaway: Both firewalld and ufw sit on top of the same nftables kernel framework, but their rule syntax and models (zones vs. direct allow-lists) are different enough that you must know which one a given server actually uses.