Skip to main content

UFW

UFW (Uncomplicated Firewall) is a user-friendly firewall management tool for Linux, most commonly used on Ubuntu and Debian-based systems. It provides a simplified command-line interface for managing packet filtering rules that are ultimately enforced by the Linux kernel through Netfilter (via iptables, and on some systems nftables).

UFW became popular because it made host-based firewalling approachable for system administrators who did not want to manage complex iptables rule syntax directly. It has been included and supported as a standard firewall tool in Ubuntu for many years, is widely documented in the Ubuntu ecosystem, and is commonly used as a baseline security control for VPS and cloud servers.

Background and history

UFW was introduced in the Ubuntu ecosystem as a simpler firewall interface compared to raw iptables. Over time it became the default “first firewall” choice for many Ubuntu server deployments because it balances simplicity with enough control for most host firewall needs.

When UFW Is a Good Fit

UFW is strongest when you need a reliable, maintainable host firewall policy with minimal complexity.

Common best-fit scenarios:

  • VPS or cloud servers that need a baseline inbound policy (deny-by-default, allow only required services)
  • Web servers (WordPress, OpenLiteSpeed, Nginx, Apache) that only require a small set of ports
  • SSH hardening (custom ports, rate limiting, allow-listing trusted IPs)
  • Simple outbound restrictions (blocking SMTP to prevent abuse, limiting egress to required services)
  • Environments where operational simplicity and clarity are important (small teams, consistent automation)
Practical guideline

Use UFW as your default host firewall on Ubuntu servers unless you have a clear requirement that demands a more advanced firewall framework.

When UFW Is Not Suitable

UFW is not designed to be a full network security platform. Avoid or reconsider UFW as the primary solution when you need:

  • High-complexity firewalling with many dynamic rules or frequent rule changes at scale
  • Advanced NAT/routing/firewall features that you want to manage entirely via higher-level policy frameworks
  • Large enterprise environments that already standardize on a different firewall stack (direct nftables, firewalld, vendor tooling, configuration management policies)
  • Deep Layer 7 filtering, WAF logic, bot management, or application-aware security (use a WAF, reverse proxy, or CDN security layer)
  • Centralized fleet policy enforcement where a single source of truth must generate firewall policies across many host OS variants (often better served by orchestration + native firewall tooling)
Important limitation

UFW controls network access at the host firewall level (Layer 3/4). It does not replace a WAF, IDS/IPS, or application security controls.

Typical Alternatives

Choose based on environment and requirements:

Tool / ApproachBest For
ufwSimple and reliable host firewall on Ubuntu/Debian; common VPS baseline
nftables (direct)Advanced/modern Linux firewall rules with full control and performance
firewalldZone-based firewall management (common in RHEL/Fedora ecosystems)
Cloud security groupsFirst perimeter layer in cloud; should complement host firewall
CDN/WAF (Cloudflare, etc.)Layer 7 protection, DDoS mitigation, bot filtering

Prerequisites

  • Ubuntu or Debian-based Linux server (VPS or bare metal)
  • sudo privileges
  • Basic understanding of ports, IP addresses, TCP/UDP

Architecture Overview

UFW is a higher-level interface that converts human-readable rules into kernel firewall rules.

Core Syntax

ufw [global-options] <command> [parameters]
ComponentMeaning
---
global-optionsFlags that affect command behavior (example: --force)
commandAction or control command (example: allow, deny, status)
parametersRule details (example: port, protocol, IP, interface)

Global Options

OptionPurpose
--
--helpShow help and available commands
--versionShow installed UFW version
--forceSkip interactive confirmations (useful for automation)
--verboseMore detailed output (commonly used with status)

Command Groups

System Control

CommandPurpose
--
enableActivate UFW and load rules
disableDeactivate UFW
reloadRe-apply rules without disabling
resetReset rules to defaults
statusShow firewall status and rules

Default Policy

Default policies apply when no rule matches.

sudo ufw default deny incoming
sudo ufw default allow outgoing
Default PolicyMeaning
--
deny incomingBlock inbound traffic unless explicitly allowed
allow outgoingAllow outbound traffic by default (common server baseline)

Rule Evaluation Order

UFW evaluates rules in order. First match wins.

To inspect ordering:

sudo ufw status numbered

Rule Building Blocks

ComponentMeaningExample
----
Actionallow, deny, reject, limitallow
Directionin / outallow in ...
Sourcesource IP/subnetfrom 203.0.113.10
Destinationdestination IPto any
Porttarget port(s)port 22 or 80,443
Protocoltcp/udpproto tcp
Interfacerestrict to NICon eth0
Commentdocumentationcomment "..."

