Best Practices for Rate Limiting Network Traffic with iptables on Ubuntu Web Servers


2 views

When securing a web server on Ubuntu VPS, rate limiting with iptables serves as a crucial defense layer against brute force attacks and DDoS attempts. The decision between global vs per-IP limits depends on your traffic patterns and threat model.

Global rate limits work best for protocols where you want to enforce absolute traffic caps:

# Example: Limit ALL new HTTP connections to 50/sec
iptables -A INPUT -p tcp --dport 80 --syn -m connlimit \
         --connlimit-above 50 -j DROP

# Protect against SYN floods
iptables -N SYN_FLOOD
iptables -A INPUT -p tcp --syn -j SYN_FLOOD
iptables -A SYN_FLOOD -m limit --limit 100/second --limit-burst 150 -j RETURN
iptables -A SYN_FLOOD -j DROP

For most web servers, per-IP limits provide better protection while maintaining service availability:

# SSH protection (3 attempts per minute)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
         -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
         -m recent --update --seconds 60 --hitcount 4 \
         --name SSH -j DROP

# HTTP per-IP throttling (25 connections per IP)
iptables -A INPUT -p tcp --dport 80 -m connlimit \
         --connlimit-above 25 -j DROP

Combine multiple approaches for comprehensive protection:

# Layer 7 protection against slowloris
iptables -N SLOWLORIS
iptables -A INPUT -p tcp --dport 80 -j SLOWLORIS
iptables -A SLOWLORIS -m recent --name ATTACKER --update \
         --seconds 300 -j DROP
iptables -A SLOWLORIS -m string --string "GET / HTTP/1.1" --algo bm \
         -m recent --name ATTACKER --set -j ACCEPT

View current connection counts to adjust your thresholds:

watch -n 1 'iptables -nvL | grep -E "DROP|REJECT"'

Check per-IP connection counts:

netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n

When securing a Linux web server, rate limiting network traffic is a crucial defense mechanism against DDoS attacks and resource exhaustion. The key decision points are whether to implement global limits or per-IP restrictions, and which traffic patterns to control.

Global rate limiting (applying thresholds to all incoming traffic collectively) makes sense for:

  • Protecting against SYN floods on specific ports
  • Limiting overall connection attempts to services
  • Controlling ICMP traffic volume

Per-IP rate limiting is more effective for:

  • Preventing brute force attacks (SSH, web admin panels)
  • Stopping abusive scraping behavior
  • Mitigating slowloris-type attacks

For SSH protection (per-IP limiting):

# Track new SSH connections
iptables -A INPUT -p tcp --dport 22 --syn -m state --state NEW -m recent --set --name SSH

# Drop excessive connection attempts (more than 3 per minute)
iptables -A INPUT -p tcp --dport 22 --syn -m state --state NEW -m recent --update --seconds 60 --hitcount 3 --rttl --name SSH -j DROP

# Accept within limits
iptables -A INPUT -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT

For HTTP/HTTPS global rate limiting:

# Limit new HTTP connections to 20 per second (burst of 40)
iptables -A INPUT -p tcp --dport 80 --syn -m state --state NEW -m limit --limit 20/second --limit-burst 40 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 --syn -m state --state NEW -m limit --limit 20/second --limit-burst 40 -j ACCEPT

For stateful connection tracking:

# Limit established connections to prevent connection exhaustion
iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 50/second --limit-burst 100 -j ACCEPT

To protect against ICMP floods:

# Allow ping but limit to 5 packets per second
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/second -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

When implementing rate limits:

  • Start with conservative values and monitor impact
  • Use separate chains for different services
  • Consider combining with fail2ban for additional protection
  • Test rules thoroughly before production deployment

Remember to persist your iptables rules (using iptables-persistent or similar) to maintain protection across reboots.