Implementing Rate Limiting with iptables

Implementing Rate Limiting with iptables

Rate limiting at the network level provides the first line of defense against brute force attacks. Using iptables to limit connection attempts prevents attackers from overwhelming the SSH service while allowing legitimate users normal access.

Create comprehensive iptables rules for SSH protection:

#!/bin/bash
# ssh-iptables-protection.sh
# Comprehensive iptables rules for SSH brute force prevention

# Flush existing SSH rules
iptables -F SSH_PROTECT 2>/dev/null
iptables -X SSH_PROTECT 2>/dev/null

# Create SSH protection chain
iptables -N SSH_PROTECT

# Jump to SSH_PROTECT for SSH traffic
iptables -A INPUT -p tcp --dport 22 -j SSH_PROTECT

# Allow established connections
iptables -A SSH_PROTECT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Create recent list for tracking
iptables -A SSH_PROTECT -m recent --name SSH --set --source

# Block if more than 3 attempts in 60 seconds
iptables -A SSH_PROTECT -m recent --name SSH --update --seconds 60 --hitcount 4 -j LOG --log-prefix "SSH-BRUTE-FORCE: "
iptables -A SSH_PROTECT -m recent --name SSH --update --seconds 60 --hitcount 4 -j DROP

# Progressive blocking for persistent attackers
# Block for 5 minutes after 10 attempts
iptables -A SSH_PROTECT -m recent --name SSH_BLACKLIST --update --seconds 300 -j DROP
iptables -A SSH_PROTECT -m recent --name SSH --update --seconds 3600 --hitcount 10 --name SSH_BLACKLIST --set -j DROP

# Allow the connection if under threshold
iptables -A SSH_PROTECT -j ACCEPT

# Save rules
iptables-save > /etc/iptables/rules.v4

# IPv6 rules (similar pattern)
ip6tables -N SSH_PROTECT
ip6tables -A INPUT -p tcp --dport 22 -j SSH_PROTECT
ip6tables -A SSH_PROTECT -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A SSH_PROTECT -m recent --name SSH6 --set --source
ip6tables -A SSH_PROTECT -m recent --name SSH6 --update --seconds 60 --hitcount 4 -j DROP
ip6tables -A SSH_PROTECT -j ACCEPT
ip6tables-save > /etc/iptables/rules.v6

Implement geographic-based rate limiting:

# Install geoip module
apt-get install xtables-addons-common libtext-csv-xs-perl

# Download GeoIP database
mkdir -p /usr/share/xt_geoip
cd /usr/share/xt_geoip
/usr/lib/xtables-addons/xt_geoip_dl
/usr/lib/xtables-addons/xt_geoip_build GeoLite2-Country-CSV_*

# Apply geographic restrictions with different rates
# More restrictive for high-risk countries
iptables -A SSH_PROTECT -m geoip --src-cc CN,RU,KP -m recent --name SSH_GEO --set --source
iptables -A SSH_PROTECT -m geoip --src-cc CN,RU,KP -m recent --name SSH_GEO --update --seconds 300 --hitcount 2 -j DROP

# Standard rate for other countries
iptables -A SSH_PROTECT -m geoip ! --src-cc US,CA,GB,DE -m recent --name SSH_FOREIGN --set --source
iptables -A SSH_PROTECT -m geoip ! --src-cc US,CA,GB,DE -m recent --name SSH_FOREIGN --update --seconds 120 --hitcount 3 -j DROP