How to Set Up a UFW Firewall on Ubuntu
Configure a UFW firewall on Ubuntu the safe way: default policies, allow SSH/HTTP/HTTPS, rate-limit, and verify rules before locking yourself out.
A server exposed to the internet is probed within minutes of coming online. A host firewall is your first, simplest line of defense: it decides which ports the outside world can reach before any service even sees the traffic. On Ubuntu, the tool for the job is UFW (Uncomplicated Firewall), a friendly front end to the kernel's nftables/iptables backend that turns common rules into one-liners.
This guide sets up UFW on Ubuntu 24.04 LTS the safe way. The single biggest risk when configuring a firewall on a remote machine is locking yourself out by enabling the firewall before allowing SSH. We will allow SSH first, set sane default policies, open only the ports you actually need, add rate-limiting, and verify every rule before and after enabling it.
Prerequisites
- A machine running Ubuntu 24.04 LTS.
- A user with
sudoprivileges. - If you are connected over SSH, know which port sshd listens on (the default is
22).
Step 1: Check whether UFW is installed
UFW ships with Ubuntu by default, but confirm it is present and see its current status:
sudo ufw status verboseOn a fresh system you will see:
Status: inactiveIf the command is not found, install it:
sudo apt update
sudo apt install ufwStep 2: Allow SSH before you do anything else
This is the rule that keeps you from being locked out. Add it now, while the firewall is still inactive:
sudo ufw allow OpenSSHThe OpenSSH application profile opens TCP port 22. If your SSH daemon listens on a non-standard portโsay 2222โallow that explicitly instead:
sudo ufw allow 2222/tcpYou can list the named application profiles UFW knows about with:
sudo ufw app listStep 3: Set default policies
A good firewall denies everything inbound and allows everything outbound, then opens only the inbound ports you need. Set those defaults:
sudo ufw default deny incoming
sudo ufw default allow outgoingStep 4: Allow the services you actually run
Open ports for the services this host provides. For a web server:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcpUFW also understands named profiles installed by packages such as Nginx:
sudo ufw allow 'Nginx Full'To restrict a port to a single trusted sourceโfor example, allow PostgreSQL only from one app server:
sudo ufw allow from 10.0.0.5 to any port 5432 proto tcpTo open a port to an entire subnet:
sudo ufw allow from 10.0.0.0/24 to any port 3306 proto tcpStep 5: Rate-limit SSH against brute force
UFW can throttle repeated connection attempts. The limit rule denies an IP that makes more than six connections in 30 secondsโan easy win against brute-force scanners:
sudo ufw limit OpenSSHIf you allowed SSH on a custom port, limit that instead: sudo ufw limit 2222/tcp. Note that limit replaces the plain allow for that port, so you do not need both.
Step 6: Review rules before enabling
Check the rules that are staged. Because the firewall is still inactive, this shows what will take effect:
sudo ufw show addedConfirm SSH is in the list. This is your last chance to catch a mistake before flipping the switch.
Step 7: Enable the firewall
sudo ufw enableUFW warns that the command may disrupt existing SSH connections and asks to proceed. Because you allowed SSH in Step 2, your current session survives. Type y and press ENTER.
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startupStep 8: Verify the active rule set
sudo ufw status verboseStatus: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skipTo Action From
22/tcp (OpenSSH) LIMIT Anywhere 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere
Open a second SSH session to the server right now, while your first session is still active. If the new connection succeeds, your rules are correct. Never close your only working session until you have proven a new one connects.
Managing rules later
List rules with numbers so you can delete by index:
sudo ufw status numberedDelete a rule by its number:
sudo ufw delete 3Or delete by specifying the original rule:
sudo ufw delete allow 80/tcpReset everything back to defaults (this disables the firewall and wipes rules):
sudo ufw resetCommon pitfalls and troubleshooting
- Enabling UFW before allowing SSH. The classic lockout. Always run
ufw allow OpenSSHfirst. If you do lock yourself out, you will need console or out-of-band access to recover. - Wrong SSH port. If sshd listens on a custom port, the
OpenSSHprofile (port 22) will not help. Check withsudo ss -tlnp | grep sshand allow the correct port. - Docker bypasses UFW. Docker writes its own iptables rules and publishes container ports directly, ignoring UFW. Bind containers to
127.0.0.1or use a dedicated approach on a firewalled host. - IPv6 forgotten. Ensure
IPV6=yesin/etc/default/ufw(the default) so rules apply to IPv6 too. - Checking logs. Blocked packets are logged. Watch them with
sudo tail -f /var/log/ufw.logto see what is being dropped.
Conclusion
A host firewall with deny-by-default inbound, an allow rule for SSH, rate-limiting, and only the ports your services need is a baseline every Ubuntu server should have. UFW makes that a five-minute job and keeps the rule set readable months later when you have forgotten why port 8443 is open.
A firewall is one layer. Pair it with automated brute-force blockingโsee our guide to stopping brute-force attacks with fail2banโfor defense in depth. The same model scales into the cloud: in OpenStack you replace per-host firewalls with security groups and keypairs that apply consistently across every instance. If you would rather not maintain firewall rules host by host, clouditiv runs a hardened, ISO 27001 / BSI C5 sovereign cloud where network policy is centrally enforced and your data stays in Germany.