How to Set Up a Firewall with UFW
Learn to configure UFW on Linux: set secure default policies, open only the ports you need, read existing rules, and verify your firewall is working correctly.
Before you start
- ▸A Linux system with sudo or root access
- ▸Basic familiarity with the terminal and running commands as root
- ▸If configuring a remote server, an active SSH session and a backup access method (console/VNC) as a safety net
UFW (Uncomplicated Firewall) is a front-end for nftables/iptables designed to make firewall management approachable without sacrificing control. It ships by default on Ubuntu and is available on most major distributions. This guide walks through setting sane default policies, opening only what you need, and verifying the result — habits that matter whether you're hardening a home server or a cloud VPS.
Install UFW
Ubuntu and Debian usually include UFW. If it's missing, install it:
sudo apt install ufw
On Fedora or RHEL-family systems, firewalld is the default, but UFW is available:
sudo dnf install ufw
On Arch Linux:
sudo pacman -S ufw
Enable and start the UFW systemd service so it persists across reboots:
sudo systemctl enable --now ufw
Set Default Policies
Default policies decide what happens to traffic that doesn't match any explicit rule. The correct starting point for almost every system is: deny all incoming, allow all outgoing. This means you open only what you deliberately choose to expose.
sudo ufw default deny incoming
sudo ufw default allow outgoing
If you're hardening a server that should not initiate arbitrary outbound connections (e.g., an air-gapped build box), you can also restrict outgoing:
sudo ufw default deny outgoing
Be careful with that last command — you'll need to explicitly allow DNS, NTP, and any update traffic before enabling the firewall, or you'll lock yourself out of package management.
Allow Essential Services Before Enabling
Critical: If you're on a remote server, allow SSH before you enable UFW or you will lose access immediately.
Allow SSH
UFW ships with named application profiles. Use the profile name when possible — it's self-documenting:
sudo ufw allow OpenSSH
If SSH runs on a non-standard port (e.g., 2222), specify it directly:
sudo ufw allow 2222/tcp
Allow Web Traffic
For an HTTP/HTTPS web server:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Or use the bundled Nginx/Apache profiles if the packages are installed:
sudo ufw allow 'Nginx Full'
Allow Other Common Services
Substitute any port number or service name from /etc/services:
# PostgreSQL — only from a specific source IP
sudo ufw allow from 192.168.1.50 to any port 5432
# Samba (file sharing on a LAN subnet)
sudo ufw allow from 192.168.1.0/24 to any app Samba
Enable the Firewall
Once your critical rules are in place, activate UFW:
sudo ufw enable
You'll see a prompt warning that enabling UFW may disrupt existing connections. Confirm with y. The firewall is now active and will start automatically on boot via systemd.
Reading and Managing Rules
Check Status and Current Rules
The most useful daily command is:
sudo ufw status verbose
Sample output (yours will differ):
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
To Action From
-- ------ ----
OpenSSH ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
OpenSSH (v6) ALLOW IN Anywhere (v6)
For a numbered list (needed when deleting rules):
sudo ufw status numbered
Delete a Rule
Find the rule number with status numbered, then delete it:
sudo ufw delete 3
You can also delete by rule specification, which is less error-prone than relying on a number that may shift:
sudo ufw delete allow 80/tcp
Reload After Changes
UFW applies changes immediately, but if you want to force a clean reload:
sudo ufw reload
Application Profiles
UFW reads profile definitions from /etc/ufw/applications.d/. When you install a package like Nginx, Apache, or OpenSSH, it may drop a profile there automatically. List all available profiles:
sudo ufw app list
Inspect what ports a profile covers before allowing it:
sudo ufw app info 'Nginx Full'
You can write your own profile file for any custom application. The format is a simple INI file with [AppName], title, description, and ports fields.
Logging
UFW can log blocked packets, which is valuable for diagnosing connection problems and spotting probes. Logging levels are off, low, medium, high, and full. Start with low:
sudo ufw logging low
Logs appear in /var/log/ufw.log and also via journald:
sudo journalctl -k --grep='\[UFW'
Verification
After enabling the firewall, confirm it's doing what you expect from a second machine or using a loopback test:
# From another host, test a port that should be closed (should time out or refuse)
nc -zv YOUR_SERVER_IP 8080
# Test a port that should be open
nc -zv YOUR_SERVER_IP 443
You can also use nmap for a broader scan against your own server to confirm the surface area matches what you intend:
nmap -sS -p 1-1024 YOUR_SERVER_IP
Check that UFW is active and rules are loaded by systemd:
sudo systemctl status ufw
Troubleshooting
- Locked out of SSH after enabling: If you have physical or console access, run
sudo ufw disable, then add the OpenSSH rule and re-enable. On cloud providers, use the vendor's emergency console. - Rule exists but traffic is still blocked: Another firewall may be active — check
sudo nft list rulesetorsudo firewall-cmd --list-all. Running UFW alongside firewalld on Fedora/RHEL can cause conflicts; pick one. - IPv6 traffic not filtered: Open
/etc/default/ufwand confirmIPV6=yes. Then runsudo ufw reload. UFW creates parallel IPv6 rules automatically when this is set. - Service doesn't appear in app list: Check whether the package installed a profile in
/etc/ufw/applications.d/. If not, allow by port number instead. - Changes not persisting across reboot: Confirm systemd is managing UFW —
sudo systemctl is-enabled ufwshould returnenabled.
Frequently asked questions
- Does UFW replace iptables or nftables?
- No. UFW is a management layer that writes rules to iptables or nftables on your behalf. On modern Ubuntu (22.04+), it targets nftables via the iptables-nft compatibility layer. The underlying packet-filtering kernel subsystem is still doing the real work.
- Can I use UFW and firewalld at the same time?
- You should not. Running both on the same machine creates conflicting rule sets that are difficult to reason about. Choose one tool and disable or remove the other.
- How do I temporarily disable the firewall without losing my rules?
- Run 'sudo ufw disable'. This stops enforcement but keeps all your configured rules intact. Re-enable with 'sudo ufw enable' when ready.
- How do I completely reset UFW to a blank state?
- Run 'sudo ufw reset'. This disables the firewall and deletes all rules. Backup copies of the previous rule files are saved in /etc/ufw/ with a timestamp suffix.
- Will UFW rules survive a kernel or package update?
- Yes, as long as the ufw systemd service is enabled. UFW stores its rules in flat files under /etc/ufw/ which are independent of the kernel version and are re-applied at boot.
Related guides
Manage Secrets with Ansible Vault
Encrypt Ansible secrets with AES-256 using ansible-vault: encrypt files and inline vars, automate with password files, and isolate group-level secrets with vault IDs.
AppArmor Explained
Learn how AppArmor profiles work, how to switch between enforce and complain mode, create new profiles, and diagnose access denials on Ubuntu, Debian, and Arch.
Apply CIS Benchmarks with OpenSCAP
Use OpenSCAP and scap-security-guide to evaluate, report on, and remediate Linux systems against CIS Benchmarks — covering install, eval, and automation.
How to Audit a Linux System with auditd
Set up auditd on Linux to track file access, syscalls, and privilege use. Covers persistent rules, file watches, ausearch, and aureport across major distros.