Configure advanced iptables firewall rules with logging, port knocking, and DDoS protection

Advanced 45 min Apr 20, 2026 135 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Build a production-grade iptables firewall with connection tracking, rate limiting, and port knocking. Includes automated DDoS protection, detailed logging, and security hardening for enterprise environments.

Prerequisites

  • Root or sudo access
  • Basic understanding of networking concepts
  • SSH access to the server
  • Another machine for testing port knocking

What this solves

Advanced iptables configurations provide enterprise-grade network security with stateful packet filtering, automated threat detection, and intelligent access control. This tutorial builds a production firewall with connection tracking, rate limiting for DDoS protection, port knocking for secure SSH access, and comprehensive logging for security monitoring.

Step-by-step configuration

Install required packages

Install iptables-persistent to save rules and rsyslog for advanced logging capabilities.

sudo apt update
sudo apt install -y iptables iptables-persistent rsyslog netfilter-persistent
sudo dnf install -y iptables iptables-services rsyslog
sudo systemctl disable firewalld
sudo systemctl stop firewalld
sudo systemctl enable iptables
sudo systemctl start iptables

Create backup of existing rules

Always backup current iptables configuration before making changes.

sudo iptables-save > /root/iptables-backup-$(date +%Y%m%d-%H%M%S).rules
sudo cp /etc/iptables/rules.v4 /etc/iptables/rules.v4.backup 2>/dev/null || true

Configure logging infrastructure

Set up dedicated log files for firewall events with proper log rotation.

# Iptables logging configuration
:msg, contains, "[IPTABLES-DROP]:" /var/log/iptables-drop.log
:msg, contains, "[IPTABLES-ACCEPT]:" /var/log/iptables-accept.log
:msg, contains, "[IPTABLES-REJECT]:" /var/log/iptables-reject.log
:msg, contains, "[PORT-KNOCK]:" /var/log/port-knock.log
:msg, contains, "[DDOS-PROTECT]:" /var/log/ddos-protect.log
& stop

Configure log rotation

Set up automated log rotation to prevent disk space issues.

/var/log/iptables-*.log /var/log/port-knock.log /var/log/ddos-protect.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 640 syslog adm
    postrotate
        /usr/lib/rsyslog/rsyslog-rotate
    endscript
}

Create advanced iptables rules script

Build comprehensive firewall rules with connection tracking, rate limiting, and logging.

#!/bin/bash

Advanced iptables firewall configuration

Variables

SSH_PORT=22 HTTP_PORT=80 HTTPS_PORT=443 KNOCK_SEQUENCE="7000 8000 9000" INTERFACE="eth0" TRUSTED_NETWORKS="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16"

Clear existing rules

iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X

Set default policies

iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT

Create custom chains

iptables -N DDOS_PROTECT iptables -N PORT_KNOCK iptables -N LOGGING_DROP iptables -N LOGGING_ACCEPT iptables -N LOGGING_REJECT iptables -N SCAN_DETECT

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 conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

DDOS Protection Chain

Rate limit new connections

iptables -A DDOS_PROTECT -m recent --name ddos --rcheck --seconds 60 --hitcount 20 -j LOG --log-prefix "[DDOS-PROTECT]: " iptables -A DDOS_PROTECT -m recent --name ddos --rcheck --seconds 60 --hitcount 20 -j DROP iptables -A DDOS_PROTECT -m recent --name ddos --set -j ACCEPT

Scan Detection Chain

iptables -A SCAN_DETECT -m recent --name portscan --rcheck --seconds 86400 --hitcount 10 -j LOG --log-prefix "[PORT-SCAN]: " iptables -A SCAN_DETECT -m recent --name portscan --rcheck --seconds 86400 --hitcount 10 -j DROP iptables -A SCAN_DETECT -m recent --name portscan --set -j ACCEPT

Port Knocking Chain

Stage 1: Knock on port 7000

