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.