Examples:

sudo ufw allow 80/tcp comment "HTTP"
sudo ufw allow from 203.0.113.10 to any port 22 proto tcp comment "SSH from office"
sudo ufw deny out 25/tcp comment "Block outbound SMTP"

Logging

Enable logging:

sudo ufw logging on

Set logging level:

sudo ufw logging low
sudo ufw logging medium
sudo ufw logging high
sudo ufw logging full
LevelTypical Use
--
lowMinimal logs (commonly blocked events)
mediumBalanced auditing
high / fullDebugging and deep analysis

View logs:

sudo tail -f /var/log/ufw.log

Practical Use Cases

Safe Initialization (Avoid SSH Lockout)

sudo ufw allow 22/tcp comment "SSH"
sudo ufw allow 80,443/tcp comment "Web"
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw --force enable
sudo ufw status verbose

Limit SSH Brute Force Attempts

sudo ufw limit 22/tcp comment "Rate-limit SSH"

Restrict MySQL to Localhost Only

sudo ufw deny 3306/tcp comment "Block MySQL external"
sudo ufw allow from 127.0.0.1 to any port 3306 proto tcp comment "MySQL localhost"

Use Case: Change Default SSH Port

This example changes SSH from port 22 to 2222 and updates UFW rules safely.

Step 1: Allow the New SSH Port in UFW

sudo ufw allow 2222/tcp comment "SSH new port"

Verify rules:

sudo ufw status verbose

Step 2: Update SSH Daemon Configuration

Edit the SSH configuration file:

sudo nano /etc/ssh/sshd_config

Set the SSH port:

Port 2222

Restart SSH:

sudo systemctl restart ssh

Step 3: Test SSH Access on the New Port

From your local machine (open a new terminal session):

ssh -p 2222 username@your_server_ip

Step 4: Close Port 22 After Successful Test

sudo ufw delete allow 22/tcp

Verify final rules:

sudo ufw status numbered

Optional Hardening: Allow SSH Only From a Trusted IP

sudo ufw allow from 203.0.113.10 to any port 2222 proto tcp comment "SSH trusted IP"
sudo ufw deny 2222/tcp comment "SSH blocked except trusted IP"

OpenLiteSpeed and WordPress Baseline Template

Common ports:

PortPurpose
:-
80HTTP
443HTTPS
7080OpenLiteSpeed admin panel

Template:

sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 2222/tcp comment "SSH"
sudo ufw limit 2222/tcp comment "Rate-limit SSH"

sudo ufw allow 80/tcp comment "HTTP"
sudo ufw allow 443/tcp comment "HTTPS"

sudo ufw allow from <your-ip> to any port 7080 proto tcp comment "OLS admin restricted"

sudo ufw --force enable
sudo ufw status verbose

Cloudflare-Only Access Pattern

Block direct access, then allow only Cloudflare IP ranges (example subset):

sudo ufw deny 80/tcp
sudo ufw deny 443/tcp

sudo ufw allow from 173.245.48.0/20 to any port 80,443 proto tcp comment "Cloudflare"
sudo ufw allow from 103.21.244.0/22 to any port 80,443 proto tcp comment "Cloudflare"

Troubleshooting

SymptomLikely CauseFix
-----
SSH fails after enabling UFWSSH rule missingAdd ufw allow <ssh-port>/tcp then retry
Web not reachablePorts not allowedAllow 80/tcp and 443/tcp
Rules not taking effectReload neededsudo ufw reload
Wrong rule precedenceOrder mismatchUse ufw status numbered + ufw insert

Emergency Recovery

If you have console access (cloud provider console/serial), you can recover quickly:

sudo ufw disable
sudo ufw reset
sudo ufw allow 22/tcp comment "SSH recovery"
sudo ufw --force enable

Quick Command Reference

GoalCommand
-
Enablesudo ufw enable
Disablesudo ufw disable
Reloadsudo ufw reload
Resetsudo ufw reset
Statussudo ufw status verbose
Numbered rulessudo ufw status numbered
Allowsudo ufw allow 443/tcp
Denysudo ufw deny 3306/tcp
Limitsudo ufw limit 2222/tcp
Delete by rulesudo ufw delete allow 80/tcp
Delete by numbersudo ufw delete <num>

Configuration Files

PathPurpose
----
/etc/ufw/ufw.confUFW enablement at boot (ENABLED=yes/no)
/etc/default/ufwDefaults (including IPv6 setting)
/etc/ufw/before.rulesRules applied before user rules
/etc/ufw/after.rulesRules applied after user rules
/etc/ufw/applications.d/Application profiles
/var/log/ufw.logUFW log output (if logging enabled)