UFW Firewall Cheat Sheet: Simple Firewall for Ubuntu and Debian

4 min read
Beginner UFW Firewall Ubuntu Security Cheat Sheet

Prerequisites

  • Ubuntu or Debian server
  • Root or sudo access

Quick Answer: ufw enable turns on the firewall. ufw allow 22 allows SSH. ufw allow 80,443/tcp allows web traffic. ufw deny 3306 blocks MySQL. ufw status shows active rules. ufw delete allow 80 removes a rule.

Need a VPS? Vultr (free credit), DigitalOcean ($200 free credit), or RackNerd (cheap annual deals).

Enable and Status

# Install (usually pre-installed on Ubuntu)
apt install ufw -y

# Enable firewall
ufw enable

# Disable firewall
ufw disable

# Check status
ufw status
ufw status verbose           # With default policies
ufw status numbered          # With rule numbers (for deleting)

# Reset all rules (careful!)
ufw reset

Allow Rules

# Allow a port (TCP + UDP)
ufw allow 22

# Allow specific protocol
ufw allow 80/tcp
ufw allow 53/udp

# Allow multiple ports
ufw allow 80,443/tcp

# Allow port range
ufw allow 8000:8100/tcp

# Allow from specific IP
ufw allow from 10.0.0.5

# Allow from specific IP to specific port
ufw allow from 10.0.0.5 to any port 3306

# Allow from subnet
ufw allow from 192.168.1.0/24

# Allow from subnet to specific port
ufw allow from 192.168.1.0/24 to any port 22

# Allow to specific interface
ufw allow in on eth0 to any port 80

Deny and Block

# Deny a port
ufw deny 23                     # Telnet
ufw deny 3306                   # MySQL from outside

# Deny from specific IP
ufw deny from 1.2.3.4

# Deny from subnet
ufw deny from 10.0.0.0/8

# Reject (sends error back, unlike deny which silently drops)
ufw reject 23

Delete Rules

# Delete by rule
ufw delete allow 80

# Delete by rule number
ufw status numbered            # See numbers first
ufw delete 3                   # Delete rule #3

# Delete deny rule
ufw delete deny from 1.2.3.4

Default Policies

# Deny all incoming (recommended)
ufw default deny incoming

# Allow all outgoing
ufw default allow outgoing

# Deny forwarding
ufw default deny routed

# View current defaults
ufw status verbose

Common Server Setup

Web Server

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp        # SSH
ufw allow 80/tcp        # HTTP
ufw allow 443/tcp       # HTTPS
ufw enable

Database Server

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow from 10.0.0.0/24 to any port 3306    # MySQL from local network only
ufw allow from 10.0.0.0/24 to any port 5432    # PostgreSQL from local network only
ufw enable

VPN Server (WireGuard)

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 51820/udp     # WireGuard
ufw enable

Proxy Server (3X-UI)

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 443/tcp             # VLESS-WS
ufw allow 8443/tcp            # Reality
ufw allow 2053/tcp            # Panel
ufw allow 2082,2083/tcp       # CDN ports
ufw allow 8880/tcp            # CDN HTTP
ufw enable

Application Profiles

# List available profiles
ufw app list

# View profile details
ufw app info "Nginx Full"

# Allow by profile
ufw allow "Nginx Full"        # 80 + 443
ufw allow "Nginx HTTP"        # 80 only
ufw allow "Nginx HTTPS"       # 443 only
ufw allow "OpenSSH"           # 22

# Common profiles
# Nginx Full    = 80,443/tcp
# Nginx HTTP    = 80/tcp
# Nginx HTTPS   = 443/tcp
# OpenSSH       = 22/tcp
# Apache Full   = 80,443/tcp

Create Custom Profile

Create /etc/ufw/applications.d/myapp:

[MyApp]
title=My Application
description=Custom web application
ports=3000/tcp|8080/tcp

Then: ufw allow "MyApp"

Logging

# Enable logging
ufw logging on

# Logging levels
ufw logging low              # Only blocked
ufw logging medium           # Blocked + allowed (if policy matched)
ufw logging high             # All packets
ufw logging full             # Everything

# View firewall logs
grep "UFW" /var/log/syslog | tail -20
journalctl | grep "UFW" | tail -20

# Disable logging
ufw logging off

Rate Limiting

# Rate limit SSH (6 connections per 30 seconds per IP)
ufw limit 22/tcp

# This blocks IPs that attempt more than 6 connections in 30 seconds
# Much simpler than iptables rate limiting

Forwarding (NAT)

To use UFW for routing/NAT (e.g., VPN server):

Edit /etc/ufw/sysctl.conf:

net/ipv4/ip_forward=1

Edit /etc/ufw/before.rules — add before the *filter line:

*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.66.66.0/24 -o eth0 -j MASQUERADE
COMMIT

Edit /etc/default/ufw:

DEFAULT_FORWARD_POLICY="ACCEPT"

Then: ufw reload

Insert Rules (Order Matters)

# Insert at specific position (rules are processed top to bottom)
ufw insert 1 allow from 10.0.0.5    # Make this the first rule

# Example: allow one IP but block its subnet
ufw insert 1 allow from 10.0.0.5
ufw insert 2 deny from 10.0.0.0/24

UFW vs iptables

UFW iptables
Difficulty Easy Hard
Best for Quick server setup Complex rules, NAT, advanced filtering
Rate limiting Basic (limit command) Advanced (per-second, per-minute)
Logging Simple on/off Granular per-rule
NAT Possible but manual Native support
Under the hood Generates iptables rules Direct kernel firewall

UFW is a frontend for iptables. When you run ufw allow 22, it creates the equivalent iptables rule. For 90% of servers, UFW is all you need.

Quick Troubleshooting

# Can't SSH after enabling UFW?
# Boot into recovery mode or use console access, then:
ufw allow 22
ufw enable

# Check if UFW is actually active
ufw status

# See generated iptables rules
iptables -L -n

# Port open in UFW but still can't connect?
# Check if service is actually listening:
ss -tlnp | grep :80

# Check if another firewall (cloud provider) is blocking:
# AWS: Security Groups
# GCP: VPC Firewall Rules
# Azure: NSG

See Also