iptables -A PORT_KNOCK -m recent --name knock1 --remove iptables -A PORT_KNOCK -m recent --name knock2 --remove iptables -A PORT_KNOCK -m recent --name knock3 --remove iptables -A PORT_KNOCK -p tcp --dport 7000 -m recent --name knock1 --set -j LOG --log-prefix "[PORT-KNOCK]: Stage 1 - " iptables -A PORT_KNOCK -p tcp --dport 7000 -j DROP

Stage 2: Knock on port 8000 within 30 seconds

iptables -A PORT_KNOCK -p tcp --dport 8000 -m recent --name knock1 --rcheck --seconds 30 -m recent --name knock2 --set -j LOG --log-prefix "[PORT-KNOCK]: Stage 2 - " iptables -A PORT_KNOCK -p tcp --dport 8000 -j DROP

Stage 3: Knock on port 9000 within 30 seconds

iptables -A PORT_KNOCK -p tcp --dport 9000 -m recent --name knock2 --rcheck --seconds 30 -m recent --name knock3 --set -j LOG --log-prefix "[PORT-KNOCK]: Stage 3 - " iptables -A PORT_KNOCK -p tcp --dport 9000 -j DROP

SSH access after successful port knocking

iptables -A PORT_KNOCK -p tcp --dport $SSH_PORT -m recent --name knock3 --rcheck --seconds 30 -m conntrack --ctstate NEW -j LOGGING_ACCEPT iptables -A PORT_KNOCK -p tcp --dport $SSH_PORT -m conntrack --ctstate NEW -j LOGGING_DROP

Logging Chains

iptables -A LOGGING_ACCEPT -j LOG --log-prefix "[IPTABLES-ACCEPT]: " iptables -A LOGGING_ACCEPT -j ACCEPT iptables -A LOGGING_DROP -j LOG --log-prefix "[IPTABLES-DROP]: " iptables -A LOGGING_DROP -j DROP iptables -A LOGGING_REJECT -j LOG --log-prefix "[IPTABLES-REJECT]: " iptables -A LOGGING_REJECT -j REJECT

Anti-spoofing rules

for network in $TRUSTED_NETWORKS; do iptables -A INPUT -i $INTERFACE ! -s $network -m addrtype --src-type LOCAL -j LOGGING_DROP done

Allow trusted networks full access

for network in $TRUSTED_NETWORKS; do iptables -A INPUT -s $network -j LOGGING_ACCEPT done

Allow ICMP (ping) with rate limiting

iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/second --limit-burst 3 -j LOGGING_ACCEPT iptables -A INPUT -p icmp --icmp-type echo-request -j LOGGING_DROP

Allow common ICMP types

iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT iptables -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT

Web server protection with rate limiting

iptables -A INPUT -p tcp --dport $HTTP_PORT -m conntrack --ctstate NEW -j DDOS_PROTECT iptables -A INPUT -p tcp --dport $HTTPS_PORT -m conntrack --ctstate NEW -j DDOS_PROTECT

Allow HTTP and HTTPS

iptables -A INPUT -p tcp --dport $HTTP_PORT -m conntrack --ctstate NEW -j LOGGING_ACCEPT iptables -A INPUT -p tcp --dport $HTTPS_PORT -m conntrack --ctstate NEW -j LOGGING_ACCEPT

SSH protection through port knocking

iptables -A INPUT -p tcp --dport $SSH_PORT -j PORT_KNOCK

Allow NTP (Network Time Protocol)

iptables -A INPUT -p udp --dport 123 -j LOGGING_ACCEPT

Allow DNS

iptables -A INPUT -p udp --dport 53 -j LOGGING_ACCEPT iptables -A INPUT -p tcp --dport 53 -j LOGGING_ACCEPT

Port scan detection for other ports

iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j ACCEPT iptables -A INPUT -m conntrack --ctstate INVALID -j LOGGING_DROP

Protect against common attacks

Null packets

