The iptables Rate-Limiting Module
Introduction
What is rate limiting with iptables?
iptables (http://www.netfilter.org) is the packet filtering firewall rolled into the GNU/Linux kernel starting with version 2.4.
In the transition from ipchains to iptables, many fairly significant changes were made. The most widely acknowledged was the introduction of statefulness, or 'connection tracking'. The more fundamental, and in my opinion, more exciting shift, has been the increased emphasis on modules.
This article will discuss the rate limiting module. The module itself is not overly complex, and I will try to emphasise application more than plain old invocation.
Applications
It is important to observe that rate limiting is conceptually different from bandwidth throttling/limiting; a bandwidth-throttled connection will queue packets and limit the rate at which they are transmitted/received. Rate limiting will not do this; when you use rate limiting on, for example, incoming TCP connection attempts to your identd, and connections exceeding the specified limit will be denied; there is no queueing of packets.
I personally use rate limiting (rlim) on a standalone dialup machine; many of the ideas expressed in this article will, however, be useful on more involved setups.
Invocation and Syntax
Referencing and loading the module
It is assumed that the reader is familiar with the basic syntax for rule composition in iptables:
iptables -A TABLENAME [matches ...] -j TARGET
The matches ... part of the command contains the description of matches for the rule; it is in here that we load modules and give them arguments like this:
-m MODULENAME -option-one value1 ...-option-n valuen
The rate limiting module resides in /lib/modules/$KERNELVERSION /kernel/net/ipv4/netfilter/ and is called ipt_limit.o. This corresponds to a MODULENAME of limit.
Module arguments
The limit module takes two arguments, both optional:
-limit [X/[second/minute/hour/day]] \
-limit-burst [Y]
-limit, according to the man page, is the ``Maximum average matching rate''. What this means, in plain english, is the maximum number of matches per time period for other parameters in the rule that will be accepted for the target to kick in.
-limit-burst is the number of packets matching the rule's other match criteria to constitute one match for -limit above.
Don't worry if none of this makes sense; I get the feeling it's not really supposed to, at least not initially.
Using rate limiting
Hopefully, none of this will have made terribly much sense so far; I'd hate to think I was the only one with trouble understanding this nifty gadget. Let's take some examples - things will become clear rather faster than you expect.
Incoming traffic
One obvious application of rate limiting on incoming traffic is to block ping flooding. We can obviously block ping floods with a rule blocking incoming echo-request ICMP packets altogether, but this is inelegant; this is linux, remember? What we want to do, rather, is to allow such packets but only in small quantities. Have a look at the relevant rule:
iptables -A INPUT -p ICMP -icmp-type echo-request \
-m limit -limit 1/minute -limit-burst 5 -j ACCEPT
-limit 1/minute will do what it says; it will only match for a rate of incoming packets up to an average of 1 per minute. The operative word here is average. So, does this mean that the first ping request you get will be accepted, then none for a whole minute? Not quite.
-limit-burst 5 tells iptables to let 5 such packets in before permitting the rule to match; so, in one minute, we can have 5 ping requests popping through. So, -limit 1/minute permits a maximum of 1 packet per minute on average, but -limit-burst 5 permits 5 in one shot. Have we found a logical error in iptables? No you silly clod, remember, -limit stes a limit on average, whereas -limit-burst limits by number of packets in one go. What will happen then in our example?
The firewall will let the first 5 packets in in the first minute, thanks to -limit-burst 5; this means, however, that the packets/minute now is 5, so any further packets are blocked until packets/minute = 1, i.e. 5 minutes later. In the sixth minute, packets/minute will be 5/6 < 1, so another ping request will be let in. When the extra ping request is admitted, the ratio becomes 6/6 = 1 again, and packets are DROPped again until the next minute. Again, average is the operative word.
Now, if you want to make life really simple and decide that you really don't want to bother with averages and limit bursts, and that you want to deal with -limit on actual basis rather than average, you can do that too;
iptables -A INPUT -p ICMP -icmp-type echo-request \
-m limit -limit 1/minute -limit-burst 1 -j ACCEPT
There; one match per minute is all you're getting, no more. Though it must be said, I hope you don't use this if you're admining a large site. One connection per minute is beyond paranoid. Let's loosen that rule up a bit.
iptables -A INPUT -p ICMP -icmp-type echo-request \
-m limit -limit 1/minute -limit-burst 2 -j ACCEPT
Now, like this, you get maybe 2 matches in the first minute, and maximum one for the rest of your uptime. This is still pathetic, but you should be beginning to get the broad idea here. -limit keeps tabs on the average, and -limit-burst regulates how big a bite you take out of the sandwich each time. A more reasonable set of figures for someone on dialup like me might look like this (YMMV):
iptables -A INPUT -p ICMP -icmp-type echo-request \
-m limit -limit 10/minute -limit-burst 20 -j ACCEPT
10 pings a minute is good and safe; a limit-burst of 20 is generous, and not enough to knock me down. More fool you, broadband-bestowed script-kiddies!
These same ideas can be applied to any other form of incoming traffic. I run an ident server; I only use it for IRC connections, so I don't expect more than 1 or two connections a minute:
iptables -A INPUT -p TCP -m state -state NEW \
-dport 113 -m limit -limit 1/minute -limit-burst 2 -j ACCEPT
Actually, we might even do this:
iptables -A INPUT -p TCP -m state -state NEW \
-m limit -limit 1/minute -limit-burst 2 -j ACCEPT
Same as the previous rule, only it's more generic; any old TCP connection attempt will match, not just ones to port 113. Of course, if you're running other servers, you might want to fiddle with those values.
Log Summarising
Rate limiting is also commonly used for summarising logging. Let's say I'm not only rate limiting connections to my ident server, but I'm logging those connections too:
iptables -A INPUT -p TCP -m state -state NEW \
-dport 113 -m limit -limit 1/minute -limit-burst 2 -j LOG
Now, I don't have to log all them connection attempts (successful and otherwise); I'm going to get at most a couple of syslog entries a minute. This can be nice when you're experiencing synflooding, or icmp flooding; you can put it on your outbound icmp traffic too to prevent becoming a participant in a distributed smurf attack too. Never know.
Outgoing traffic
You get the basic idea by now; the trick is to identify the expected and eccepted rates of traffic for the specific kind of packet you will be looking for, and you know how to adjust -limit and -limit-burst to deal with this. It's really no different for outgoing traffic, though it's more rare. Rate-limiting outbound traffic is usually done to limit the potential for attacks from your machine, whether from a malicious local user or whether because you've been cracked.
iptables -A OUTPUT -p ICMP -icmp-type echo-request \
-s ! $MY_IP -m limit -limit 10/second -limit-burst 30 \
-j LOG -log-prefix "Forged echo-request: "|
iptables -A OUTPUT -p ICMP -icmp-type echo-request \
-s ! $MY_IP -m limit -limit 10/second -limit-burst 30 \
-j ACCEPT
Same semantics, different chains. Common practise is, as above, to write two identical rules with a LOG target then a ACCEPT target for this type of malicious activity. In fact, it may be worth considering, on local systems with numerous (and potentially untrustworthy) users, to impose carefully selected and very precise outbound limits; having your resources used in inflicting cracker activity is almost as bad as being victim.
As ever, if the log entries become too numerous, you just delete the first rule.
Caveat Emptor
Rate limits vs. bandwidth allocation
Rate limiting, as we said earlier, is not bandwidth limiting or throttling. For a newbie like me, the difference is subtle; rate limiting simply reduces your exposure to what you would consider excessive quantities of certain types of packets. Bandwidth limiting is more a resource allocation technique.
As such, iptables won't queue packets with the limit module. You might want to use it to set a cieling on the number of connection attempts (as opposed to actual connections) to your web server, but you won't be using it to limit the amount of data an existing connection will make away with.
If it's bandwidth limiting you want to do, try Squid proxy; TLDP has a very nice Bandwidth limiting HOWTO.
The bigger picture
iptables is a splendid packet filtering tool, but it falls short in terms of identifying larger patterns. This is not a deficiency, it is what a packet filter does - filter packets. What this means is that you can't expect iptables with its modules such as limit to function as an IDS.
It may technically be possible to do so, with some truly horrendous scripts and perhaps a SQL database as a log target all jazzed up with funky triggers, but that is:
- Unproductive; you're reinventing the wheel, and
- Unnecessary.
To make a long story short, hammers are for nails and screwdrivers for screws. Don't build kludgy iptables scripts to act as rudimentary intrusion detection systems; it won't work all that well, and you will come quickly to appreciate that it doesn't take all that many rules before your packet filtering rules begin to munch appreciably on those precious CPU cycles.
Acknowledgements
Rusty Russell for his packet filtering HOWTO; Donald Knuth for TEX
Trackback URL for this post:
Tag Cloud
Popular content
All time:
- KDE 5.0 Available
- The iptables Rate-Limiting Module
- Cavalier Egyptian Attitudes to Trademarks
- Five tips to better variable naming practises
- New Windows!
- Software Requirements Specification: A Modern Look at How the Enterprise Determines What It Thinks It Needs
- pycurl CurlMulti mini-HOWTO
- UNJobs.org Screenscraper and RSS Generator
- My Resumé

Good article filled with nice jokes.
Enjoyed learning it!
Nice post
Hey, thanks a lot for this post.
I was having a hard time trying to figure out how iptables limit module should work, but that was before reading your post...
There isn't much information on this module around, al least not as instructive as yours!
regards,
Aécio