How to Set Up a Firewall on Ubuntu Server with UFW

A firewall decides which doors on your server are open. By default Ubuntu Server leaves every door that a running program opens reachable from the whole network. UFW (Uncomplicated Firewall) closes them all and lets you open only the ones you choose. It's installed already; it just isn't switched on.
Quick reference
| Task | Command |
|---|---|
| Allow SSH (do this first!) | sudo ufw allow OpenSSH |
| Turn the firewall on | sudo ufw enable |
| See the rules | sudo ufw status numbered |
| Open a port | sudo ufw allow 80/tcp |
| Remove a rule | sudo ufw delete 3 |
| Turn it off | sudo ufw disable |
1. Allow SSH before anything else
If you enable the firewall without this step, your SSH connection is the first thing it blocks.
sudo ufw allow OpenSSH
If you've moved SSH to a different port, allow that instead: sudo ufw allow 2222/tcp.
2. Turn it on
sudo ufw enable
It warns that existing connections may be disrupted — type y. Your current SSH session survives because you allowed it in step 1.
The defaults are now: block everything coming in, allow everything going out. That's exactly what you want.
3. Open the ports your services use
Only open what you actually run:
sudo ufw allow 80/tcp # web server (http)
sudo ufw allow 443/tcp # web server (https)
sudo ufw allow 445/tcp # Samba file sharing
sudo ufw allow 51820/udp # WireGuard VPN
Many apps have profiles so you can use the name instead: sudo ufw app list shows them, and sudo ufw allow 'Nginx Full' opens 80 and 443 together.
4. Only allow your home network
For a service you'd never use from outside, limit it to your local network:
sudo ufw allow from 192.168.1.0/24 to any port 445
The /24 means "any address starting 192.168.1".
5. Check what's allowed
sudo ufw status numbered
Each rule has a number. To remove one:
sudo ufw delete 3
Logging
sudo ufw logging on writes blocked attempts to /var/log/ufw.log. Useful when a service "mysteriously" isn't reachable — you'll see the port it tried.
Troubleshooting
You've locked yourself out. Log in at the server's keyboard and run sudo ufw allow OpenSSH (or sudo ufw disable to start again).
A service still isn't reachable after allowing the port. Check it's actually listening: sudo ss -tlnp lists open ports and the program behind each. If it's only on 127.0.0.1, it's bound to localhost and the firewall isn't the problem.
Docker containers ignore the firewall. Docker writes its own rules that bypass UFW. Publish container ports only on 127.0.0.1 unless you want them open, or put a reverse proxy in front (tutorial 28).
TCP or UDP? Almost everything is TCP. WireGuard, DNS and some game servers use UDP. If unsure, allow the port without specifying and UFW opens both.
Wrapping up
Allow SSH, enable, then open ports one at a time as you install things. Check ufw status whenever something isn't reachable. Five commands, and random scans of your server now hit a wall.