iptables -A INPUT -p tcp --tcp-flags ALL NONE -j LOGGING_DROP

Syn-flood protection

iptables -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j LOGGING_DROP

XMAS packets

iptables -A INPUT -p tcp --tcp-flags ALL ALL -j LOGGING_DROP

Stealth scans

iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j LOGGING_DROP iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOGGING_DROP

Drop fragments

iptables -A INPUT -f -j LOGGING_DROP

Apply scan detection to remaining traffic

iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j SCAN_DETECT

Log and drop everything else

iptables -A INPUT -j LOGGING_DROP echo "Advanced firewall rules applied successfully" echo "Port knocking sequence: $KNOCK_SEQUENCE" echo "Check logs in /var/log/iptables-*.log and /var/log/port-knock.log"

Create port knocking client script

Build a helper script for legitimate users to perform the port knock sequence.

#!/bin/bash

Port knocking client for SSH access

if [ $# -ne 1 ]; then echo "Usage: $0 " echo "Example: $0 203.0.113.10" exit 1 fi TARGET="$1" KNOCK_PORTS="7000 8000 9000" SSH_PORT="22" echo "Performing port knock sequence on $TARGET..." for port in $KNOCK_PORTS; do echo "Knocking port $port..." nc -z $TARGET $port 2>/dev/null || timeout 1 bash -c "/dev/null sleep 1 done echo "Port knock complete. You can now SSH to $TARGET" echo "ssh user@$TARGET" echo "Access window: 30 seconds"

Make scripts executable and apply rules

Set proper permissions and execute the firewall configuration script.

sudo chmod +x /usr/local/bin/setup-advanced-firewall.sh
sudo chmod +x /usr/local/bin/knock-ssh.sh
sudo /usr/local/bin/setup-advanced-firewall.sh

Save iptables rules permanently

Ensure firewall rules persist after system reboot.

sudo iptables-save | sudo tee /etc/iptables/rules.v4
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
sudo systemctl enable netfilter-persistent
sudo iptables-save | sudo tee /etc/sysconfig/iptables
sudo systemctl enable iptables
sudo systemctl save iptables

Restart rsyslog and configure log monitoring

Apply logging configuration and set up log file permissions.

sudo systemctl restart rsyslog
sudo touch /var/log/iptables-drop.log /var/log/iptables-accept.log /var/log/iptables-reject.log /var/log/port-knock.log /var/log/ddos-protect.log
sudo chown syslog:adm /var/log/iptables-*.log /var/log/port-knock.log /var/log/ddos-protect.log
sudo chmod 640 /var/log/iptables-*.log /var/log/port-knock.log /var/log/ddos-protect.log

Create firewall management script

Build a management interface for common firewall operations.

#!/bin/bash

case "$1" in
    status)
        echo "=== Firewall Status ==="
        iptables -L -n --line-numbers
        echo ""
        echo "=== Connection Tracking ==="
        cat /proc/net/nf_conntrack | wc -l
        echo "Active connections"
        ;;
    logs)
        echo "=== Recent Firewall Logs ==="
        echo "Dropped packets (last 10):"
        tail -10 /var/log/iptables-drop.log 2>/dev/null || echo "No drop logs yet"
        echo ""
        echo "Port knocking attempts (last 10):"
        tail -10 /var/log/port-knock.log 2>/dev/null || echo "No knock logs yet"
        echo ""
        echo "DDoS protection triggers (last 10):"
        tail -10 /var/log/ddos-protect.log 2>/dev/null || echo "No DDoS logs yet"
        ;;
    stats)
        echo "=== Firewall Statistics ==="
        echo "Chain packet/byte counts:"
        iptables -L -n -v
        echo ""
        echo "Recent connection tracking:"
        cat /proc/sys/net/netfilter/nf_conntrack_count
        echo "Current connections"
        cat /proc/sys/net/netfilter/nf_conntrack_max
        echo "Maximum connections"
        ;;
    allow-ip)
        if [ -z "$2" ]; then
            echo "Usage: $0 allow-ip "
            exit 1
        fi
        echo "Adding temporary allow rule for $2"
        iptables -I INPUT -s "$2" -j LOGGING_ACCEPT
        echo "Rule added. Use 'remove-ip $2' to remove"
        ;;
    remove-ip)
        if [ -z "$2" ]; then
            echo "Usage: $0 remove-ip "
            exit 1
        fi
        echo "Removing allow rule for $2"
        iptables -D INPUT -s "$2" -j LOGGING_ACCEPT 2>/dev/null && echo "Rule removed" || echo "Rule not found"
        ;;
    reset-knock)
        echo "Clearing port knock tracking"
        iptables -Z PORT_KNOCK
        iptables -F PORT_KNOCK
        echo "Port knock counters reset"
        ;;
    backup)
        BACKUP_FILE="/root/iptables-backup-$(date +%Y%m%d-%H%M%S).rules"
        iptables-save > "$BACKUP_FILE"
        echo "Firewall rules backed up to $BACKUP_FILE"
        ;;
    *)
        echo "Advanced Firewall Management"
        echo "Usage: $0 {status|logs|stats|allow-ip|remove-ip|reset-knock|backup}"
        echo ""
        echo "Commands:"
        echo "  status     - Show current firewall rules and connection count"
        echo "  logs       - Display recent firewall log entries"
        echo "  stats      - Show detailed firewall statistics"
        echo "  allow-ip   - Temporarily allow an IP address"
        echo "  remove-ip  - Remove temporary IP allow rule"
        echo "  reset-knock- Reset port knocking tracking"
        echo "  backup     - Create backup of current rules"
        exit 1
        ;;
