Class 52 of 55 • Advanced Linux Administration

Linux Security & Firewall Tutorial: UFW, Firewalld, iptables & Fail2ban

Any server connected to the public Internet is subjected to thousands of automated port scans, brute-force dictionary attacks, and unauthorized intrusion attempts daily. The Linux kernel contains an extremely fast packet inspection framework named Netfilter that inspects incoming, outgoing, and routed network packets at wire speed.

To control Netfilter without writing obscure kernel code, Linux provides firewall management tools: UFW (Uncomplicated Firewall) for Debian and Ubuntu, Firewalld for Red Hat and Fedora, and low-level iptables / nftables. When combined with intrusion prevention tools like Fail2ban, your Linux server becomes an impenetrable fortress.


1. Mastering UFW (Uncomplicated Firewall) - Ubuntu & Debian

UFW simplifies packet filtering into intuitive commands. Always establish a Default Deny posture:


# STEP 1: Set secure defaults (Block all incoming, allow all outgoing)
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing

# STEP 2: CRITICAL! Allow SSH FIRST before enabling firewall (Prevents lockout!)
$ sudo ufw allow 22/tcp
# Or allow custom SSH port: sudo ufw allow 2222/tcp

# STEP 3: Enable firewall daemon
$ sudo ufw enable
Firewall is active and enabled on system startup

# STEP 4: Allow standard web server traffic
$ sudo ufw allow 80/tcp   # HTTP
$ sudo ufw allow 443/tcp  # HTTPS
# Or by service profile: sudo ufw allow "Nginx Full"

# STEP 5: Allow access from a specific trusted IP subnet only (e.g. office VPN)
$ sudo ufw allow from 198.51.100.25 to any port 3306 proto tcp  # MySQL access

# STEP 6: Apply rate limiting to thwart SSH brute force (limits to 6 attempts per 30 sec)
$ sudo ufw limit 22/tcp

# STEP 7: View active rules with line numbers (for easy deletion)
$ sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere                  
[ 2] 80/tcp                     ALLOW IN    Anywhere                  
[ 3] 443/tcp                    ALLOW IN    Anywhere                  

# STEP 8: Delete rule by number
$ sudo ufw delete 2
							

2. Mastering Firewalld - Red Hat, Fedora & CentOS

RHEL and Fedora distributions utilize Firewalld, which organizes network interfaces into security Zones (e.g., public, internal, dmz, trusted):


# Check active zones and assigned interfaces
$ sudo firewall-cmd --get-active-zones
public
  interfaces: eth0

# Allow HTTP and HTTPS permanently
$ sudo firewall-cmd --permanent --zone=public --add-service=http
$ sudo firewall-cmd --permanent --zone=public --add-service=https

# Open a specific port permanently
$ sudo firewall-cmd --permanent --zone=public --add-port=8080/tcp

# Reload firewall rules to apply changes without dropping active sessions
$ sudo firewall-cmd --reload

# List all open ports, services, and active rules
$ sudo firewall-cmd --zone=public --list-all
							

3. iptables Architecture: Chains & Tables

Underneath UFW and Firewalld lies the classic iptables packet filter. Network packets traverse three core built-in chains:

     1. INPUT Chain: Packets destined for local processes on this machine.

     2. OUTPUT Chain: Packets generated locally and leaving the machine.

     3. FORWARD Chain: Packets routed through this machine to another network destination.


# View all raw iptables rules with packet byte counters
$ sudo iptables -L -n -v

# Manually drop all traffic originating from a malicious attacker IP
$ sudo iptables -A INPUT -s 203.0.113.88 -j DROP

# Save iptables rules permanently
$ sudo apt install iptables-persistent && sudo netfilter-persistent save
							

4. Automated Intrusion Prevention with Fail2ban

Fail2ban inspects authentication logs for repeated login failures and automatically injects temporary firewall DROP rules to ban the attacker's IP address:


# 1. Install Fail2ban
$ sudo apt install fail2ban -y || sudo dnf install fail2ban -y

# 2. Create custom configuration override (Never edit jail.conf directly!)
$ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
$ sudo nano /etc/fail2ban/jail.local

# Configure SSH jail protection:
[sshd]
enabled = true
port = 22
maxretry = 3
findtime = 10m
bantime = 24h

# 3. Restart and check ban status
$ sudo systemctl restart fail2ban
$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  `- Total failed:     48
`- Actions
   |- Currently banned: 3
   |- Total banned:     15
   `- Banned IP list:   198.51.100.4 203.0.113.92 192.0.2.14

# Unban an accidental lockout of a legitimate team member
$ sudo fail2ban-client set sshd unbanip 198.51.100.4
							

5. Server Hardening Checklist for Production

Apply these industry best practices to secure your Linux environment:

     • Principle of Least Privilege: Never run everyday applications as root. Create dedicated system service accounts.

     • Close Unused Ports: Run sudo ss -tulnp regularly and terminate daemons listening on 0.0.0.0 that are not needed.

     • Automatic Security Patches: Enable unattended-upgrades on Ubuntu/Debian or dnf-automatic on RHEL to patch zero-day kernel vulnerabilities immediately.

     • Enforce Strict Permissions: Audit SUID binaries with find / -perm /4000 2>/dev/null.


Beginner Student Lab Practice Session


# Task 1: Check your active firewall status
$ sudo ufw status verbose || sudo firewall-cmd --state

# Task 2: Scan your own machine locally for open listening network ports
$ sudo ss -tuln

# Task 3: Test adding a temporary block rule and verifying rejection
$ sudo ufw deny from 10.0.0.99
$ sudo ufw status

# Task 4: Inspect real-time authentication logs for failed login attempts
$ sudo grep "Failed password" /var/log/auth.log || sudo journalctl -u ssh | grep "Failed"

# Task 5: Check kernel security modules status (AppArmor or SELinux)
$ sudo aa-status || sudo sestatus
							

Frequently Asked Questions (FAQ)

Because UFW defaults to deny incoming, enabling it without whitelisting SSH will immediately cut off your remote connection and prevent reconnection. You would need out-of-band console access (such as a cloud provider VNC / serial web console) to log in and run sudo ufw allow 22/tcp.

On Ubuntu/Debian: sudo ufw disable. On RHEL/Fedora: sudo systemctl stop firewalld. Once troubleshooting is complete, always re-enable the firewall immediately: sudo ufw enable or sudo systemctl start firewalld.

REJECT discards the packet and sends an ICMP "Port Unreachable" or TCP RST reply back to the sender, letting them know the port is closed. DROP silently discards the packet with zero response; port scanners must wait for an execution timeout, making scanning exponentially slower for attackers.

Next Step in Your Linux Learning Path:

Learn how to diagnose bottlenecks, monitor CPU/RAM/IO, and troubleshoot slow systems in Class 53: Linux Performance Monitoring & System Diagnostics.

Continue to Class 53: Performance Monitoring → Previous: ← Class 51: Cron & Automation | Full Syllabus

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Reddit

You may also like this!