A fresh VPS with no firewall rules is wide open. Every port that has something listening on it is reachable from the entire internet, and automated scanners will find those ports within minutes of the server going online.

UFW (Uncomplicated Firewall) is the standard firewall management tool on Debian and Ubuntu systems. It sits on top of iptables and gives you a command-line interface that does not require memorising iptables syntax. If you have followed the VPS security checklist, you already know that enabling a firewall is one of the first things to do on a new server. This guide covers how to actually do it properly.

For RHEL-family distributions (Rocky Linux, AlmaLinux, CentOS Stream), the equivalent tool is firewalld. The principles are the same, but the commands differ. This article focuses exclusively on UFW.

Installing UFW

On most Ubuntu server images, UFW comes preinstalled. On Debian, it may not be. Check first:

which ufw

If that returns nothing, install it:

sudo apt update
sudo apt install ufw -y

Before enabling UFW, you need to configure your rules. Enabling it with no allow rules and a default-deny policy will lock you out of SSH immediately. Configure first, enable second.

Setting Default Policies

UFW has two default policies: one for incoming traffic and one for outgoing traffic. The correct starting point for a server is:

sudo ufw default deny incoming
sudo ufw default allow outgoing

This means: block all inbound connections unless explicitly allowed, and let all outbound connections through. Your server can still reach the internet (to download packages, send email, query APIs), but nothing from the outside can reach your server unless you open a specific port.

Some guides suggest restricting outbound traffic too. Unless you have a specific compliance requirement or a multi-tenant environment where you need to prevent certain egress patterns, denying outgoing traffic adds complexity without meaningful security benefit for a typical VPS workload.

Allowing SSH (Do This Before Enabling UFW)

This is the step people skip, and it is the step that locks them out:

sudo ufw allow ssh

That opens port 22 for both IPv4 and IPv6. If you changed your SSH port to something non-standard (which the security checklist discusses), specify it directly:

sudo ufw allow 2222/tcp

If you are currently connected to your server over SSH and you enable UFW without this rule, your session will survive (established connections are not killed), but you will not be able to reconnect after disconnecting. At that point, your only recovery option is your provider's web console or out-of-band access.

Enabling UFW

Once SSH is allowed:

sudo ufw enable

UFW will warn you that existing SSH connections might be disrupted. If you already added the SSH allow rule, confirm with y. The firewall is now active and will persist across reboots.

Check the current status:

sudo ufw status verbose

You should see your default policies and the SSH allow rule listed.

Allowing Web Traffic

If your server runs a website or web application, open the HTTP and HTTPS ports:

sudo ufw allow http
sudo ufw allow https

Or equivalently:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Both forms do the same thing. The named versions (http, https, ssh) are aliases defined in /etc/services.

If you are setting up SSL certificates afterward, you need port 80 open even for HTTPS-only sites. Certbot's HTTP-01 validation challenge uses port 80 to prove domain ownership, and automatic HTTP-to-HTTPS redirects also need it. The SSL setup guide covers this in detail.

Application Profiles

UFW supports application profiles, which are predefined rule sets that software packages register. List the available profiles:

sudo ufw app list

Common profiles include Nginx Full (opens both 80 and 443), Nginx HTTP, Nginx HTTPS, OpenSSH, and Apache Full. Using profiles is slightly more readable than raw port numbers:

sudo ufw allow 'Nginx Full'

You can inspect what a profile actually opens:

sudo ufw app info 'Nginx Full'

Application profiles are convenient shortcuts, nothing more. They resolve to the same underlying port rules. Use whichever form you find clearer.

Restricting Access by IP

Sometimes you need a port open, but only for a specific source. Database ports are the classic example: PostgreSQL (5432) or MySQL (3306) should almost never be open to the entire internet. If a second server needs to connect to your database, restrict the rule to that server's IP:

sudo ufw allow from 203.0.113.50 to any port 5432 proto tcp

This allows TCP connections to port 5432 only from 203.0.113.50. Everyone else is still blocked by the default deny policy.

For administrative ports you access from a fixed IP (your office, your home), you can lock down SSH the same way:

sudo ufw allow from 198.51.100.10 to any port 22 proto tcp

Be careful with IP-restricted SSH rules. If your home IP changes (most residential ISPs use dynamic addressing), you will be locked out. Keep a broader SSH rule as a fallback, or make sure you have console access through your provider's dashboard.

Rate Limiting

UFW has a built-in rate limiter that is useful for SSH:

sudo ufw limit ssh

