For various reasons over the past year or so I have been wondering what is the best way to block access to my server. I have used .htaccess files in the past, but they have two drawbacks. First, they have to be processed by apache everytime someone requests a page. Second, they have to be set up for every domain. It would be much more efficient to drop traffic before it even gets to apache.
That is what the iptables command does, and I think I finally got it figured out.
I am not a server administrator. I manage a server, but it’s not completely in my comfort zone. I would rather be writing code or tuning a database. But since I have a dedicated box and I don’t want to pay the extra cost for a managed server, that leaves me to do the job.
So, what exactly does iptables do, and why am I posting about it?
A few days ago I posted about two specific spammers. One was from Hong Kong and was responsible for nearly two thousand failed registration attempts on only one board on my server. The other was from Germany. Further research showed that it was not just me they were annoying. They get mentioned in posts on webhostingtalk and sitepoint and other sites as well.
I also checked to see if any legitimate traffic was coming from those IP ranges, and it turned out that there wasn’t any. So I decided to block them. I already knew how to use .htaccess to deny access from an IP address, but I also knew that isn’t the most efficent method. So I did some searching and learned about
iptables and how it works.
It’s the Network
I think everyone knows that the Internet runs on packets of information. Each packet has an IP address attached to it. It is the return address used to pass the requested information (a web page, for example) back to the requester. There’s more to it than that, of course, but that’s the very basic explanation.
All traffic that comes into (or leaves out of) my server has an IP address attached to it. The
iptables command lets me decide what to do – at a very low level – with that traffic if a specific IP address (or range) is attached to the packet. That means that the operating system is going to take a look at the packet before it even gets to apache, which is what I want.
To block traffic from a specific IP address I type the following command as root:
iptables -A INPUT -s 18.104.22.168/24 -j DROP
iptables is the command name, of course. The option
-A is going to add a row to my IP table list. The option
-s specifies the source address, in this case it is a range of values from .0 to .255 for the provided IP. The argument
-j is short for “jump” and tells the operating system what to do with the packet if it matches that pattern. In this case the destination is the keyword
DROP. I probably don’t have to explain what that does.
I typed this command at a shell prompt, and then I also added another entry to block my (not-so-much) friends from Hong Kong.
iptables -A INPUT -s 22.214.171.124/24 -j DROP
In both cases I use the mask /24 which will make every specific IP address from that range.
Review The Configuration
There are a couple of ways to see if these commands worked. First, the
iptables -L command will echo back the rules I just created, like this:
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- 126.96.36.199/24 anywhere
DROP all -- h-188.8.131.52.keyweb.de/24 anywhere
This shows that I am dropping all traffic from the two IP masks on all protocols. They can’t view my web sites, they can’t send me email, then can’t try to telnet/ssh to my box. They’re ignored. Another option for reviewing the configuration is the
iptables-save command. That’s really just one word, not a command with a parameter. That command is used to dump out the contents of the iptables cache in a format that you can save to a text file, and it looks like this:
# Generated by iptables-save v1.2.8 on Thu Mar 27 13:43:57 2008
:INPUT ACCEPT [305379:40546551]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [363012:312935976]
:acctboth - [0:0]
-A INPUT -s 184.108.40.206/255.255.255.0 -j DROP
-A INPUT -s 220.127.116.11/255.255.255.0 -j DROP
# Completed on Thu Mar 27 13:43:57 2008
This is the format of the
/etc/sysconfig/iptables file as well. I have set up iptables to save the rules when it is stopped or restarted so I don’t have to put them in again each time. While you’re testing, it might be a good idea to not save, just in case you lock yourself out of your own server. Once you’re confident that everything is working, then make the changes permanent. I made the changes “stick” by altering the iptables configuration file located in
/etc/sysconf/iptables-config so that it includes the following lines:
Then I restarted the service using
service iptables restart and verified the iptables configuration using the
iptables -L command mentioned earlier. Everything seems to be set up; I hope it is all working.
I have some more testing to do. But I hope this will eliminate some of the traffic that moves through my box, leaving more resources available for legitimate users. If it works, in a few months I should be able to check and not find any traces of activity from these IP address ranges anywhere in my server logs.
I found a lot of information on the web about iptables. Quite a bit of it was really bad or incomplete. Here are a few links that helped me get up and running.