Set up a firewall with ufw
Turn on ufw without locking yourself out, open only the ports you use, and check the rules, on Ubuntu 24.04 or Debian 12.
ufw, the "uncomplicated firewall", is a friendly front end to the Linux firewall. The policy we recommend is simple: block everything coming in, allow everything going out, then open the handful of ports you actually use.
The one way to get this wrong is to turn the firewall on before allowing SSH. So we'll do it in the right order.
Install it
Ubuntu 24.04 has ufw already, switched off. Debian 12 doesn't have it:
apt update
apt install -y ufwMake sure it's off before you start:
ufw statusThat should say Status: inactive.
Allow SSH, then switch it on
ufw allow OpenSSHOpenSSH is a profile for port 22. If you moved SSH to another port, allow that instead, for example ufw allow 2222/tcp.
Then set the defaults and turn it on:
ufw default deny incoming
ufw default allow outgoing
ufw enableufw warns that this may disrupt SSH connections. You've allowed SSH, so answer y. Your session stays up.
Check it:
ufw status verboseYou should see Status: active, the two default policies, and OpenSSH ALLOW IN Anywhere, plus the same line again with (v6). ufw covers IPv6 as well as IPv4 out of the box.
Then open a second terminal and log in again. It's the only real proof that new SSH sessions get through.
Opening more ports
Open only what you run. A few common ones:
ufw allow 'Nginx Full' # HTTP and HTTPS, once nginx is installed
ufw allow 51820/udp # WireGuard
ufw allow from 203.0.113.0/24 to any port 5432 proto tcp # PostgreSQL, from one network onlyufw app list shows which profiles your installed packages provide.
You can also rate-limit SSH. With this rule instead of the plain one, ufw refuses an address that opens six or more connections in 30 seconds:
ufw limit OpenSSHIt takes the edge off, but for proper brute-force protection add fail2ban too.
To remove a rule, list them with numbers and delete by number:
ufw status numbered
ufw delete 3The numbers shift after every delete, so list them again before the next one.
The Docker gotcha
Ports published by Docker go straight past ufw. A container started with -p 8080:80 is reachable from the internet, and ufw status won't mention port 8080 at all. Install Docker shows how to bind containers to localhost instead.
If you lock yourself out
You can fix it from the serial console, if you've set a password to log in there with. Log in and run:
ufw allow OpenSSHOr switch the firewall off with ufw disable while you sort out the rules.