Should I rate-limit packets with iptables?

28,360

Solution 1

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.

Solution 2

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.

Solution 3

I typically limit rate limiting rules to servers that I expect to have:

  • low amounts of expected traffic
  • authentication services

For example, a hosting control panel's login page, POP3, IMAP, SSH, etc. I usually leave HTTP services wide open and only block if there is an issue.

You do not want to drop good web traffic. A link on slashdot could send you tons of traffic and with global rules, you may not realize an issue.

With regard to spoofed IPs, they cannot be blocked using this method and are typically not a concern since these rules mainly focus on limiting established TCP connections. With a spoof IP the TCP connection can never be established.

Share:
28,360

Related videos on Youtube

ML--
Author by

ML--

Updated on September 18, 2022

Comments

  • ML--
    ML-- over 1 year

    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?

  • ML--
    ML-- over 12 years
    Hi jeffatrackaid, thanks for your answer! I'm inclined, too, to rate-limit (globally) these types of services (SSH etc). Regarding HTTP traffic, that's why I don't intend to apply a global limit. In this question I expect to see whether there are cases when a limit per IP can be interesting. Regarding spoofed IPs (I opened a separated question on that) although connections can't be established, there's the possibility of a DoS by using a SYN flood. I remain interested in hearing how this could be mitigated.
  • Ján Lalinský
    Ján Lalinský over 5 years
    Per-ip or per-ip-port rate limiting also seems to make sense when defending from legitimate traffic that is too massive for one's server but whose originator isn't likely to exploit the problem you mention, say, abusive behaviour from the Bingbot or Facebook bots.