Apache: Limit the Number of Requests/Traffic per IP?
Solution 1:
This is my iptables solution for this kind of issue. Adjust --seconds
--hitcount
as you need, also iptables table.
iptables -A FORWARD -m state --state NEW -m recent --rcheck --seconds 600 --hitcount 5 --name ATACK --rsource -j REJECT --reject-with icmp-port-unreachable
iptables -A FORWARD -d 192.168.0.113/32 -o eth1 -p tcp -m tcp --dport 80 -m recent --set --name ATACK --rsource -j ACCEPT
Explained:
iptables
check if source IP is listed on /proc/net/ipt_recent/ATACK file for 5 or more times in 600 seconds interval and if it's a NEW request. If it is, do a reject; elseiptables
check if request is destinated to port 80. If so, print IP and timestamp to /proc/net/ipt_recent/ATACK and forward packet.
It's working fine for my needs.
Solution 2:
If you want a pure Apache solution bw_mod for Apache 2.0 and mod_bandwidth for Apache 1.3. They can throttle the bandwidth of your server to limit bandwidth usage.
There is also mod_limitipconn, which prevents one user from making lots of connections to your server. mod_cband is another option, but I have never used it.
If you don't want to mess with your Apache installation you can put a squid proxy in front of Apache. It gives you more control also over the throttling.
However, in most cases the problem is a few large objects when you want to limit bandwidth per IP, and you want to give a sane error message when a user pulls too much data and you block him. In that case it might be easier to write a PHP script and store the access information in a temporary table in a database.