How To

ufw Command in Linux: Manage Firewall Rules with Examples

ufw (Uncomplicated Firewall) sits on top of iptables (or nftables on newer systems) and replaces complex packet-filter rules with readable commands. It is the standard firewall tool on Ubuntu and Debian. The kernel still enforces the actual rules, ufw is a frontend that generates them for you.

Almost every ufw invocation requires sudo because it changes firewall rules.

How to Use the ufw Command in Linux”

Check the current status before making any changes:

bash<br>sudo ufw status # inactive or active + rule list<br>sudo ufw status numbered # same list with rule numbers for easy deletion<br>sudo ufw status verbose # adds default policies and logging level<br>

Enable ufw safely over SSH. The first time you turn the firewall on, allow SSH first — enabling it over an SSH connection without an SSH rule will lock you out immediately:

bash<br>sudo ufw allow ssh # FIRST: allow SSH<br>sudo ufw enable # THEN: start enforcing + register for boot startup<br>

Once enabled, ufw enforces rules immediately and starts automatically on every reboot. disable stops enforcement but keeps your rules. When you re-enable it, the same rules come back. reset is different: it removes every rule, including the SSH rule.

Set the default policies for traffic that does not match any rule. The standard hardening is:

bash<br>sudo ufw default deny incoming<br>sudo ufw default allow outgoing<br>

After these two commands, all inbound traffic is blocked by default. You only need to explicitly open the ports your server needs to expose. If the host acts as a router or runs containers, also add:

bash<br>sudo ufw default deny routed<br>Allow Connections by Port, Service, and Address<br>Allow by service name — ufw reads /etc/services. Each command opens the matching port for both TCP and UDP where applicable:
bash<br>sudo ufw allow ssh # port 22<br>sudo ufw allow http # port 80<br>sudo ufw allow https # port 443<br>

Allow by port number without a protocol suffix, both TCP and UDP are opened:

bash<br>sudo ufw allow 8080 # TCP + UDP<br>sudo ufw allow 8080/tcp # TCP only<br>sudo ufw allow 53/udp # UDP only

Port ranges require an explicit protocol. The colon separates the start and end, and both endpoints are inclusive:

bash<br>sudo ufw allow 6000:6007/tcp

Allow from a specific address or subnet:

bash<br>sudo ufw allow from 203.0.113.25 # any port<br>sudo ufw allow from 203.0.113.25 to any port 22 # specific port only<br>sudo ufw allow from 192.168.1.0/24 to any port 3306 # subnet to DB port<br>

The subnet pattern keeps the database port closed to the internet and reachable only from your internal network.

Allow on a specific interface:

bash<br>sudo ufw allow in on eth1 to any port 3306 # inbound on eth1 only<br>

Deny, Reject, and Rate-Limit Connections
deny takes the same arguments as allow and silently drops matching packets with no reply. When the default incoming policy is already deny, explicit deny rules are most useful for blocking a specific address while a port stays open to everyone else:

bash<br>sudo ufw deny from 198.51.100.77<br>

reject sends an ICMP “connection refused” message back to the sender:

bash<br>sudo ufw reject 23<br>

deny vs reject: deny = silent drop; reject = ICMP response. Reject is slightly friendlier to well-behaved clients but makes the server more visible to port scanners.

Rate-limit SSH against brute-force attacks:

bash<br>sudo ufw limit ssh<br>

This blocks a source IP that makes six or more connection attempts in 30 seconds — a quick defense without installing a full intrusion-prevention tool.

Delete Rules, App Profiles, and Dry Run
Delete a rule by rule text or by number:

bash<br>sudo ufw delete allow 8080/tcp # by repeating the rule with delete<br>sudo ufw status numbered # find the rule number first<br>sudo ufw delete 3 # then delete by number<br>

After a deletion, the numbering shifts for all remaining rules. Always run status numbered again before deleting the next rule.

Application profiles let services register their own port definitions:

bash<br>sudo ufw app list # list available profiles<br>sudo ufw allow 'Nginx Full' # open all ports the profile covers<br>sudo ufw app info 'Nginx Full' # see which ports the profile includes<br>

Quote profile names that contain spaces.

Preview changes without applying them:

bash<br>sudo ufw --dry-run allow 8080/tcp<br>

–dry-run shows the exact iptables lines ufw would write, without creating any rule. Useful when writing rules over SSH and you want to double-check the effect first.

Logging, Reset, and IPv6
Enable and tune logging:

bash

sudo ufw logging on
sudo ufw logging medium # levels: off, low, medium, high, full
On Ubuntu, entries appear in /var/log/ufw.log and are also accessible through journalctl.

Reset clears every rule and disables the firewall:

bash<br>sudo ufw reset
⚠️ <strong>Warning:</strong> reset removes every rule including SSH. On a remote server, re-add sudo ufw allow ssh and re-enable the firewall immediately after resetting, or you will lose access when you reconnect.

IPv6: check /etc/default/ufw for IPV6=yes. When set, generic rules like sudo ufw allow 22/tcp apply to both IPv4 and IPv6. Rules with explicit addresses stay specific to their address family. IPv6 rules appear with (v6) in the status output.

<strong>Note:</strong> if you run Docker, it writes its own iptables rules that can bypass ufw. Firewall rules alone may not be enough to block Docker-published ports.

Start with default deny incoming and allow outgoing, open only the ports you need, use status numbered for clean rule management, and always check with –dry-run before applying rules over SSH. Leave a comment below if you run into any issues.

Cyber Defence

Recent Posts

Nginx Commands in Linux: Start, Stop, Reload, Test, and Log

Nginx is a high-performance web server and reverse proxy trusted by some of the largest…

1 hour ago

who Command in Linux: Show All Logged-In Users and Sessions

When you share a server with a team or investigate unexpected activity, the first question…

1 hour ago

file Command in Linux: Identify File Types Without Extensions

The file command inspects the actual contents of a file and reports its type — regardless of…

1 day ago

chattr Command in Linux: Set File Attributes with lsattr

chattr sets and removes special file attributes that operate at the filesystem level, separate from standard…

1 day ago

env Command in Linux: Show and Set Environment Variables

env prints the current environment, sets or removes variables for a single command, and can start…

1 day ago

nmap Command in Linux: Port Scanning and Host Discovery Guide

nmap (Network Mapper) discovers live hosts, identifies open ports, and detects which service is running…

1 day ago