UFW, short for Uncomplicated Firewall, is Ubuntu's standard command-line tool for managing a host-based firewall. It lets you deny unsolicited inbound traffic and then open only the ports, protocols, and source networks your server actually needs.
In this tutorial, you will install UFW on Ubuntu 24.04, protect SSH before enabling the firewall, configure IPv4 and IPv6 rules, allow web traffic, restrict private services by source address, inspect logs, and avoid common mistakes involving Docker-published ports.
Step 1 — Update Ubuntu and Install UFW
Update the package index and install UFW:
sudo apt update
sudo apt install -y ufw
Check its current state:
A new installation normally reports:
UFW being inactive does not mean every port is automatically open. A service must still be listening on an interface before it can accept connections. UFW adds a deny-by-default policy so newly started or accidentally exposed services are not reachable unless you permit them.
Step 2 — Check IPv6 Before Enabling the Firewall
If the VM has IPv6 connectivity, UFW should manage IPv6 rules as well as IPv4 rules.
Check the setting:
grep '^IPV6=' /etc/default/ufw
For dual-stack servers, the result should be:
If it is set to no, edit the file before enabling UFW:
sudo nano /etc/default/ufw
Set:
Do not publish an AAAA DNS record unless IPv6 is configured and protected correctly. UFW will display separate (v6) rules when IPv6 support is enabled.
Step 3 — Identify and Allow the Active SSH Port
Always allow SSH before enabling UFW. Otherwise, a deny-incoming policy can lock you out of the VM.
Check the effective SSH port:
sudo sshd -T | awk '$1 == "port" {print $2}'
For the default port 22, allow the OpenSSH application profile:
If SSH uses a custom port, allow that port instead. For example:
sudo ufw allow 2222/tcp comment 'SSH'
Confirm the rule exists:
Keep the current SSH session open until the firewall is enabled and a second connection has been tested.
Step 4 — Set the Default Policies
Deny new incoming connections unless a rule allows them, while permitting normal outbound traffic:
sudo ufw default deny incoming
sudo ufw default allow outgoing
These defaults are appropriate for most application servers. Package downloads, DNS queries, API calls, and other outbound connections continue to work, while inbound access must match an explicit allow rule.
UFW is primarily a host firewall. It complements upstream network controls and DDoS protection but does not replace them.
Step 5 — Enable UFW and Verify Remote Access
Enable the firewall:
Confirm the prompt, then inspect the effective rules:
You should see Status: active, the default incoming and outgoing policies, and the SSH rule you created.
Open a second terminal on your local computer and test a new connection:
ssh your_user@your_server_ip
Do not close the original session until this succeeds. If the new connection fails, use the existing session to review the SSH port and UFW rules.
Step 6 — Allow HTTP, HTTPS, and Application Profiles
For a public web server, allow ports 80 and 443:
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
Applications can install named UFW profiles. List them with:
If Nginx is installed, inspect its profiles:
sudo ufw app info 'Nginx Full'
Then allow both HTTP and HTTPS with:
sudo ufw allow 'Nginx Full'
Do not create duplicate numeric and application-profile rules unless there is a reason to keep both. For the complete web-server flow, follow How to Install Nginx on Ubuntu 24.04 and How to Secure Nginx with Let's Encrypt.
Step 7 — Restrict Private Services by Source Address
Databases, admin panels, and monitoring services should not be globally reachable unless the application requires public access.
Allow PostgreSQL only from a private subnet:
sudo ufw allow from 10.0.0.0/24 to any port 5432 proto tcp comment 'Private PostgreSQL'
Allow a management port from one trusted public IP:
sudo ufw allow from 203.0.113.5 to any port 9090 proto tcp comment 'Admin access'
The address 203.0.113.5 is an example documentation address. Replace it with your actual trusted source IP.
For multi-VM workloads, prefer a Raff VPC and bind the service to its private interface. A UFW source rule is an additional control; it does not correct a service that is bound to the wrong interface or configured with weak authentication.
Step 8 — Rate-Limit SSH Carefully
UFW provides a limit action for services such as SSH. It can reduce repeated connection bursts from one source address, but it is not a full intrusion-prevention or DDoS system.
Replace a plain default-port SSH allow rule with a limit rule:
sudo ufw delete allow OpenSSH
sudo ufw limit OpenSSH
For a custom SSH port:
sudo ufw limit 2222/tcp comment 'Rate-limited SSH'
Check the result:
Rate limiting can affect legitimate users behind the same NAT address or automation that opens many short-lived connections. SSH keys and disabled password authentication remain the more important controls. Follow How to Set Up SSH Keys on Ubuntu 24.04 before tightening SSH access further.
Step 9 — Review, Delete, and Reset Rules
Display numbered rules:
Delete a rule by number:
Because the list is renumbered after each deletion, run status numbered again before deleting another rule.
You can also delete a rule by repeating its original syntax:
sudo ufw delete allow 3000/tcp
Reload rules without disabling the firewall:
Temporarily disable UFW while retaining its rules:
Reset all rules and return UFW to an inactive state:
Use reset only when you intend to rebuild the complete policy, including SSH access.
Step 10 — Enable Logging and Inspect Blocked Traffic
Enable low-volume logging:
Inspect recent kernel firewall messages:
sudo journalctl -k -g 'UFW' --since '15 minutes ago'
On systems using rsyslog, UFW messages may also be available in /var/log/ufw.log:
sudo test -f /var/log/ufw.log && sudo tail -n 50 /var/log/ufw.log
Increase logging only while troubleshooting because higher levels can create substantial disk activity on busy public servers.
Confirm UFW starts with the server:
sudo systemctl is-enabled ufw
The expected result is enabled.
Step 11 — Check Listening Services Against the Firewall
List processes listening on network ports:
Compare this output with:
A port can be listening locally without being allowed through UFW. Conversely, an allow rule does nothing useful when no application is listening. Remove stale rules when a service is retired.
Test public ports from another machine rather than from the server itself. UFW controls traffic reaching the host and a local connection does not reproduce the same network path.
Step 12 — Account for Docker-Published Ports
Docker creates its own firewall and NAT rules. Ports published with commands such as -p 8080:80 can be routed before UFW's normal input rules, so a restrictive UFW policy alone may not protect those container ports.
Review published ports:
docker ps --format 'table {{.Names}}\t{{.Ports}}'
For services that should only be reached through a local reverse proxy, bind them to loopback:
Use Docker's DOCKER-USER chain or an upstream firewall when source filtering is required for published container ports. Do not disable Docker's firewall rule management unless you are replacing it with a complete tested policy, because doing so can break container networking.
See How to Install Docker on Ubuntu 24.04 before exposing container services.
Conclusion
Your Ubuntu 24.04 server now has an active UFW policy that protects SSH, denies unsolicited incoming traffic, allows only required services, supports source-restricted rules, and produces logs you can inspect.
Raff Linux VMs start at $8.49 per month with 2 vCPU, 2 GB RAM, 40 GB NVMe storage, and 3 Gbps unmetered bandwidth. UFW is configured inside the operating system and works alongside Raff's infrastructure-level security controls.
Review sudo ss -tulpn and sudo ufw status numbered whenever you deploy or remove a service. Firewall rules are most useful when they remain aligned with the applications actually listening on the VM.