Blog
3 min read

UFW Firewall Basics: Lock Down a Linux Server in Five Commands

A firewall decides which network traffic can reach your server. UFW makes Linux's firewall simple: allow SSH, HTTP and HTTPS, deny the rest. The commands, how not to lock yourself out, why your database port should never be open, and the Docker gotcha that bypasses UFW.

A brand-new server on the internet starts receiving automated login attempts and port scans within minutes. A firewall decides which of those connections are allowed to reach anything. On Ubuntu and Debian, the friendly way to manage it is UFW — "Uncomplicated Firewall."

The idea

Every network service listens on a port: SSH on 22, websites on 80 and 443, Postgres on 5432. (Ports explained) A firewall's job is simple: deny everything incoming by default, then allow only the ports you need.

For a typical web server, that's three:

Port For
22 SSH (so you can log in)
80 HTTP (redirects to HTTPS, certificate checks)
443 HTTPS

Everything else — your database, Redis, your app's internal port 3000 — should be reachable only from the server itself.

The five commands

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH          # do this BEFORE enabling!
sudo ufw allow 80,443/tcp
sudo ufw enable

Then check:

sudo ufw status verbose

Don't lock yourself out

If you enable UFW without allowing SSH first, your current session may survive, but the next login won't. On a cloud server, that means using the provider's web console to fix it.

  • Always ufw allow OpenSSH (or ufw allow 22/tcp) before ufw enable.
  • If you moved SSH to another port, allow that port instead.
  • Keep your current SSH session open while testing a new login in a second terminal.

Useful extras

sudo ufw limit OpenSSH                         # rate-limit SSH attempts
sudo ufw allow from 203.0.113.10 to any port 22   # SSH only from your IP
sudo ufw status numbered                       # list rules with numbers
sudo ufw delete 3                              # remove rule number 3
sudo ufw disable                               # turn it off (troubleshooting)

Never expose your database

A surprising number of data breaches start with a database port open to the internet, protected only by a password (or the default password). Postgres, MySQL, MongoDB and Redis should not be reachable from outside:

  • Don't ufw allow 5432.
  • Configure the database to listen on localhost only.
  • To look at the database from your laptop, use an SSH tunnel instead. (SSH port forwarding)

Same for your app's internal port: visitors should come through your reverse proxy on 443, not straight to port 3000. (What is Nginx?)

The Docker gotcha

Docker writes its own firewall rules directly into iptables, and they're processed before UFW's. So this:

ports:
  - "5432:5432"

publishes Postgres to the whole internet even if UFW says port 5432 is denied. ufw status won't show it.

Fixes:

  • Bind published ports to localhost: "127.0.0.1:5432:5432".
  • Or don't publish database ports at all; let containers talk over a Docker network.

(Container networking internals explains why this happens.)

Cloud firewalls

Most cloud providers (Hetzner, DigitalOcean, AWS security groups) also offer a firewall outside your server, in their dashboard. It filters traffic before it reaches the machine and isn't affected by the Docker issue. Using both is a good belt-and-braces setup.

A firewall is one layer

It doesn't replace the rest of securing a new server: SSH keys instead of passwords, automatic security updates, and not running your app as root.

The summary

  • Deny incoming by default; allow 22, 80 and 443.
  • Allow SSH before enabling, or you'll lock yourself out.
  • Never open database ports; use SSH tunnels.
  • Docker's published ports bypass UFW — bind them to 127.0.0.1.

EasySpawn servers come with the firewall, patching and SSL handled for you, and databases that are never exposed to the internet. See how it works or join the waitlist.

Related: How to Secure a New VPS · What Is a VPS? · Ports Explained · SSH Keys Explained

Keep reading