Limiting HTTP Connections By IP
February 4, 2007
I run ftp.linux.ncsu.edu which is a FTP/HTTP mirror of Fedora, CentOS, and other things I find useful. Apparently, my HTTP side has been “discovered.” The pages day in and day out telling me my server was down quickly became annoying. Especially as this was not the server being down put being DoS’d by your average download accelerator. Like the FTP side I wanted to limit the mount of connections each IP could have so the next time I got out grep I wouldn’t find on IP connected 63 times to download an ISO.
Apache itself doesn’t do this without 3rd party modules. Looking more closely at my RHEL 3 server I find that the IPTables tool has the ‘iplimit’ module but the kernel isn’t built with that module. The kernel is built with the ‘recent’ NetFilter module, however the IPTables tool is not. Good grief, Red Hat. (I also noted that RHEL 4’s IPTables have the ‘connlimit’ module but that kernel does not have the matching module either.)
I decided to use the NetFilter tools and grabbed the IPTables source RPM from RHEL 4, rebuilt, and installed that on my server. Now, I can use the ‘recent’ match. I typed in the following rules:
- iptables -A INPUT -p tcp –dport 80 –tcp-flags FIN FIN -m recent –name httpusers –remove -j ACCEPT
- iptables -A INPUT -p tcp –dport 80 –syn -m recent –name httpusers –rcheck –seconds 120 –hitcount 5 -j REJECT
- iptables -A INPUT -p tcp –dport 80 –syn -m recent –name httpusers –set -j ACCEPT
These rules are very order specific. The first rule checks to see if a HTTP connection is closing and removes the IP from the list. The second rule checks to see if this is a new connection to the http port and looks to see if there are 5 other recorded SYN packets from this IP in the last 120 seconds. If this matches (more than 5 connections) the packet is rejected and the user informed with an ICMP packet. Finally, all new connections are recorded in the IP list.
Is this perfect? Far from it. I’d really like to have the ‘conntrack’ module built for the kernel to do this right. If one connection closes in the above example the connection counter is reset to 0. However, this should level the playing field against those script kiddies.