Uncomplicated Firewall (UFW) is a user-friendly front-end for managing iptables firewall rules. Its goal is to make firewall configuration easy, or “uncomplicated.” UFW is particularly well-suited for host-based firewalls. It simplifies the process of configuring a firewall by providing a simplified command-line interface. This article will guide intermediate users through the basics of UFW, covering installation, key commands, rule management, and practical examples for securing your Linux server.
Overview and Installation
UFW comes pre-installed with all Ubuntu installations. However, it is typically disabled by default. For other Debian-based distributions, if UFW is not installed, you can easily install it via the package manager.
To install UFW, use the following command:
sudo apt-get install ufwBasic Commands
Understanding the basic commands will help you manage UFW effectively. These commands allow you to enable, disable, and check the status of your firewall, providing quick insights into the rules that are active.
Enable UFW:
To activate the firewall, use:
sudo ufw enableThis command activates the firewall with the current ruleset. On a remote server, run sudo ufw allow OpenSSH (or sudo ufw allow 22/tcp) before you enable UFW. UFW denies incoming traffic by default, so enabling it without an SSH rule drops your session’s next connection and locks you out.
Disable UFW:
If you need to turn off the firewall, use:
sudo ufw disableThis will stop the firewall and deactivate all rules.
Check UFW Status:
To see which rules are currently active, along with the status of the firewall, use:
sudo ufw status verboseThis command provides a detailed output of all active rules and additional status information like logging settings.
Basic Rules
Setting up basic rules in UFW for common services such as SSH, HTTP, and HTTPS is straightforward.
Allow SSH (Port 22):
To prevent being locked out of your server, you should first allow SSH connections:
sudo ufw allow 22/tcpAllow HTTP (Port 80) and HTTPS (Port 443):
To allow web traffic, HTTP and HTTPS services need to be accessible:
sudo ufw allow 80/tcpsudo ufw allow 443/tcpDeny Access:
If you wish to deny traffic on a specific port, use:
sudo ufw deny 8080This command blocks all access to port 8080.
Examples
Here are practical step-by-step scenarios for deploying UFW rules.
Scenario 1: Allow Access from Specific IP
If you need to allow access from a specific IP address to all services, you can specify the source:
sudo ufw allow from 192.168.1.5This allows all traffic from IP address 192.168.1.5.
Scenario 2: Allow Access to a Specific Port from Specific IP
To restrict access to a service (e.g., SSH) so that it’s only available from a specific IP:
sudo ufw allow from 192.168.1.5 to any port 22This rule allows SSH connections only from 192.168.1.5.
Scenario 3: Allow Port Range
You might need to open a range of ports for certain applications:
sudo ufw allow 6000:6007/tcpThis command will allow TCP traffic for ports ranging from 6000 to 6007.
Conclusion
Getting started with UFW doesn’t have to be complicated. With the basic commands and rules outlined in this article, you can securely configure your firewall. Remember, managing a server’s firewall matters for maintaining server security and should be treated diligently. Always double-check the rules you’ve set up to ensure that they correctly reflect the access controls you intend to enforce.
Gotchas That Will Bite You at 2 AM
The rules work. You checked them. You’re confident. Then you reboot the server and suddenly nothing connects. Here are the things that catch people off guard.
Default policies matter more than your rules
UFW defaults to DENY on incoming and ALLOW on outgoing, but a changed or reset config can leave different values. Set them explicitly so you know what you have:
sudo ufw default deny incomingsudo ufw default allow outgoingRun sudo ufw status verbose and look for the Default: line at the top. If it says allow (incoming), your firewall is basically decorative.
UFW doesn’t save rules the way you think
When you add a rule, it persists across reboots, that part’s fine. What bites people is rule ordering. UFW evaluates rules top-to-bottom and stops at the first match. If you’ve got a broad allow from 192.168.1.0/24 rule sitting above a deny from 192.168.1.50, the deny never fires. Check rule numbers with:
sudo ufw status numberedDelete by number when you need to reorder:
sudo ufw delete 3Docker pokes holes in your firewall without asking
Docker manipulates iptables directly and bypasses UFW for published ports. Docker routes container traffic in the nat table, so packets are diverted before they reach the INPUT chain that UFW uses (Docker docs). A deny 8080 rule does nothing for a container started with -p 8080:80, because Docker already opened the port before UFW got involved.
To keep a published port private, bind it to loopback (-p 127.0.0.1:8080:80) and put a reverse proxy in front, or filter in Docker’s DOCKER-USER chain. Setting "iptables": false in /etc/docker/daemon.json is a trap: Docker’s docs warn it is likely to break container networking. Also check the Rootless Docker post, since running Docker rootless sidesteps this.
Default logging is minimal
UFW logs at the low level by default, which misses most of what a portscan looks like. Raise it:
sudo ufw logging mediumLogs land in /var/log/ufw.log. low logs blocked packets that hit the default policy, medium adds invalid packets and all new connections (allowed ones included). Don’t set high or full on a public-facing server unless you enjoy watching your disk fill up.
The app profile shortcut is cleaner than raw ports
Instead of remembering port numbers, UFW ships with named profiles for common services. See what’s available:
sudo ufw app listsudo ufw allow 'Nginx Full'sudo ufw allow 'OpenSSH'Nginx Full opens both 80 and 443 in one command. Less typing, fewer mistakes. If you’re adding custom services, drop a profile file into /etc/ufw/applications.d/, it’s just an INI file with [ServiceName], title, description, and ports.
The double-check habit mentioned above is good advice. sudo ufw status verbose after every change, before you close that terminal session. Future you is counting on it.