Linux Firewall Cheat Sheet: ufw and firewall-cmd Side by Side

Most used

Allow SSH and a web server, then turn the firewall on:

# ufw (Ubuntu, Mint, Debian if installed)
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enable
sudo ufw status verbose

# firewalld (Fedora, RHEL family, openSUSE)
sudo firewall-cmd --permanent --add-service={ssh,http,https}
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

Both tools are front ends to the kernel's nftables packet filter. ufw is simple and rule-based; firewalld groups interfaces into zones and has a separate runtime and permanent configuration. Use the one your distro ships and never run both at once. The step-by-step setup, including Docker interaction, is in the ufw and firewalld guide.

Working over SSH?

Allow SSH before enabling or tightening a firewall on a remote machine, and keep your current session open while you test a new login in a second terminal. If you are locked out, you will see Connection timed out rather than "refused".

Install, enable and check status

Taskufwfirewalld
Installsudo apt install ufw / sudo pacman -S ufwsudo dnf install firewalld / sudo zypper install firewalld / sudo apt install firewalld
Enable now and at bootsudo ufw enablesudo systemctl enable --now firewalld
Disablesudo ufw disablesudo systemctl disable --now firewalld
Is it running?sudo ufw statussudo firewall-cmd --state
Show all rulessudo ufw status verbosesudo firewall-cmd --list-all
Rules with numberssudo ufw status numberedn/a; sudo firewall-cmd --list-all-zones shows every zone
Apply saved configsudo ufw reloadsudo firewall-cmd --reload
Reset to defaultssudo ufw resetRemove files in /etc/firewalld/zones/, then reload

Allow and deny ports and services

Taskufwfirewalld
Allow a TCP portsudo ufw allow 8080/tcpsudo firewall-cmd --permanent --add-port=8080/tcp
Allow a UDP portsudo ufw allow 51820/udpsudo firewall-cmd --permanent --add-port=51820/udp
Allow a port rangesudo ufw allow 6000:6010/tcpsudo firewall-cmd --permanent --add-port=6000-6010/tcp
Allow a named servicesudo ufw allow OpenSSHsudo firewall-cmd --permanent --add-service=ssh
List known service namessudo ufw app listfirewall-cmd --get-services
Remove an allowed portsudo ufw delete allow 8080/tcpsudo firewall-cmd --permanent --remove-port=8080/tcp
Remove a servicesudo ufw delete allow OpenSSHsudo firewall-cmd --permanent --remove-service=ssh
Delete rule by numbersudo ufw delete 3n/a (remove by what it allows)
Deny a port explicitlysudo ufw deny 23/tcpClosed unless allowed; use a rich rule to reject explicitly
Rate-limit SSH brute forcesudo ufw limit OpenSSHRich rule with limit value="10/m"

After any --permanent change, run sudo firewall-cmd --reload. ufw rules take effect immediately.

Restrict by source IP or interface

Taskufwfirewalld
Allow everything from one IPsudo ufw allow from 192.168.1.10sudo firewall-cmd --permanent --zone=trusted --add-source=192.168.1.10
Allow a port only from a subnetsudo ufw allow from 192.168.1.0/24 to any port 22 proto tcpsudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
Block an IPsudo ufw insert 1 deny from 203.0.113.7sudo firewall-cmd --permanent --zone=drop --add-source=203.0.113.7
Rule for one interfacesudo ufw allow in on wg0 to any port 53sudo firewall-cmd --permanent --zone=internal --change-interface=wg0
Allow outgoing only on a portsudo ufw allow out 53Outgoing is open by default; use policies to restrict

Need help writing a CIDR range like 192.168.1.0/24? Use the subnet calculator.

Defaults, zones and logging

