How to Configure UFW (Uncomplicated Firewall) and Rate Limiting on Ubuntu Server 24.04 LTS

Hardening Linux infrastructure against automated port scanning, unauthorized ingress traffic, and brute-force intrusion attempts begins at the network packet boundary. In Ubuntu Server 24.04 LTS, the Linux kernel manages packet filtering and network address translation through the nftables subsystem. While interacting directly with raw packet-filtering rules can be complex and error-prone, Ubuntu supplies Uncomplicated Firewall (ufw) as the standard, robust management frontend. Mastering ufw allows system administrators and DevOps engineers to enforce default-deny policies, authorize specific service ports, establish CIDR subnet boundaries, and deploy automated rate limiting to protect critical SSH endpoints.

Understanding UFW Architecture and Packet Flow

The ufw framework acts as an abstraction layer above kernel packet filtering, simplifying stateful inspection without sacrificing security. The table below delineates the operational characteristics of UFW rule evaluation:

Architectural Component Configuration File / Path Operational Role
Core UFW Binary /usr/sbin/ufw Command-line management interface for applying runtime modifications.
Default Policies /etc/default/ufw Defines system-wide ingress/egress baselines and IPv6 support flags.
User-Defined Rules /etc/ufw/user.rules / user6.rules Houses custom administrative ports, IP whitelists, and rate limits.
Application Profiles /etc/ufw/applications.d/ Vendor-supplied XML/text descriptors mapping services (e.g., Nginx, OpenSSH) to ports.
Kernel Backend nftables / netfilter Executes wire-speed packet inspection, connection tracking, and drops directly in kernel memory.

Safely Initialising UFW Without Locking Out SSH

The single greatest operational hazard in remote server administration is enabling the firewall before explicitly permitting SSH ingress, resulting in an immediate lockout. Follow this strict deployment order.

Step 1: Verify Active Status and Default Policies

Check the current operational state:

sudo ufw status verbose

By default, UFW is Status: inactive.

Step 2: Enforce Default Directional Policies

Security best practices dictate a strict default-deny ingress policy paired with an open egress policy:

# Block all unauthorized incoming traffic
sudo ufw default deny incoming

# Permit outbound server connections (DNS, package updates, APIs)
sudo ufw default allow outgoing

Step 3: Authorise Inbound SSH Prior to Activation

If running SSH on the standard port 22, add the rule explicitly:

sudo ufw allow 22/tcp comment 'Permit Standard SSH'

If your server utilizes a hardened, non-standard SSH port (for example, port 2222):

sudo ufw allow 2222/tcp comment 'Permit Hardened SSH'

Step 4: Enable the Firewall Service

Once SSH is authorized, activate UFW:

sudo ufw enable

When prompted with “Command may disrupt existing ssh connections. Proceed with operation (y|n)?”, type y and press Enter. The firewall will engage and persist across server reboots.

Configuring Port Rules and CIDR Subnet Whitelisting

Web servers, API gateways, and database clusters require explicit ingress rules to process authorized client requests.

1. Authorising Standard Web Services

To permit HTTP (port 80) and HTTPS (port 443) traffic, leverage named protocols or port numbers:

# Using explicit ports
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Alternatively, using Nginx application profiles
sudo ufw allow 'Nginx Full'

2. Restricting Ingress to Specific Corporate Subnets

Exposing database engines (such as PostgreSQL on port 5432 or MySQL on port 3306) to the public internet is a critical vulnerability. Restrict access strictly to authorized internal CIDR IP blocks:

sudo ufw allow from 10.8.0.0/24 to any port 5432 proto tcp comment 'PostgreSQL VPN Subnet Only'

To whitelist a single trusted static IP address for administrative access:

sudo ufw allow from 203.0.113.45 to any port 22 proto tcp comment 'Bastion Admin IP'

Deploying Ingress Rate Limiting Against Brute-Force Attacks

While standard allow rules permit unlimited connection attempts, threat actors frequently deploy distributed dictionary tools against SSH ports. UFW provides native rate limiting:

sudo ufw limit ssh

Operational behaviour of ufw limit:

  • Permits standard inbound TCP connections normally.
  • If an IP address initiates six or more connection handshakes within a 30-second window, UFW automatically drops subsequent packets from that IP address.
  • Provides effective mitigation against automated credential stuffing without requiring complex fail2ban dependencies.

Managing, Numbering, and Deleting Rules

As firewall rules evolve, auditing their sequential execution order and purging deprecated rules ensures configuration clarity.

1. Inspecting Rules with Sequential Numbering

UFW evaluates rules sequentially from top to bottom; the first rule that matches an incoming packet terminates evaluation. View numbered rules using:

sudo ufw status numbered

2. Deleting Obsolete Rules

To remove a rule by its precise index number:

sudo ufw delete 4

Confirm the deletion prompt. UFW re-indexes remaining rules automatically.

Enabling Logging for Forensic Audits

To track dropped probes and analyze security telemetry in /var/log/ufw.log:

# Enable standard logging
sudo ufw logging on

# Enable detailed logging (records all dropped and authorized packets)
sudo ufw logging medium

To inspect real-time firewall drops as they occur:

sudo tail -f /var/log/ufw.log | grep "\[UFW BLOCK\]"

Troubleshooting UFW Network and Service Disruptions

When services fail to bind or legitimate traffic is dropped, apply the following triage methodology:

  • Docker Bypassing UFW Rules Completely: By default, Docker manipulates iptables/nftables directly, exposing published container ports (e.g., docker run -p 8080:8080) even if UFW has not authorized that port. To resolve this, configure Docker daemon with "iptables": false in /etc/docker/daemon.json, or employ community hardening scripts like ufw-docker.
  • IPv6 Traffic Leaking or Blocked: If dual-stack servers experience IPv6 drops, verify that IPV6=yes is declared inside /etc/default/ufw. If disabled, UFW manages IPv4 exclusively, leaving IPv6 exposed or unrouted.
  • Resetting All Rules in Emergency Scenarios: If a misconfigured rule causes erratic behavior, purge all custom policies and restore factory defaults using:
    sudo ufw reset

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.