Skip to content

Linux Firewalls: Complete Guide

Overview

Linux firewalls control network traffic flow based on predetermined rules. They operate at different layers and use various frameworks, from low-level packet filtering to high-level application gateways.

Firewall Evolution Timeline

Era Tool Type Status
Legacy ipchains Packet filter Obsolete
Traditional iptables/ip6tables Netfilter frontend Widely used
Modern nftables Unified framework Current standard
User-Friendly ufw, firewalld High-level frontends Popular

iptables: Traditional Firewall

iptables Architecture

Netfilter Hooks → Tables → Chains → Rules → Targets

Tables and Chains

# Tables (processing purposes)
filter    # Default table for filtering packets
nat       # Network Address Translation
mangle    # Packet alteration
raw       # Connection tracking exemption
security  # SELinux context

# Built-in Chains
INPUT     # Incoming packets destined for local system
OUTPUT    # Outgoing packets from local system
FORWARD   # Packets routed through the system
PREROUTING  # Packets before routing decision
POSTROUTING # Packets after routing decision

Basic iptables Commands

# View current rules
iptables -L -n -v                    # List all rules with packet counts
iptables -t nat -L                   # List NAT table rules
iptables -L INPUT --line-numbers     # Show rule numbers

# Basic rule syntax
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
#        │  │     │                   │
#        │  │     │                   └─ Target (action)
#        │  │     └─ Match criteria
#        │  └─ Chain
#        └─ Action (Append)

# Common actions
-A  # Append rule to end of chain
-I  # Insert rule at specific position
-D  # Delete rule
-R  # Replace rule
-F  # Flush (delete all rules)
-P  # Set default policy

Common iptables Rules

# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Allow loopback traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

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

# Allow SSH (port 22)
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

# Allow specific source
iptables -A INPUT -s 192.168.1.100 -j ACCEPT

# Block specific IP
iptables -A INPUT -s 10.0.0.100 -j DROP

# Allow ping (ICMP)
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT

# Rate limiting (prevent DoS)
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT

Advanced iptables Features

# Connection tracking
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Time-based rules
iptables -A INPUT -p tcp --dport 80 -m time --timestart 09:00 --timestop 17:00 -j ACCEPT

# MAC address filtering
iptables -A INPUT -m mac --mac-source 00:11:22:33:44:55 -j ACCEPT

# Multi-port matching
iptables -A INPUT -p tcp -m multiport --dports 80,443,8080 -j ACCEPT

# String matching
iptables -A FORWARD -p tcp --dport 80 -m string --string "malware" --algo bm -j DROP

# Geolocation blocking (with geoip module)
iptables -A INPUT -m geoip --src-cc CN,RU -j DROP

# Recent module (track connection attempts)
iptables -A INPUT -p tcp --dport 22 -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP

NAT Configuration

# SNAT (Source NAT) - Masquerading
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# DNAT (Destination NAT) - Port forwarding
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:8080

# Redirect local ports
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 8080

iptables Persistence

# Save rules (Debian/Ubuntu)
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

# Install persistence package
sudo apt install iptables-persistent

# Save rules (CentOS/RHEL)
service iptables save
# or
iptables-save > /etc/sysconfig/iptables

# Restore rules
iptables-restore < /etc/iptables/rules.v4

nftables: Modern Firewall Framework

nftables Advantages

  • Unified framework for IPv4/IPv6
  • Better performance
  • Simplified rule syntax
  • Atomic rule updates
  • Better scripting support

Basic nftables Concepts

# Hierarchy: table → chain → rule

# Tables (address families)
ip        # IPv4
ip6       # IPv6
inet      # IPv4 and IPv6
arp       # ARP
bridge    # Bridge
netdev    # Network device (ingress)

nftables Commands

# List current configuration
nft list ruleset

# List specific table
nft list table inet filter

# Create table
nft add table inet filter

# Create chain
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }

# Add rule
nft add rule inet filter input tcp dport 22 accept

# Delete rule by handle
nft list ruleset -a    # Show handles
nft delete rule inet filter input handle 5

Sample nftables Configuration

#!/usr/sbin/nft -f

# Clear existing rules
flush ruleset

# Main table
table inet filter {
    # Input chain
    chain input {
        type filter hook input priority 0; policy drop;

        # Allow loopback
        iif lo accept

        # Allow established/related
        ct state established,related accept

        # Allow SSH
        tcp dport 22 accept

        # Allow HTTP/HTTPS
        tcp dport { 80, 443 } accept

        # Allow ICMP
        icmp type echo-request accept

        # Rate limiting
        tcp dport 80 limit rate 10/second accept

        # Drop everything else
        counter drop
    }

    # Output chain
    chain output {
        type filter hook output priority 0; policy accept;
    }

    # Forward chain
    chain forward {
        type filter hook forward priority 0; policy drop;
    }
}

# NAT table
table inet nat {
    chain prerouting {
        type nat hook prerouting priority -100;

        # Port forwarding
        tcp dport 8080 dnat to 192.168.1.100:80
    }

    chain postrouting {
        type nat hook postrouting priority 100;

        # Masquerading
        oif eth0 masquerade
    }
}

