Key Takeaways

- UFW translates simple commands into complex netfilter rules, making firewall setup accessible without deep networking knowledge
- On current Ubuntu and Debian, UFW 0.36.x uses nftables backend through iptables-nft compatibility layer
- Start with deny-all incoming, allow-all outgoing defaults, then whitelist only the services you need
UFW, the Uncomplicated Firewall, is the fastest way to secure a fresh Ubuntu or Debian server. It wraps the kernel's netfilter framework in readable commands, so you type 'sudo ufw allow ssh' instead of wrestling with iptables syntax. This guide walks through installation, default policies, application profiles, and logging.
Most cloud servers face thousands of automated attacks daily. An open SSH port without rate limiting or a forgotten test service can become an entry point within hours. UFW does not make a server invincible, but it closes the most common gaps in minutes rather than hours.
What UFW actually does under the hood
UFW does not replace the Linux kernel's firewall. It manages it. The kernel filters network traffic through netfilter, which administrators traditionally configure with iptables or, more recently, nftables. Writing those rules by hand is powerful but error-prone. UFW sits on top of that machinery and translates short, readable commands into the lower-level rules the kernel enforces.
On current Ubuntu and Debian releases, UFW 0.36.x uses the nftables backend through the iptables-nft compatibility layer. Even when you think in iptables terms, the rules are applied through nftables under the hood. This change is transparent. The commands in this guide work identically regardless of the backend.
To check your installed version, run:
sudo ufw versionThe output shows the UFW version and license. Expect something like 'ufw 0.36.2' on recent distributions.
Installing UFW on Ubuntu and Debian
Ubuntu ships with UFW installed but disabled by default. Debian may or may not include it depending on the image. Either way, installation is one command:
sudo apt update && sudo apt install ufwIf UFW is already present, apt will confirm and move on. Before enabling anything, ensure you have a non-root user with sudo privileges. The DigitalOcean initial server setup guides for Ubuntu and Debian cover this. Locking yourself out of SSH by enabling UFW without allowing port 22 is a common mistake.
Setting default policies
A firewall needs a baseline stance: what happens to traffic that matches no explicit rule? The safest default is to deny all incoming connections and allow all outgoing. Your server can still reach the internet, but nothing gets in unless you whitelist it.
sudo ufw default deny incoming
sudo ufw default allow outgoingThese commands do not take effect until you enable UFW. Think of them as loading a policy that remains dormant until activation.
Allowing SSH before enabling UFW
If you enable UFW with deny-all incoming and forget to allow SSH, you lose remote access immediately. Allow SSH first:
Code sample: sudo ufw allow ssh
UFW recognizes 'ssh' as an alias for port 22. You can also specify the port directly with 'sudo ufw allow 22'. If your SSH daemon runs on a non-standard port, use that number instead.
Enabling UFW and checking status
With SSH allowed, enable the firewall:
Code sample: sudo ufw enable
UFW warns that this may disrupt existing SSH connections. Confirm, and the firewall activates. Check status with:
Code sample: sudo ufw status verbose
This displays active rules, default policies, and whether logging is on. The 'verbose' flag adds detail about each rule's direction and action.
Using application profiles
UFW ships with pre-configured profiles for common services. List them with:
Code sample: sudo ufw app list
Profiles like 'Nginx Full', 'OpenSSH', and 'Apache' bundle the correct ports. Allow a profile by name:
Code sample: sudo ufw allow 'Nginx Full'
This opens both HTTP (80) and HTTPS (443). Profiles reduce typos and make rule audits easier. Install packages like Nginx or Apache, and their profiles appear automatically.
Allowing specific ports and IP addresses
For services without profiles, allow by port number:
Code sample: sudo ufw allow 3000
That opens TCP port 3000 for a Node.js app, for instance. To restrict access to a single IP address:
Code sample: sudo ufw allow from 203.0.113.50 to any port 22
Now only that IP can reach SSH. Combine this with denying SSH globally for tighter control.
Denying connections and deleting rules
Deny works like allow, but blocks instead:
Code sample: sudo ufw deny 23
To remove a rule, use 'delete' followed by the rule:
Code sample: sudo ufw delete allow 3000
Alternatively, list rules by number with 'sudo ufw status numbered', then delete by index. This is cleaner when rules get complex.
Enabling logging for troubleshooting
UFW can log blocked and allowed connections. Enable logging with:
Code sample: sudo ufw logging on
Logs appear in /var/log/ufw.log. Review them when connections fail unexpectedly. High-traffic servers may want to set logging to 'low' or 'medium' to reduce disk writes.
Resetting UFW to defaults
If rules become tangled, reset everything:
Code sample: sudo ufw reset
This disables UFW and deletes all rules. You start fresh. Remember to allow SSH again before re-enabling.
| Tool | Complexity | Best for |
|---|---|---|
| UFW | Low | Quick setups, most Ubuntu/Debian servers |
| firewalld | Medium | RHEL/CentOS, zone-based policies |
| iptables/nftables | High | Granular control, custom chains |
IPv6 considerations
UFW applies rules to IPv6 by default if IPv6 is enabled on the system. Verify this in /etc/default/ufw where IPV6=yes should be set. If you disable IPv6 at the OS level, UFW ignores it. For dual-stack servers, each 'allow' command creates both IPv4 and IPv6 rules automatically.
Frequently Asked Questions
What happens if I enable UFW without allowing SSH?
You immediately lose remote access. Always run 'sudo ufw allow ssh' before 'sudo ufw enable'. If locked out, access the server via console (cloud provider dashboard or physical KVM) to disable UFW.
Does UFW persist across reboots?
Yes. Once enabled, UFW starts automatically on boot with your saved rules intact. Disable it explicitly with 'sudo ufw disable' if needed.
Can I use UFW alongside Docker?
Docker manipulates iptables directly, which can bypass UFW rules. Use the DOCKER-USER chain for firewall rules affecting Docker containers, or configure Docker with iptables=false and manage everything manually.
How do I allow a port range?
Specify the range with a colon: 'sudo ufw allow 6000:6007/tcp'. The protocol (tcp or udp) is required for ranges.
Is UFW enough for production servers?
UFW handles host-based firewalling well. For production, pair it with fail2ban for brute-force protection, network-level firewalls from your cloud provider, and regular security audits.
Logicity's Take
UFW is the right tool for 90% of Ubuntu and Debian server setups. It costs nothing and takes five minutes. Engineering teams spinning up staging environments or side projects should not skip this step. For production workloads, combine UFW with your cloud provider's network firewall (AWS Security Groups, GCP VPC firewall rules, DigitalOcean Cloud Firewalls) for defense in depth. The cloud firewalls block traffic before it reaches your VM, reducing load on the host. If you manage fleets of servers, consider Ansible roles or Terraform to template UFW rules consistently rather than configuring each box by hand.
Need Help Implementing This?
Logicity can connect you with infrastructure specialists who configure firewalls, automate server hardening, and audit security postures. Reach out through our consulting page to discuss your setup.
Manaal Khan
Tech & Innovation Writer
Produced with AI assistance and reviewed by the Logicity editorial team. Learn more in our Editorial Policy.
Related Articles
Browse all
CVE Vulnerability Tracker: How to Build an Automated Security Dashboard with Notion and Kestra
A developer shares her journey building an automated CVE vulnerability tracker using Notion's database plugins and Kestra workflows. The tutorial covers plugin defaults, handling tricky data types like rich text arrays, and integrating AI for priority assessment.

CoreOptimize FPS Calculator: Build Your Own Game Performance Estimator in 30 Minutes
Tired of downloading games only to find they run like a slideshow? This tutorial walks you through building a simple FPS calculator that estimates game performance based on your actual hardware specs. No frameworks needed, just HTML and JavaScript.

ReactFlow Multi-Selection Tutorial: Building Undo/Redo and Box Selection From Scratch
A deep technical walkthrough of implementing multi-selection with undo/redo in ReactFlow. The ArchScope team shares their coordinate transformation nightmares, event handling gotchas, and the solutions that actually worked.