esac

Make management script executable

Set permissions for the firewall management script.

sudo chmod +x /usr/local/bin/manage-firewall.sh
Important: Test your configuration thoroughly before applying to production systems. Always maintain a backup connection method and have console access available when implementing advanced firewall rules.

Advanced configuration options

Configure connection tracking optimization

Tune connection tracking parameters for high-traffic environments.

# Connection tracking optimization
net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_established = 1200
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 60
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 180

Hash table size

net.netfilter.nf_conntrack_buckets = 262144

TCP window scaling

net.netfilter.nf_conntrack_tcp_be_liberal = 1 net.netfilter.nf_conntrack_tcp_loose = 1

Apply sysctl settings

Load the connection tracking optimizations.

sudo sysctl -p /etc/sysctl.d/99-netfilter.conf
sudo sysctl net.netfilter.nf_conntrack_max

Set up automated log monitoring

Create a script to monitor and alert on suspicious firewall activity.

#!/bin/bash

Firewall log monitoring script

LOG_FILE="/var/log/iptables-drop.log" ALERT_FILE="/tmp/firewall-alerts.tmp" THRESHOLD=100 TIME_WINDOW=300 # 5 minutes

Check for high drop rates

DROP_COUNT=$(tail -1000 "$LOG_FILE" | grep "$(date '+%b %d %H:%M' -d '5 minutes ago')" | wc -l) if [ "$DROP_COUNT" -gt "$THRESHOLD" ]; then echo "$(date): High drop rate detected - $DROP_COUNT drops in last $TIME_WINDOW seconds" >> "$ALERT_FILE" # Send alert (configure mail/slack webhook as needed) echo "ALERT: High firewall drop rate - $DROP_COUNT drops detected" | logger -p local0.warning fi

Check for port scan attempts

SCAN_ATTEMPTS=$(grep "PORT-SCAN" /var/log/iptables-drop.log | grep "$(date '+%b %d')" | wc -l) if [ "$SCAN_ATTEMPTS" -gt 10 ]; then echo "$(date): Port scan activity detected - $SCAN_ATTEMPTS attempts today" >> "$ALERT_FILE" echo "ALERT: Port scan activity - $SCAN_ATTEMPTS attempts detected today" | logger -p local0.warning fi