nftables Sets and Maps

# Create sets for efficient matching
nft add set inet filter blacklist { type ipv4_addr \; }
nft add element inet filter blacklist { 10.0.0.1, 10.0.0.2 }
nft add rule inet filter input ip saddr @blacklist drop

# Create maps
nft add map inet filter port_redirect { type inet_service : ipv4_addr . inet_service \; }
nft add element inet filter port_redirect { 80 : 192.168.1.100 . 8080 }
nft add rule inet filter prerouting dnat to tcp dport map @port_redirect

UFW (Uncomplicated Firewall)

UFW Basics

# Enable/disable UFW
sudo ufw enable
sudo ufw disable

# Check status
sudo ufw status
sudo ufw status verbose
sudo ufw status numbered

# Default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing

UFW Rules

# Allow/deny by port
sudo ufw allow 22
sudo ufw allow 80/tcp
sudo ufw allow 53/udp
sudo ufw deny 23

# Allow/deny by service name
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https

# Allow from specific IP
sudo ufw allow from 192.168.1.100
sudo ufw allow from 192.168.1.0/24

# Allow to specific port from specific IP
sudo ufw allow from 192.168.1.100 to any port 22

# Allow specific application
sudo ufw allow 'Apache Full'
sudo ufw allow 'OpenSSH'

# Delete rules
sudo ufw delete allow 80
sudo ufw delete 2  # By rule number

# Advanced rules
sudo ufw allow from 192.168.1.0/24 to any port 3306
sudo ufw limit ssh  # Rate limiting for SSH

UFW Application Profiles

# List available profiles
sudo ufw app list

# Show profile details
sudo ufw app info 'Apache Full'

# Create custom profile (/etc/ufw/applications.d/myapp)
[MyApp]
title=My Application
description=Custom application
ports=8080,8443/tcp

# Update application profiles
sudo ufw app update MyApp

firewalld: Dynamic Firewall Management

firewalld Concepts

# Zones: Predefined rule sets for different trust levels
# Services: Named service definitions
# Runtime vs Permanent: Temporary vs persistent changes

firewalld Zones

# List zones
firewall-cmd --get-zones

# Default zones
drop       # Drop all incoming, allow outgoing
block      # Reject all incoming, allow outgoing
public     # Default zone, selective incoming
external   # Masquerading enabled
dmz        # Limited access
work       # Trust work environment
home       # Trust home environment
internal   # Internal network
trusted    # Trust all connections

# Check active zones
firewall-cmd --get-active-zones

# Get default zone
firewall-cmd --get-default-zone

# Set default zone
firewall-cmd --set-default-zone=public

firewalld Commands

# Service management
firewall-cmd --list-services
firewall-cmd --add-service=http
firewall-cmd --add-service=https --permanent
firewall-cmd --remove-service=ssh
firewall-cmd --reload  # Apply permanent changes

# Port management
firewall-cmd --list-ports
firewall-cmd --add-port=8080/tcp
firewall-cmd --add-port=1000-2000/tcp
firewall-cmd --remove-port=8080/tcp

# Source management
firewall-cmd --add-source=192.168.1.0/24
firewall-cmd --remove-source=192.168.1.100

# Rich rules (advanced)
firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" drop'

# Masquerading
firewall-cmd --add-masquerade
firewall-cmd --list-all

# Port forwarding
firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.100

Custom firewalld Services

# Create custom service (/etc/firewalld/services/myapp.xml)
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>MyApp</short>
  <description>My custom application</description>
  <port protocol="tcp" port="8080"/>
  <port protocol="udp" port="8081"/>
</service>

# Reload and use
firewall-cmd --reload
firewall-cmd --add-service=myapp

Application Layer Firewalls

fail2ban: Intrusion Prevention

# Install fail2ban
sudo apt install fail2ban

# Configuration files
/etc/fail2ban/jail.conf     # Default configuration (don't edit)
/etc/fail2ban/jail.local    # Local overrides

# Sample jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
ignoreip = 127.0.0.1/8 192.168.1.0/24

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3

