UFW (Uncomplicated Firewall) is the default firewall front end on Ubuntu. It writes netfilter rules for you through short, readable commands, so you can control which ports and addresses can reach your server without writing raw iptables or nftables rules. In this tutorial you will configure UFW on Ubuntu 24.04 with a default deny policy, allow SSH and web traffic, restrict a service to a single IP, rate limit SSH and learn how to review and delete rules.
Prerequisites
To follow this tutorial, you need:
- A server running Ubuntu 24.04 LTS (Debian 12 works the same way once UFW is installed), for example a CubePath VPS.
- A non-root user with
sudoprivileges. - An open SSH session to the server. Keep it open until you have confirmed that a new SSH connection still works after enabling the firewall.
WarningIf you enable UFW before allowing SSH, your current session may keep working but new connections will be refused. Always add the SSH rule first.
Step 1 - Installing UFW
UFW ships preinstalled on Ubuntu 24.04. On Debian 12 and minimal images it may be missing. Install it (the command does nothing if it is already present):
sudo apt update
sudo apt install ufw
Check the current state:
sudo ufw status verbose
On a fresh server the firewall is inactive:
Status: inactive
Step 2 - Setting the default policies
Default policies decide what happens to traffic that no rule matches. The safe baseline for a server is to block all incoming connections and allow all outgoing ones:
sudo ufw default deny incoming
sudo ufw default allow outgoing
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)
Default outgoing policy changed to 'allow'
(be sure to update your rules accordingly)
Nothing is enforced yet because UFW is still inactive. IPv6 is handled automatically: IPV6=yes is the default in /etc/default/ufw, so every rule you add applies to both IPv4 and IPv6.
Step 3 - Allowing SSH
Before enabling the firewall, allow SSH so you do not lock yourself out. Packages can register application profiles with UFW. List them:
sudo ufw app list
Available applications:
OpenSSH
Allow the OpenSSH profile, which opens port 22/tcp:
sudo ufw allow OpenSSH
If SSH listens on a custom port, allow that port instead. For example, for port 2222:
sudo ufw allow 2222/tcp
To slow down brute force attempts, you can use limit instead of allow. UFW then denies an address that opens 6 or more connections within 30 seconds:
sudo ufw limit OpenSSH
If you already added an allow rule for the same port, limit updates it rather than creating a duplicate.
Step 4 - Allowing other services
Open only the ports your applications actually need. For a web server serving HTTP and HTTPS:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
If Nginx or Apache is installed, you can use their profiles instead (sudo ufw allow 'Nginx Full' or sudo ufw allow 'Apache Full'). They only appear in ufw app list after the web server package is installed.
Open a range of ports by giving the protocol explicitly:
sudo ufw allow 6000:6007/tcp
Step 5 - Restricting access by IP address
Services such as databases or admin panels should not be reachable from the whole Internet. Allow them only from a trusted address. Replace your_trusted_ip with the public IP of your office, another server or your home connection:
sudo ufw allow from your_trusted_ip to any port 3306 proto tcp
You can also allow a whole subnet, for example a private network:
sudo ufw allow from 10.0.0.0/24
To block a specific address entirely, use deny. Because UFW evaluates rules in order and stops at the first match, insert the deny rule at the top so it takes effect before any allow rules:
sudo ufw insert 1 deny from 203.0.113.50
Step 6 - Enabling UFW
Review the rules you have added before activating them:
sudo ufw show added
Added user rules (see 'ufw status' for running firewall):
ufw limit OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
Make sure SSH is in the list, then enable the firewall:
sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
Now open a second terminal and connect to the server with SSH. If the new connection works, your SSH rule is correct and you can close the old session.
Step 7 - Checking the active rules
Show the running rule set together with the default policies:
sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip
To Action From
-- ------ ----
OpenSSH LIMIT IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
OpenSSH (v6) LIMIT IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
You can also confirm from another machine that a port you did not open is now filtered, for example with nc -zv your_server_ip 8080, which should time out.
Step 8 - Deleting rules
List the rules with their numbers:
sudo ufw status numbered
To Action From
-- ------ ----
[ 1] OpenSSH LIMIT IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere
[ 4] OpenSSH (v6) LIMIT IN Anywhere (v6)
[ 5] 80/tcp (v6) ALLOW IN Anywhere (v6)
[ 6] 443/tcp (v6) ALLOW IN Anywhere (v6)
Delete a rule by number. UFW asks for confirmation and renumbers the remaining rules afterwards, so list them again before deleting another one:
sudo ufw delete 2
Deleting by number removes only the IPv4 or the IPv6 entry. To remove both at once, delete the rule by its original syntax:
sudo ufw delete allow 80/tcp
Step 9 - Using the UFW log
With logging on (the default level is low), UFW logs blocked packets to the kernel log with the prefix [UFW BLOCK]. On Ubuntu 24.04 they are written to /var/log/ufw.log. Follow them while you test a connection:
sudo tail -f /var/log/ufw.log
Sep 25 10:12:03 server kernel: [UFW BLOCK] IN=eth0 OUT= SRC=198.51.100.23 DST=203.0.113.10 PROTO=TCP SPT=51544 DPT=3306 ...
DPT is the destination port that was blocked, which tells you which rule is missing if a legitimate service stops working.
Troubleshooting
- Locked out of SSH. Log in through the VNC console in your provider's control panel, then run
sudo ufw allow OpenSSH(or your custom port) orsudo ufw disabletemporarily while you fix the rules. - Docker containers are reachable despite UFW. Docker writes its own netfilter rules for published ports, and they bypass UFW's input rules. Publish internal services only on localhost (for example
-p 127.0.0.1:8080:80) instead of relying on UFW to hide them. - Starting over.
sudo ufw resetdisables the firewall and deletes all rules, keeping backups of the old rule files in/etc/ufw. Add your SSH rule again before re-enabling it.
Conclusion
Your server now drops all unsolicited incoming traffic except the services you explicitly allowed, for both IPv4 and IPv6, and SSH is protected by rate limiting. Keep the rule set small and review it with sudo ufw status numbered whenever you add or remove a service. As next steps, consider switching SSH to key-based authentication, installing Fail2ban for smarter brute force protection, and restricting admin ports to your own IP addresses.