Check connection tracking table usage

CURRENT_CONNS=$(cat /proc/sys/net/netfilter/nf_conntrack_count) MAX_CONNS=$(cat /proc/sys/net/netfilter/nf_conntrack_max) USAGE_PERCENT=$(( CURRENT_CONNS * 100 / MAX_CONNS )) if [ "$USAGE_PERCENT" -gt 80 ]; then echo "$(date): High connection tracking usage - ${USAGE_PERCENT}%" >> "$ALERT_FILE" echo "ALERT: Connection tracking usage at ${USAGE_PERCENT}%" | logger -p local0.warning fi

Set up monitoring cron job

Schedule the monitoring script to run every 5 minutes.

sudo chmod +x /usr/local/bin/firewall-monitor.sh
(sudo crontab -l 2>/dev/null; echo "/5    * /usr/local/bin/firewall-monitor.sh") | sudo crontab -

Verify your setup

# Check firewall status
sudo /usr/local/bin/manage-firewall.sh status

View recent logs

sudo /usr/local/bin/manage-firewall.sh logs

Test port knocking from another machine

/usr/local/bin/knock-ssh.sh 203.0.113.10

Check connection tracking

cat /proc/sys/net/netfilter/nf_conntrack_count cat /proc/sys/net/netfilter/nf_conntrack_max

Verify logging is working

sudo tail -f /var/log/iptables-drop.log

Test DDoS protection (from external host)

for i in {1..25}; do curl -m 1 http://your-server; done

Check custom chains

sudo iptables -L DDOS_PROTECT -n -v sudo iptables -L PORT_KNOCK -n -v sudo iptables -L SCAN_DETECT -n -v

Port knocking usage

To access SSH after implementing port knocking, users must perform the knock sequence first:

# From client machine
/usr/local/bin/knock-ssh.sh 203.0.113.10

Then immediately connect

ssh user@203.0.113.10

The port knock sequence opens SSH access for 30 seconds. Each successful knock is logged for auditing purposes.

Monitoring and maintenance

Task Command Frequency
Check firewall status manage-firewall.sh status Daily
Review security logs manage-firewall.sh logs Daily
Monitor connection usage manage-firewall.sh stats Weekly
Backup firewall rules manage-firewall.sh backup Before changes
Check log rotation ls -la /var/log/iptables-* Monthly

Consider integrating firewall logs with your centralized logging infrastructure or setting up automated alerting for security events.

Common issues

Symptom Cause Fix
SSH access locked out Port knocking sequence incorrect Use manage-firewall.sh reset-knock and retry sequence
High connection tracking usage Too many concurrent connections Increase nf_conntrack_max in sysctl configuration
Web server responding slowly DDoS protection too aggressive Adjust rate limits in DDOS_PROTECT chain
Logs not appearing rsyslog configuration issues Check sudo systemctl status rsyslog and restart service
Rules not persisting after reboot iptables-persistent not configured Run sudo iptables-save > /etc/iptables/rules.v4
Port knocking not working Recent module tracking issues Clear tracking: echo > /proc/net/xt_recent/knock1

Advanced tuning options

For high-traffic environments, consider these additional optimizations:

  • Hash table sizing: Increase nf_conntrack_buckets to 1/4 of nf_conntrack_max
  • TCP timeouts: Reduce timeout values for faster cleanup of stale connections
  • Rate limiting: Adjust --limit and --limit-burst values based on traffic patterns
  • Connection tracking: Use NOTRACK target for high-volume, low-risk traffic
  • Hardware acceleration: Enable network offloading features when available

Next steps

Running this in production?

Want this handled for you? Running this at scale adds a second layer of work: capacity planning, failover drills, cost control, and on-call. Our managed platform covers monitoring, backups and 24/7 response by default.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle infrastructure security hardening for businesses that depend on uptime. From initial setup to ongoing operations.