UFW (Uncomplicated Firewall) is the friendly front-end to the Linux firewall on Ubuntu and Debian. It turns rules like “allow SSH, HTTP and HTTPS, deny everything else” into a few short commands. Here’s how to set it up without locking yourself out.
1. Install (if needed)
UFW comes preinstalled on Ubuntu. On Debian:
sudo apt install -y ufw
2. Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
Everything inbound is blocked unless a rule allows it; the server can still make outbound connections (updates, APIs, DNS).
3. Allow SSH first — before enabling
This is the step that saves you from a lockout:
sudo ufw allow OpenSSH # port 22
# or, if SSH runs on another port:
sudo ufw allow 2222/tcp
Even better, allow SSH only from your own IP if it’s static:
sudo ufw allow from 198.51.100.25 to any port 22 proto tcp
4. Allow your services
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# or by application profile
sudo ufw allow 'Nginx Full'
sudo ufw app list
5. Enable the firewall
sudo ufw enable
sudo ufw status verbose
UFW warns that enabling may disrupt SSH connections — if you’ve allowed your SSH port, answer y. Existing sessions continue. UFW starts automatically at boot from now on.
If you do lock yourself out, use the VNC console in your VPS control panel to log in and run sudo ufw allow 22/tcp or sudo ufw disable.
Common rules
# Port ranges (protocol required)
sudo ufw allow 6000:6010/tcp
# UDP (WireGuard, game servers)
sudo ufw allow 51820/udp
# A subnet
sudo ufw allow from 10.0.0.0/24
# A specific IP to a specific port (databases!)
sudo ufw allow from 203.0.113.5 to any port 3306 proto tcp
# Deny an abusive IP (insert at the top so it wins)
sudo ufw insert 1 deny from 192.0.2.66
# Rate-limit SSH: blocks IPs with 6+ connections in 30 seconds
sudo ufw limit OpenSSH
UFW checks rules in order and the first match wins. That’s why deny rules for specific IPs should be inserted before general allow rules.
View and delete rules
sudo ufw status numbered
To Action From
-- ------ ----
[ 1] OpenSSH ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere
sudo ufw delete 2 # by number
sudo ufw delete allow 80/tcp # by rule
Numbers shift after each deletion; list again before deleting another.
IPv6
UFW handles IPv4 and IPv6 together when IPV6=yes is set in /etc/default/ufw (the default). Each rule then appears twice in the status, once with (v6).
Logging
sudo ufw logging low # off | low | medium | high | full
Blocked packets appear in /var/log/ufw.log (or the journal) as [UFW BLOCK]. low is enough; higher levels produce a lot of noise on a public server.
The Docker caveat
Docker manipulates iptables directly, and published container ports bypass UFW. docker run -p 8080:80 is reachable from the internet even with no UFW rule for 8080. Options:
- Publish on localhost only:
-p 127.0.0.1:8080:80, and expose the service through a reverse proxy on 80/443. - Filter in the
DOCKER-USERiptables chain. - Use a helper like
ufw-docker, which adds rules to make UFW apply to containers.
See installing Docker on Ubuntu for safe defaults.
Reset or disable
sudo ufw disable # turn off, keep rules
sudo ufw reset # delete all rules, disable (asks for confirmation)
Under the hood
UFW writes iptables (or nftables via iptables-nft) rules. Custom rules that UFW’s syntax can’t express — NAT for a VPN, for example — go in /etc/ufw/before.rules. If you need full control, see iptables or nftables, and on RHEL-family systems, firewalld.
A sensible web server setup
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
Add Fail2Ban to ban IPs that keep failing logins, and you’ve covered the basics of Linux firewall rules.
UFW filters traffic that reaches your server; large-scale DDoS floods have to be stopped upstream, before they reach it. For projects that attract attacks, our dedicated servers offer a DDoS protection add-on.