This allows SSH connections but blocks an IP that makes more than six connection attempts within 30 seconds. It is a simple brute-force mitigation. It does not replace fail2ban for serious attack patterns (fail2ban watches authentication logs and bans based on failed login attempts, not just connection rate), but it adds a quick first layer of defence with a single command.

Rate limiting applies per source IP. Legitimate users making a normal number of connections will never notice it.

Checking and Deleting Rules

List all active rules with their numbers:

sudo ufw status numbered

Delete a rule by its number:

sudo ufw delete 3

Or delete by specifying the rule itself:

sudo ufw delete allow 80/tcp

If you want to start over entirely:

sudo ufw reset

That disables UFW and removes all rules. You are back to the beginning. Useful if you have made a mess of your rules and want a clean slate, but remember that reset also disables the firewall. Re-enable it after reconfiguring.

Logging

UFW can log blocked (and optionally allowed) connections:

sudo ufw logging on

The default level is low, which logs blocked packets. Logs go to /var/log/ufw.log. This is useful for diagnosing connectivity problems ("is the firewall blocking this?") and for spotting scanning patterns.

Higher logging levels (medium, high, full) log progressively more detail but generate significantly more output. For most VPS workloads, low is the right level. Bump it up temporarily when debugging a specific issue, then turn it back down.

Mistakes That Leave Servers Exposed

Even with UFW enabled, several common errors weaken or negate the protection:

  1. Opening ports for temporary testing and forgetting to close them. A quick allow 8080 during development becomes a permanent hole. Audit your rules periodically: sudo ufw status numbered. If you do not recognise a rule, investigate or delete it.

  2. Allowing entire subnets when only one IP is needed. allow from 10.0.0.0/8 is not the same as allowing a single server. Be as specific as the situation allows.

  3. Not enabling UFW after configuring rules. UFW rules exist in configuration files even when the firewall is inactive. You can add rules all day without them doing anything. Run sudo ufw status and confirm it says "active," not "inactive."

  4. Ignoring IPv6. UFW handles IPv6 by default (check that IPV6=yes exists in /etc/default/ufw), but some administrators disable IPv6 at the OS level without realising their firewall rules were relying on it. If your server has an IPv6 address, make sure your firewall covers it.

  5. Relying on the firewall instead of fixing the underlying problem. A firewall does not make a misconfigured service secure. If your database is set to listen on 0.0.0.0 instead of 127.0.0.1, fixing the bind address is better than adding a firewall rule to hide the mistake. Defence in depth means both: fix the configuration and add the firewall rule.

When UFW Is Not Enough

UFW covers the basics well, but it has limits. It does not handle:

  • Stateful application-layer inspection. UFW works at the network layer. It cannot block a specific HTTP path or inspect payload content.
  • Geo-blocking at scale. While you can add individual IP blocks, managing country-level blocklists through UFW rules is impractical. Tools like ipset with iptables, or a cloud provider's network firewall, are better suited.
  • Cloud-level firewalls. Many VPS providers offer a firewall at the infrastructure level (before traffic reaches your server). If your provider has this, use both: the cloud firewall as the outer layer and UFW on the server itself. Two independent layers that an attacker must bypass is always better than one.

If you are on an unmanaged VPS, the firewall is entirely your responsibility. Managed plans may handle some of this for you, but the coverage varies significantly between providers. Check what your plan actually includes before assuming the provider has it covered.

Quick Reference

Task Command
Install UFW sudo apt install ufw
Set default deny incoming sudo ufw default deny incoming
Set default allow outgoing sudo ufw default allow outgoing
Allow SSH sudo ufw allow ssh
Allow HTTP and HTTPS sudo ufw allow http then sudo ufw allow https
Allow custom port sudo ufw allow 8080/tcp
Allow from specific IP sudo ufw allow from 203.0.113.50 to any port 5432
Rate limit SSH sudo ufw limit ssh
Enable UFW sudo ufw enable
Check status sudo ufw status verbose
List numbered rules sudo ufw status numbered
Delete rule by number sudo ufw delete 3
Enable logging sudo ufw logging on
Reset all rules sudo ufw reset

Moving Forward

A properly configured UFW firewall cuts out a large category of low-effort attacks before they reach any service on your server. Combined with the other hardening steps in the VPS security checklist (SSH key authentication, fail2ban, automatic updates, TLS), it forms the foundation of a server that is not an easy target.

If you are still in the early stages of server setup, the first-time VPS setup guide covers the full sequence from first login to first deployment. And if you are evaluating providers, user reviews on VPS Host Review surface real experiences with security tooling, network quality, and support responsiveness across dozens of providers.