Taskufwfirewalld
Default deny incomingsudo ufw default deny incomingDefault zone public already rejects unlisted ports
Default allow outgoingsudo ufw default allow outgoingDefault behaviour
Show default zonen/afirewall-cmd --get-default-zone
Which zone each interface is inn/afirewall-cmd --get-active-zones
Change default zonen/asudo firewall-cmd --set-default-zone=home
Work in a specific zonen/aAdd --zone=NAME to any command
Turn on loggingsudo ufw logging on (logs to the kernel log, prefix [UFW BLOCK])sudo firewall-cmd --set-log-denied=all
Read blocked packetsjournalctl -k | grep 'UFW BLOCK'journalctl -k | grep -i 'REJECT\|DROP'
Try a rule for 5 minutesn/asudo firewall-cmd --add-port=8080/tcp --timeout=5m
Save runtime rules as permanentn/a (always persistent)sudo firewall-cmd --runtime-to-permanent
Port forwardingEdit /etc/ufw/before.rules (NAT section)sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080

nftables underneath

CommandWhat it does
sudo nft list rulesetThe real rules the kernel is using, whichever front end wrote them
sudo nft list tablesTables present (firewalld uses inet firewalld)
sudo iptables -L -n -vLegacy view; on current distros this is iptables-nft translating to nftables
sudo ss -tulpnWhat is actually listening, to compare with what you opened
sudo systemctl enable --now nftablesLoad hand-written rules from /etc/nftables.conf (Debian, Arch) or /etc/sysconfig/nftables.conf (Fedora)

Common recipes

Fresh Ubuntu server with SSH, HTTP and HTTPS:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit OpenSSH
sudo ufw allow 'Nginx Full'      # or: sudo ufw allow 80,443/tcp
sudo ufw enable

Fedora workstation: open a development port for the local network only:

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3000" protocol="tcp" accept'
sudo firewall-cmd --reload
sudo firewall-cmd --list-rich-rules

Check from another machine whether a port is reachable:

nc -zv server.example.com 443
# "succeeded" = open; "refused" = nothing listening; timeout = filtered by a firewall

SSH listens on a custom port (see the SSH server guide):

sudo ufw allow 2222/tcp
sudo firewall-cmd --permanent --add-port=2222/tcp && sudo firewall-cmd --reload
sudo semanage port -a -t ssh_port_t -p tcp 2222   # also needed on SELinux systems

Gotchas

  • firewalld runtime vs permanent. A rule without --permanent vanishes on reload; a rule with only --permanent is not active until you reload. Use both, or --runtime-to-permanent.
  • Docker bypasses ufw. Published container ports (-p 8080:80) are opened in Docker's own chains before ufw sees them. Bind to 127.0.0.1:8080:80 or use the DOCKER-USER chain.
  • Rule order in ufw. The first matching rule wins. To block an IP that an earlier rule allows, use ufw insert 1 deny from ....
  • Refused vs timed out. "Connection refused" means the packet arrived and nothing is listening; a firewall that drops packets causes a timeout, and a reject rule can cause No route to host.
  • Cloud firewalls. On AWS, Azure, GCP or a VPS panel, a security group can block traffic before it reaches your host firewall. Open the port in both places.
  • IPv6. ufw applies rules to IPv6 when IPV6=yes in /etc/default/ufw (the default). firewalld zones cover both families unless you use family="ipv4" in a rich rule.

Upstream documentation: UFW on help.ubuntu.com, firewalld.org and nftables on the Arch Wiki.

Frequently asked questions

Which firewall does my distro use?

Ubuntu ships ufw (inactive by default). Fedora, RHEL-family and openSUSE use firewalld, which is active by default. Debian and Arch install neither; add ufw or firewalld yourself or write nftables rules.

How do I open a port with firewall-cmd permanently?

Run sudo firewall-cmd --permanent --add-port=8080/tcp and then sudo firewall-cmd --reload. Without --permanent the rule only lasts until the next reload or reboot.

Will enabling ufw lock me out of SSH?

It can, because the default policy denies incoming connections. Run sudo ufw allow OpenSSH (or sudo ufw allow 22/tcp) before sudo ufw enable.

How do I delete a ufw rule?

List rules with numbers using sudo ufw status numbered, then sudo ufw delete N. You can also repeat the original rule with delete in front: sudo ufw delete allow 80/tcp.

Can I use ufw and firewalld together?

No. Both manage the same nftables backend and will fight over the rules. Pick one, and disable the other with systemctl disable --now.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.