By Akshay Singh
The Complete Guide to UFW: Securing Your Linux VPS Firewall
When you provision a new Virtual Private Server (VPS) from a cloud provider like DigitalOcean, AWS, or Hetzner, it is often deployed with all of its network ports wide open to the public internet. Within minutes of a server going online, automated bots and malicious actors will begin scanning it for vulnerabilities, open database ports, and brute-forcing SSH credentials.
Securing your network perimeter is not optional—it is the foundational step of server administration. The standard tool for this job on Ubuntu and Debian-based systems is UFW (Uncomplicated Firewall).
UFW is an incredibly user-friendly command-line frontend for iptables and nftables, the deeply complex, underlying packet filtering frameworks in the Linux kernel. It abstracts away the complex syntax of raw iptables rules into simple, human-readable commands.
In this exhaustive, end-to-end guide, we will cover everything from initial installation to advanced rate-limiting, ensuring your infrastructure is locked down correctly.
Prerequisites
Before interacting with firewall rules, ensure you have:
- A Linux server (this guide focuses on Ubuntu/Debian).
- A non-root user with
sudoprivileges.
Crucial Warning: Before you ever run the command to enable the firewall, you must ensure that SSH access is explicitly permitted. If you fail to do this, you will permanently lock yourself out of your own server the moment the firewall activates.
Step 1: Installation and Status Verification
Most modern Ubuntu distributions come with UFW pre-installed. However, it is disabled by default to prevent accidental lockouts during initial server setup.
If it is not installed, you can add it via the package manager:
sudo apt update
sudo apt install ufw -y
Check the current status of the firewall:
sudo ufw status
If it says Status: inactive, you are ready to proceed. Do not enable it yet.
Step 2: Establish Default Policies
The core philosophy of a secure firewall is "Default Deny." This means that unless you explicitly open a door, all traffic should hit a brick wall.
Conversely, outgoing traffic (your server downloading updates, connecting to external APIs, sending emails) is generally considered safe and should be allowed by default.
Set your foundational default policies with these two commands:
sudo ufw default deny incoming
sudo ufw default allow outgoing
These rules establish the baseline behavior, but they are not yet enforced because the firewall is currently inactive.
Step 3: The Golden Rule (Allowing SSH)
If you turn on the firewall right now, your active SSH session might survive, but the next time you try to log in, the default deny policy will reject your connection.
You must explicitly allow SSH traffic. UFW understands standard application names, so you can easily allow SSH using its protocol name:
sudo ufw allow ssh
Alternatively, if you have configured SSH to run on a custom, non-standard port (for example, port 2222), you must specify the port number directly:
sudo ufw allow 2222/tcp
Advanced: Rate Limiting SSH to Prevent Brute Force
Allowing SSH is necessary, but it leaves you open to brute-force dictionary attacks. UFW has a built-in mechanism called limit that automatically blocks an IP address if it attempts to initiate six or more connections within 30 seconds.
This is highly recommended for SSH:
sudo ufw limit ssh
Step 4: Enabling the Firewall
With your default policies set and SSH safely allowed, it is time to arm the system.
sudo ufw enable
You will receive a warning:
Command may disrupt existing ssh connections. Proceed with operation (y|n)?
Type y and press Enter.
Verify the status again, this time adding the verbose flag to see the underlying rules:
sudo ufw status verbose
You should see an output indicating the status is active, the default policies are in place, and your SSH port is explicitly permitted.
Step 5: Allowing Web Traffic (HTTP and HTTPS)
If your VPS is hosting a web application—like a Next.js frontend or a Node.js API—you need to allow HTTP (port 80) and HTTPS (port 443) traffic.
You can allow them individually by port number:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Using Application Profiles
When you install web servers like Nginx or Apache, they register "Application Profiles" with UFW, which bundle multiple ports together for convenience.
You can list all available application profiles with:
sudo ufw app list
If you see Nginx Full or Apache Full, you can allow both HTTP and HTTPS in a single command:
sudo ufw allow 'Nginx Full'
(Note: If the application name contains spaces, you must wrap it in quotes).
Step 6: Advanced Rule Configuration
Real-world server administration often requires highly specific access controls. Let's explore more advanced UFW capabilities.
1. Specifying the Protocol
Some services use UDP instead of TCP (e.g., DNS servers or VPNs). You can specify the protocol by appending /tcp or /udp to the port number.
sudo ufw allow 53/udp
2. Allowing Specific IP Addresses
If you have a backend database (like PostgreSQL on port 5432) that should only be accessible by a specific application server, never open the port to the entire internet. Instead, restrict access to a single IP address:
sudo ufw allow from 203.0.113.50
3. Allowing an IP to a Specific Port
To combine the previous concepts and achieve maximum precision—allowing a specific IP address to access a specific port:
sudo ufw allow from 203.0.113.50 to any port 5432
4. Allowing a Subnet
If you are managing an internal private network and want to allow all servers within a specific subnet (e.g., a VPC in AWS) to communicate freely, you can use CIDR notation:
sudo ufw allow from 10.0.0.0/24
5. Port Ranges
Certain applications, like passive FTP servers or WebRTC applications, require a vast range of ports to be open. You can specify a range using a colon, but you must specify the protocol when doing so:
sudo ufw allow 6000:6007/tcp
sudo ufw allow 6000:6007/udp
Step 7: Managing and Deleting Rules
As your server evolves, you will inevitably need to remove old rules. There are two primary ways to delete rules in UFW.
Method 1: By Rule Specification
If you know exactly what rule you created, you can simply prefix the original command with delete:
sudo ufw delete allow 80/tcp
Method 2: By Numbered List (The Easy Way)
For complex rules, deleting by specification is prone to typos. Instead, list all your active rules with line numbers:
sudo ufw status numbered
The output will look like this:
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
If you want to remove rule number 2 (port 80):
sudo ufw delete 2
UFW will prompt you for confirmation. Type y to execute the deletion.
(Important: If you plan to delete multiple numbered rules, be aware that deleting a rule shifts the numbers of all subsequent rules down by one. Always delete starting from the highest number and working your way down, or re-run ufw status numbered after every deletion).
Step 8: Logging and Diagnostics
When troubleshooting network issues, firewall logs are invaluable. They can tell you exactly why a connection was dropped.
Enable UFW logging:
sudo ufw logging on
By default, this operates at a 'low' level, logging dropped packets not matching the default policy. The logs are written directly to your system's kernel log files, which you can view here:
sudo tail -f /var/log/ufw.log
(On some systems, it may write to /var/log/kern.log or /var/log/syslog instead).
If you need more verbose data during a critical debugging session, you can increase the logging level:
sudo ufw logging medium
Levels range from low, medium, high, to full. Be cautious with high or full in production, as they can rapidly consume disk space with massive log files.
Step 9: Resetting UFW (The Nuclear Option)
If your firewall configuration becomes hopelessly tangled, or you accidentally blocked yourself out of a crucial service and want a fresh start, you can reset UFW completely.
This disables UFW, deletes all active rules, and reverts all policies back to their defaults.
sudo ufw reset
Once executed, your server will rely entirely on its default network configuration until you build a new set of UFW rules and re-enable it.
Conclusion
A misconfigured firewall is one of the leading causes of server breaches. By utilizing UFW, you eliminate the complexity of raw packet routing and gain a simple, readable interface for securing your infrastructure.
Remember the golden rules of network security:
- Deny everything by default.
- Only open the specific ports your applications absolutely require.
- If a service doesn't need to be public, restrict it to a trusted IP address or subnet.
- Never forget to allow SSH before enabling the firewall.
With these practices in place, your Linux server is prepared to handle the hostility of the public internet.
