Linux / Tool

Linux firewall rule generator: nftables, ufw and firewalld

Tick your server's services and choose who can reach them: the tool writes ready-to-paste rules for nftables, ufw or firewalld, with SSH rate-limited against brute force, correct ICMP for IPv6 and the essential warning if Docker runs on the machine.

Linux Tool Intermediate Published October 21, 2026 Translated October 27, 2026 5 min read Version française
Brick wall painted red and orange
Photo: Tools For Motivation on Unsplash

In plain words

A firewall is the guard at the entrance of a building: by default it lets nobody in, and you give it a precise list ("the postman may come in through door 443", "the neighbours on the local network may ring at door 445"). nftables, ufw and firewalld are three different guards who understand the same list written in three languages. The tool writes that list for you in your distribution's language.

Which one to choose?

Tool Distributions Principle
nftables All; Debian's default tool A /etc/nftables.conf file read at boot. The most precise, and the most readable once you are used to it.
ufw Ubuntu, Debian (to install) Short commands that write nftables rules for you. Ideal for a simple server.
firewalld Fedora, RHEL, AlmaLinux, Rocky, openSUSE Zones and named services, changed on the fly with firewall-cmd.

Use only one at a time: two active managers step on each other's toes and the result becomes unpredictable.

Applying without locking yourself out

  1. Open two SSH sessions: one to apply the rules, the other stays open as a fallback.
  2. Check that the SSH rule is in what you are about to apply, with the right port.
  3. Apply, then open a third connection from your workstation. If it works, all is well; otherwise, fix it from the fallback session.
  4. On a VPS, find the provider's web console before you start: it gives access to the machine even when the network is closed.

Docker bypasses ufw and firewalld

When a container publishes a port (ports: "8080:80"), Docker adds its own rules, which are checked before those of ufw and firewalld. So the port is reachable even if the firewall does not open it. Two simple fixes: publish the port on a specific address ("192.168.1.10:8080:80") or on 127.0.0.1 behind a reverse proxy, or publish nothing at all and use an internal Docker network. The docker-compose generator already applies this principle.

Checking what is really open

From the server, list the listening ports; from another machine, check what really answers:

sudo ss -tulpn                      # listening ports and their programs
sudo nft list ruleset               # all active rules (nftables, ufw, firewalld, Docker)
nmap -Pn 192.168.1.10               # from another machine: reachable ports

A port that is listening but missing from the nmap result is properly filtered. A port visible in nmap that you did not open often comes from a Docker container.

To go further: Securing SSH access completes the firewall with key-based authentication, and Understanding firewalls explains state, default policy and filtering.

Read next