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
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
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
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_bucketsto 1/4 ofnf_conntrack_max - TCP timeouts: Reduce timeout values for faster cleanup of stale connections
- Rate limiting: Adjust
--limitand--limit-burstvalues based on traffic patterns - Connection tracking: Use
NOTRACKtarget for high-volume, low-risk traffic - Hardware acceleration: Enable network offloading features when available
Next steps
- Set up OSSEC intrusion detection to complement firewall logging
- Configure centralized logging for security event correlation
- Advanced network security with iptables
- Implement fail2ban for automated blocking
- Configure iptables high availability for redundant firewall deployments
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Advanced iptables firewall configuration script
# Configures enterprise-grade network security with DDoS protection, port knocking, and logging
# Color definitions
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuration variables
SSH_PORT="${1:-22}"
INTERFACE="${2:-$(ip route | grep default | awk '{print $5}' | head -n1)}"
KNOCK_SEQUENCE="7000 8000 9000"
BACKUP_DIR="/root/iptables-backups"
# Usage function
usage() {
echo "Usage: $0 [SSH_PORT] [INTERFACE]"
echo "Example: $0 22 eth0"
exit 1
}
# Cleanup function
cleanup() {
echo -e "${RED}[ERROR] Script failed. Restoring original iptables rules...${NC}"
if [ -f "$BACKUP_DIR/iptables-backup-latest.rules" ]; then
iptables-restore < "$BACKUP_DIR/iptables-backup-latest.rules"
echo -e "${GREEN}Firewall rules restored${NC}"
fi
}
trap cleanup ERR
# Check if running as root
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root${NC}"
exit 1
fi
# Detect distribution
echo "[1/8] Detecting distribution..."
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
SERVICE_CMD="systemctl"
IPTABLES_RULES_FILE="/etc/iptables/rules.v4"
RSYSLOG_CONF_DIR="/etc/rsyslog.d"
LOGROTATE_DIR="/etc/logrotate.d"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
SERVICE_CMD="systemctl"
IPTABLES_RULES_FILE="/etc/sysconfig/iptables"
RSYSLOG_CONF_DIR="/etc/rsyslog.d"
LOGROTATE_DIR="/etc/logrotate.d"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
SERVICE_CMD="systemctl"
IPTABLES_RULES_FILE="/etc/sysconfig/iptables"
RSYSLOG_CONF_DIR="/etc/rsyslog.d"
LOGROTATE_DIR="/etc/logrotate.d"
;;
*)
echo -e "${RED}Unsupported distribution: $ID${NC}"
exit 1
;;
esac
echo -e "${GREEN}Detected: $PRETTY_NAME${NC}"
else
echo -e "${RED}Cannot detect distribution${NC}"
exit 1
fi
# Install required packages
echo "[2/8] Installing required packages..."
if [ "$PKG_MGR" = "apt" ]; then
apt update
$PKG_INSTALL iptables iptables-persistent rsyslog netfilter-persistent
else
$PKG_INSTALL iptables iptables-services rsyslog
$SERVICE_CMD disable firewalld 2>/dev/null || true
$SERVICE_CMD stop firewalld 2>/dev/null || true
$SERVICE_CMD enable iptables
fi
# Create backup directory and backup existing rules
echo "[3/8] Creating backup of existing rules..."
mkdir -p "$BACKUP_DIR"
iptables-save > "$BACKUP_DIR/iptables-backup-$(date +%Y%m%d-%H%M%S).rules"
cp "$BACKUP_DIR/iptables-backup-$(date +%Y%m%d-%H%M%S).rules" "$BACKUP_DIR/iptables-backup-latest.rules"
# Configure logging infrastructure
echo "[4/8] Configuring logging infrastructure..."
cat > "$RSYSLOG_CONF_DIR/99-iptables.conf" << 'EOF'
# 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
EOF
# Configure log rotation
echo "[5/8] Configuring log rotation..."
cat > "$LOGROTATE_DIR/iptables" << 'EOF'
/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
}
EOF
# Create advanced iptables rules
echo "[6/8] Creating advanced iptables rules..."
# 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 SCAN_DETECT
# Logging chains
iptables -A LOGGING_DROP -m limit --limit 10/min -j LOG --log-prefix "[IPTABLES-DROP]: "
iptables -A LOGGING_DROP -j DROP
iptables -A LOGGING_ACCEPT -m limit --limit 10/min -j LOG --log-prefix "[IPTABLES-ACCEPT]: "
iptables -A LOGGING_ACCEPT -j 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 conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# DDoS Protection Chain
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 3600 --hitcount 10 -j LOG --log-prefix "[PORT-SCAN]: "
iptables -A SCAN_DETECT -m recent --name portscan --rcheck --seconds 3600 --hitcount 10 -j DROP
iptables -A SCAN_DETECT -m recent --name portscan --set -j ACCEPT
# Port Knocking Chain
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
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
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 with port knocking
iptables -A INPUT -p tcp --dport "$SSH_PORT" -m recent --name knock3 --rcheck --seconds 30 -j DDOS_PROTECT
iptables -A INPUT -p tcp --dport 7000:9000 -j PORT_KNOCK
# Allow HTTP and HTTPS
iptables -A INPUT -p tcp --dport 80 -j DDOS_PROTECT
iptables -A INPUT -p tcp --dport 443 -j DDOS_PROTECT
# Apply scan detection to all other traffic
iptables -A INPUT -j SCAN_DETECT
# Log and drop everything else
iptables -A INPUT -j LOGGING_DROP
# Save rules
echo "[7/8] Saving iptables rules..."
if [ "$PKG_MGR" = "apt" ]; then
mkdir -p "$(dirname "$IPTABLES_RULES_FILE")"
iptables-save > "$IPTABLES_RULES_FILE"
$SERVICE_CMD enable netfilter-persistent
else
iptables-save > "$IPTABLES_RULES_FILE"
$SERVICE_CMD enable iptables
fi
# Restart services
$SERVICE_CMD restart rsyslog
if [ "$PKG_MGR" = "apt" ]; then
$SERVICE_CMD restart netfilter-persistent
else
$SERVICE_CMD restart iptables
fi
# Verification
echo "[8/8] Verifying configuration..."
if iptables -L -n | grep -q "DDOS_PROTECT"; then
echo -e "${GREEN}✓ DDoS protection chain configured${NC}"
else
echo -e "${RED}✗ DDoS protection chain not found${NC}"
fi
if iptables -L -n | grep -q "PORT_KNOCK"; then
echo -e "${GREEN}✓ Port knocking chain configured${NC}"
else
echo -e "${RED}✗ Port knocking chain not found${NC}"
fi
if [ -f "$RSYSLOG_CONF_DIR/99-iptables.conf" ]; then
echo -e "${GREEN}✓ Logging configuration created${NC}"
else
echo -e "${RED}✗ Logging configuration not found${NC}"
fi
echo -e "\n${GREEN}Advanced iptables firewall configuration completed successfully!${NC}"
echo -e "${YELLOW}Port knocking sequence: $KNOCK_SEQUENCE${NC}"
echo -e "${YELLOW}SSH port: $SSH_PORT${NC}"
echo -e "${YELLOW}Network interface: $INTERFACE${NC}"
echo -e "${YELLOW}Log files: /var/log/iptables-*.log, /var/log/port-knock.log${NC}"
echo -e "\n${RED}IMPORTANT: Test SSH connectivity before closing this session!${NC}"
Review the script before running. Execute with: bash install.sh