iptables rate limiting can be a surprisingly blunt instrument for DDoS protection, often causing more problems than it solves if not configured with surgical precision.

Let’s see it in action. Imagine a web server under a flood of SYN packets, its connection table filling up, and legitimate users getting dropped. We can use iptables to throttle these incoming connections.

# Allow established and related connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Rate limit new incoming TCP connections on port 80
iptables -A INPUT -p tcp --syn --dport 80 -m limit --limit 10/minute --limit-burst 20 -j ACCEPT

# Drop all other incoming TCP connections (this is the blunt part)
iptables -A INPUT -p tcp --dport 80 -j DROP

This setup starts by allowing traffic that’s already part of an established connection, which is crucial for normal operations. Then, it applies a rate limit to new incoming TCP connections (--syn) destined for port 80. We’re allowing up to 10 new connections per minute, with an initial burst of 20 allowed before the rate limit kicks in. If the rate exceeds this, the packets are dropped.

The real power here is understanding how limit and limit-burst interact. The --limit option defines the average rate, expressed as average number of packets per second (or per minute, or per hour, etc.). The --limit-burst option specifies how many packets can arrive in a short period before the rate limiting is enforced. Think of --limit-burst as a buffer: it allows a temporary spike in traffic, but once that buffer is depleted, packets are dropped until the rate falls back within the --limit average.

The problem arises when you set these values too low for legitimate traffic spikes. A popular website might naturally see bursts of connection attempts during peak hours. If your --limit is set to, say, 5 connections per minute, even a moderate surge could trigger the drop rule, impacting your actual users. The final iptables -A INPUT -p tcp --dport 80 -j DROP is the catch-all that drops anything that wasn’t explicitly allowed by the preceding rules. This is essential for a firewall but also highlights the need for precise allow rules.

The most common mistake is to think of rate limiting as a hard cap. It’s not. It’s a statistical average. If you set --limit 10/minute, that’s 1 packet every 6 seconds on average. If you have --limit-burst 20, it means you can have 20 packets arrive almost instantly, and then the system will start dropping packets if more than 10 arrive within the next minute. The system effectively "resets" its burst capacity over time, governed by the --limit. So, if you’re seeing drops, it’s not necessarily that you’re exceeding the average rate, but that you’ve exhausted your burst capacity and haven’t given the system enough time to "recover" that capacity.

A more sophisticated approach for DDoS involves using iptables in conjunction with other tools, like fail2ban, to dynamically update rules based on malicious activity, or to use specialized hardware or cloud-based DDoS mitigation services that can absorb much larger volumes of traffic.

The next error you’ll likely encounter is a legitimate user complaining they can’t access the service, which means your rate limits are still too aggressive.

Want structured learning?

Take the full Iptables course →