[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache*/*error.log
maxretry = 6

# Manage fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Check status
sudo fail2ban-client status
sudo fail2ban-client status sshd

# Unban IP
sudo fail2ban-client set sshd unbanip 192.168.1.100

ModSecurity: Web Application Firewall

# Install ModSecurity for Apache
sudo apt install libapache2-mod-security2

# Enable module
sudo a2enmod security2

# Configuration (/etc/apache2/mods-enabled/security2.conf)
<IfModule mod_security2.c>
    SecRuleEngine On
    SecRequestBodyAccess On
    SecResponseBodyAccess Off
    SecDataDir /var/cache/modsecurity

    # Include OWASP Core Rule Set
    Include /etc/modsecurity/*.conf
    Include /etc/modsecurity/activated_rules/*.conf
</IfModule>

# Download OWASP CRS
cd /etc/modsecurity
sudo wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/v3.3.0.tar.gz
sudo tar -xzf v3.3.0.tar.gz
sudo mv owasp-modsecurity-crs-3.3.0 crs

Network Segmentation and VLANs

Bridge Firewalling

# Enable bridge firewalling
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 1 > /proc/sys/net/bridge/bridge-nf-call-ip6tables

# Make persistent
echo 'net.bridge.bridge-nf-call-iptables = 1' >> /etc/sysctl.conf
echo 'net.bridge.bridge-nf-call-ip6tables = 1' >> /etc/sysctl.conf

# Bridge filtering rules
iptables -A FORWARD -m physdev --physdev-in eth0 --physdev-out eth1 -j ACCEPT

VLAN Filtering

# Create VLAN interfaces
ip link add link eth0 name eth0.100 type vlan id 100
ip link add link eth0 name eth0.200 type vlan id 200

# Configure VLAN firewalling
iptables -A FORWARD -i eth0.100 -o eth0.200 -j DROP
iptables -A FORWARD -i eth0.200 -o eth0.100 -j DROP

Advanced Firewall Features

Connection Tracking

# View connection tracking table
conntrack -L

# Connection tracking statistics
cat /proc/net/nf_conntrack

# Tune connection tracking
echo 'net.netfilter.nf_conntrack_max = 131072' >> /etc/sysctl.conf
echo 'net.netfilter.nf_conntrack_tcp_timeout_established = 54000' >> /etc/sysctl.conf

DPI (Deep Packet Inspection)

# Layer 7 filtering with l7-filter (deprecated)
# Modern alternative: nDPI integration

# Protocol detection with nDPI
iptables -A FORWARD -m ndpi --protocol bittorrent -j DROP
iptables -A FORWARD -m ndpi --protocol facebook -j REJECT

Traffic Shaping Integration

# QoS with tc (traffic control)
tc qdisc add dev eth0 root handle 1: htb default 30

# Create classes
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 80mbit ceil 100mbit
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 20mbit ceil 100mbit

# Mark packets with iptables
iptables -t mangle -A OUTPUT -p tcp --dport 80 -j MARK --set-mark 10
iptables -t mangle -A OUTPUT -p tcp --dport 22 -j MARK --set-mark 20

# Filter based on marks
tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 10 fw flowid 1:10
tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 20 fw flowid 1:20

Firewall Testing and Monitoring

Testing Firewall Rules

# Port scanning with nmap
nmap -sS -O target_host              # SYN scan
nmap -sU target_host                 # UDP scan
nmap -A target_host                  # Aggressive scan

# Test specific ports
nc -zv target_host 80                # Test TCP port
nc -zuv target_host 53               # Test UDP port

# Test from specific source
hping3 -S -p 80 -c 5 target_host     # SYN flood test

Monitoring and Logging

# Enable iptables logging
iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4

# View firewall logs
tail -f /var/log/kern.log | grep IPTABLES
journalctl -f -k | grep IPTABLES

# Analyze logs with fail2ban
# Custom filter for iptables logs
# /etc/fail2ban/filter.d/iptables.conf
[Definition]
failregex = .*IPTABLES-DROP.*SRC=<HOST>.*
ignoreregex =

# Performance monitoring
watch -n 1 'iptables -L -n -v'
watch -n 1 'nft list ruleset'

Firewall Performance Optimization

Rule Optimization

# Place most common rules first
# Use specific matches instead of generic ones
# Minimize rule traversal

# Good: Specific rule first
iptables -A INPUT -s 192.168.1.100 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Use connection tracking efficiently
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Avoid unnecessary logging in performance-critical paths

Hardware Acceleration

# Check for hardware offload support
ethtool -k eth0 | grep hw-tc-offload

# Enable hardware offload (if supported)
ethtool -K eth0 hw-tc-offload on

# nftables offload (requires kernel 5.4+)
nft add table netdev filter
nft add chain netdev filter ingress { type filter hook ingress device eth0 priority 0 \; }
nft add rule netdev filter ingress tcp dport 80 counter accept

Firewall Comparison Summary

Feature iptables nftables UFW firewalld
Complexity High Medium Low Medium
Performance Good Better Good Good
IPv6 Support Separate tool Unified Built-in Built-in
Atomic Updates No Yes No Yes
Scripting Complex Better Limited Good
Learning Curve Steep Moderate Easy Moderate
Enterprise Features Manual Built-in Limited Extensive

Best Practices

Security Best Practices

# 1. Default deny policy
iptables -P INPUT DROP
iptables -P FORWARD DROP

# 2. Allow only necessary services
# 3. Use rate limiting for public services
# 4. Implement logging for security events
# 5. Regular rule audits
# 6. Network segmentation
# 7. Intrusion detection integration
# 8. Regular updates and patches

Management Best Practices

# 1. Document all rules and changes
# 2. Use version control for configurations
# 3. Test rules in staging environment
# 4. Implement change management procedures
# 5. Monitor firewall performance
# 6. Regular backup of configurations
# 7. Emergency access procedures
# 8. Staff training and knowledge transfer

Linux firewalls provide comprehensive network security through multiple layers and tools, from low-level packet filtering to high-level application protection, enabling fine-grained control over network traffic flow.