Should I rate-limit packets with iptables?

I'm using iptables on Ubuntu Server. It's a web server on a VPS.
I'd like to know if I should rate-limit packets. If so, what should I rate-limit? And should I do so globally or per IP address?

Reference
I saw people suggesting this:

# Limit packet traffic on a TCP or UDP port:
iptables -A INPUT -p $proto --destination-port $port --syn -m state --state NEW -m limit --limit $lim/s --limit-burst $lb -j ACCEPT

# Limit established/related packet traffic:
iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit $lim/s --limit-burst $lb -j ACCEPT

The above, a global rate-limit don't seem very useful, at least for the cases I can imagine. Is there any case where I should rate-limit globally?
I believe that a rate-limit per IP is usually better:

# Add the IP to the list:
iptables -A INPUT -p $proto --destination-port $port --syn -m state --state NEW -m recent --set --name RATELIMITED
# Drop if exceeded limit:
iptables -A INPUT -p $proto --destination-port $port --syn -m state --state NEW -m recent --update --seconds $sec --hitcount $hc --rttl --name RATELIMITED -j DROP
# Accept if inside limit:
iptables -A INPUT -p $proto --destination-port $port --syn -m state --state NEW -j ACCEPT

Additional question: Remote IPs may be spoofed. How to limit them properly?
Added another question for this:
https://serverfault.com/questions/340258/how-to-rate-limit-spoofed-ips-with-iptables

The goal
I'm trying to mitigate the risk of some D/DoS attacks and general abuse.

Related
How can I rate limit SSH connections with iptables?

PS: I have just opened a related question just for ICMP and it includes rate-limiting for this protocol: iptables | Types of ICMP: which ones are (potentially) harmful?


A rate limit is not a prevention but rather an invitation to DoS - especially in the flavor presented above where packets are going to be dropped if a certain rate of unauthenticated packets without state information has been exceeded. Since everybody can forge packets (including source IP addresses) at this connection state without greater effort, a new DoS attack vector leveraging your rate limit facility will arise.

A rate limit generally will only make sense if you have

  1. either a predictable hard or a soft connection limit in your configuration
  2. set the rate limit for general traffic below this limit in order to be able to set up connections for priority or administrative traffic regardless of the load

While 1. often is hard enough to determine to even bother, 2. will obviously only work if you are able to reliably differentiate "priority or administrative" traffic from the rest upon connection setup - e.g. if it is coming through a different network interface.

In other cases, it would rather reduce your system's resiliency than add to it.


The problem with -m limit is the limitation of all TCP packets whatever the source IP addresses. So, if you have a low limitation for syn packets like

-A INPUT -p tcp  --syn -m limit --limit 30/s --limit-burst 30 -j ACCEPT
-A INPUT -p tcp --syn -j DROP

only one client with the hping command line can take down your server by sending as many tcp packets with SYN flag because the limit rule will match and it will drop many packets whatever the sources IP addresses. limit does not make difference between good traffic and bad traffic. It will take the down the good incoming traffic too.

hping could be something like:

hping thetargetedhostip -p 80 -S -c 1000 -i u20000

It is better to use hashlimit to limit incoming tcp connections per IP address. The following rule will match only if 30 packets per seconds will be received reducing the number of authorized packet per IP to 15 packets per second.

-A INPUT -p tcp --syn -m hashlimit --hashlimit 15/s --hashlimit-burst 30 --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name synattack -j ACCEPT 
-A INPUT -p tcp --syn -j DROP

In Fact, I am CONVINCED that many servers that are taken down today aren't taken by being out of resources during an attack but because of the limit module dropping all the incoming traffic.