Linux Firewall Guide: ufw and iptables for Beginners

A Linux firewall controls which network traffic is allowed in and out of your server. Without one, every open port is exposed to the internet. This guide covers two approaches: ufw (Uncomplicated Firewall — the easier choice for most use cases) and iptables (the underlying engine — essential for advanced scenarios).

ufw — Uncomplicated Firewall (Ubuntu/Debian)

ufw wraps iptables with a simpler command interface. It is included by default on Ubuntu and is the right choice for standard server setups.

Enabling and Checking Status

sudo ufw status                      # Show status and rules
sudo ufw status verbose              # Detailed view
sudo ufw enable                      # Enable firewall
sudo ufw disable                     # Disable firewall (not recommended on production)

Warning: enable ufw only after you have allowed SSH, or you will lock yourself out.

Basic Rules

# Allow SSH before enabling (critical!)
sudo ufw allow ssh                   # Allow port 22
sudo ufw allow 2222/tcp              # Allow custom SSH port

# Allow common services
sudo ufw allow http                  # Allow port 80
sudo ufw allow https                 # Allow port 443
sudo ufw allow 3306/tcp              # MySQL (be careful — prefer restricting)

# Allow from specific IP only
sudo ufw allow from 192.168.1.100 to any port 22
sudo ufw allow from 192.168.1.0/24 to any port 3306

# Deny a port
sudo ufw deny 23/tcp                 # Deny Telnet

Deleting Rules

sudo ufw status numbered             # Show rules with numbers
sudo ufw delete 3                    # Delete rule #3
sudo ufw delete allow http           # Delete by rule definition

Default Policies

sudo ufw default deny incoming       # Block all incoming by default
sudo ufw default allow outgoing      # Allow all outgoing by default

Logging

sudo ufw logging on                  # Enable logging
sudo tail -f /var/log/ufw.log        # Watch firewall log

firewalld — For RHEL/Rocky/Fedora

sudo systemctl status firewalld
sudo firewall-cmd --state

# Allow services
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=8080/tcp

# Reload to apply permanent rules
sudo firewall-cmd --reload

# List all rules
sudo firewall-cmd --list-all

iptables — The Low-Level Engine

iptables is the actual Linux kernel firewall. ufw and firewalld are front-ends for it. Understanding iptables basics helps you debug issues and write precise rules.

Viewing Rules

sudo iptables -L -n -v              # List rules with stats
sudo iptables -L -n --line-numbers  # Show line numbers
sudo iptables -t nat -L -n          # NAT table rules

Basic Rule Structure

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT    # Allow SSH
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT    # Allow HTTP
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT  # Allow established
sudo iptables -A INPUT -i lo -j ACCEPT                 # Allow loopback
sudo iptables -P INPUT DROP                            # Default deny incoming

Deleting Rules

sudo iptables -D INPUT -p tcp --dport 23 -j ACCEPT    # Delete specific rule
sudo iptables -D INPUT 3                              # Delete by line number
sudo iptables -F                                      # Flush ALL rules (careful)

Saving iptables Rules

# Ubuntu/Debian
sudo apt install iptables-persistent
sudo netfilter-persistent save

# RHEL/Rocky
sudo service iptables save
cat /etc/sysconfig/iptables

A Minimal Secure iptables Ruleset

#!/bin/bash
# Flush existing rules
iptables -F
iptables -X

# Default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT

# Allow established/related connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Allow HTTP and HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Log and drop everything else
iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: "
iptables -A INPUT -j DROP

Summary

For most servers, ufw on Ubuntu/Debian and firewalld on RHEL/Rocky provide everything you need with a clean interface. Understanding iptables gives you the power to handle complex scenarios — NAT, port forwarding, traffic shaping. Always allow SSH before enabling any firewall, and test rules carefully before applying them to production.