Exclusive offer — -20% on all VPS plans with code NVH20 · Deployment in 60 seconds
Home / Documentation / Configuring UFW
Security

Configuring the UFW firewall on a VPS: the allow-list approach

By NVHCloud Team 3 October 2026 5 min read

UFW, the Uncomplicated Firewall, ships with Ubuntu and is available on Debian. It drives the Linux kernel firewall with readable commands. Set up properly, it guarantees that a service installed by mistake, or a database left open, cannot be reached from the Internet.

1. The principle: close everything, then open case by case

The only sensible policy on an exposed server is an allow-list: all incoming traffic is denied by default, and you only open the ports you actually need. Outgoing traffic stays allowed so the server can update itself.

Before you start, list what is really listening on the server:

ss -tulpn

Any service listening on 0.0.0.0 or [::] may be reachable from the Internet. Services listening on 127.0.0.1 are not.

2. Install and enable

apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw enable
ufw status verbose
⚠️ Always allow SSH before ufw enable, otherwise your session is cut and you cannot reconnect. If you moved SSH to another port, replace OpenSSH with 2222/tcp, for example.

UFW handles IPv4 and IPv6 at the same time. Check that IPV6=yes is set in /etc/default/ufw: otherwise your rules would not apply to the server's IPv6 address.

3. Ports to open for each use

UseCommand
Website (HTTP and HTTPS)ufw allow 80,443/tcp
FiveMufw allow 30120 (TCP and UDP)
Minecraft Javaufw allow 25565/tcp
Minecraft Bedrockufw allow 19132/udp
Rustufw allow 28015/udp and ufw allow 28016/tcp for RCON
WireGuardufw allow 51820/udp
Mail (SMTP, IMAP)ufw allow 25,465,587,993/tcp

Without a protocol, as for FiveM, the rule opens both TCP and UDP. Specify it whenever you can so you do not open more than needed. Add a comment to find your way later:

ufw allow 30120 comment 'FiveM'
⚠️ Never open database ports (3306 for MySQL and MariaDB, 5432 for PostgreSQL, 6379 for Redis, 27017 for MongoDB) to the whole Internet. They are favourite bot targets. If remote access is essential, restrict it to one IP address as shown below, or go through an SSH tunnel or a VPN.

4. Restrict a port to one IP address

For an admin panel, a database or a game server's RCON, only allow your own address:

ufw allow from 203.0.113.10 to any port 3306 proto tcp comment 'MariaDB office'
ufw allow from 203.0.113.10 to any port 28016 proto tcp comment 'Rust RCON'

Replace 203.0.113.10 with your public IP address. If it changes often, as with many ISPs, use a VPN instead: see our VPN offer.

5. Rate-limit SSH connections

The limit rule rejects an address that opens 6 or more connections within 30 seconds. It is an effective first brake on brute force:

ufw delete allow OpenSSH
ufw limit OpenSSH

Add Fail2ban, which bans for longer: see securing SSH.

6. Manage rules

ufw status numbered        # numbered rules
ufw delete 4               # delete rule number 4
ufw delete allow 80/tcp    # delete a rule by its content
ufw reload                 # reload after a manual change
ufw logging low            # log blocked packets

Blocked packets appear in /var/log/ufw.log, or with journalctl -k | grep UFW. Useful to understand why a service does not answer.

7. The Docker trap

This is the most frequent surprise, and a dangerous one: ports published by Docker bypass UFW. Docker writes its own rules into the kernel firewall, ahead of UFW's. A container started with -p 3306:3306 is therefore reachable from the Internet even if ufw status does not allow it.

The simplest fix is to publish on all interfaces only what must be public, and bind the rest to the local address:

ports:
  - "127.0.0.1:3306:3306"   # reachable from the server only
  - "80:80"                 # public, on purpose

Services that only other containers need to reach do not even need a ports section: they talk over Docker's internal network.

8. UFW and Anti-DDoS protection

UFW and Anti-DDoS do not do the same job. UFW decides which services are reachable. It does not stop a volumetric attack: when gigabits of traffic hit your server, the link is saturated before the firewall can reject anything. That filtering must happen upstream, on the network. It is the role of the Anti-DDoS protection included with our VPS. The two complement each other.

Frequently asked questions

I locked myself out after ufw enable, what now?
Contact support to get console access, then run ufw allow OpenSSH or ufw disable. To avoid this, always allow SSH before enabling UFW.
Why is my Docker container reachable when UFW blocks the port?
Because Docker inserts its own rules into the kernel firewall, and they apply before UFW's. Publish internal ports on 127.0.0.1 in your Compose file, or do not publish them at all if only other containers use them.
Does UFW protect against DDoS attacks?
No. UFW filters which services are reachable, but a volumetric attack saturates the connection before the firewall can reject the traffic. You need protection upstream, on the provider's network.
UFW or firewalld?
UFW is the natural choice on Ubuntu and Debian. firewalld is the standard tool on AlmaLinux, Rocky Linux and Fedora. Both do the same job: use only one of them on a given server.