Next Previous Contents

7. Block those countries

Now it's time to move on and get our system so it can block the countries we don't want or don't need. There's nothing personal intended here, but there comes a time when we just can't take it anymore and must take some drastic action. It's just too bad that there are some bad people out there spoiling the internet for everyone else.

Some will say, "a few bad apples spoils it for everyone". Well, it's not a few bad apples. There are thousands if not millions of bad apples in this case. What do we do about them? BLOCK 'EM!

7.1 Get IPTABLES running

Now, before going any further, you must make sure that iptables is working on your Linux system, or other Unix type of system. For this discussion, I'll make reference to Linux because that's what I'm using. If you use something different and it still has iptables, then you can adapt to what I will talk about.

The first thing to do is see if you get any kind of response from iptables. Simply typing the command all by itself will reveal if it's available on your system. From a command prompt type:


You should get a message saying something like 'type iptables -h for more information'. If you get a message that says "command not found", it might be that you will need to be logged in as 'root' rather than a normal user.

Knowing that iptables is working, you must also make sure that the iprange module is supported by your version of the kernel and iptables. Enter an iptables command that uses iprange and see if it either accepts it or responds with an error message. From a command prompt do:

iptables -t nat -I PREROUTING -m iprange --src-range -j DROP

Newer kernels require a slightly different version of this command. If you have a newer kernel, you might get an error due to "DROP" being included in the command. If so, try this variation:

iptables -t nat -I PREROUTING -m iprange --src-range -j DNAT --to 0

If you get a command prompt back with no error message, then you are in luck. Plus, you have just blocked out over 2 million IP addresses in China.

(Sorry China, but I figured this was a good example to use since I'm blocking China on my system)

If you want to undo this block, just issue the same command but replace the -I part with -D. This stuff is really quite simple once you understand how to do it and provided someone explains it in an easy to understand manner. Hopefully, I'm doing just that.

If you get an error message when entering the iptables command example above, it most likely means that your kernel doesn't support the iprange module or maybe the module just isn't loaded in. At this point, you will have to figure out how to get Linux to accept iprange in the iptables command. Generally, the error message when it isn't working is something like "no chain/target/match by that name" or something like that. The error might be something different if iprange is in the kernel but just not working right. This was my case. It didn't work for me initially and I had to upgrade to the 2.6.x kernel. From what I could tell, iprange was installed on my system, but for some reason the coding wasn't right and it didn't work. I found out it also didn't work for many other people. A newer kernel is what was needed. Trust me, it's worth the effort to upgrade your system to be able to use this functionality.

For the rest of this documentation, we will assume that iptables is working for you and it is also accepting the iprange match in the command.

7.2 Setup for IPTABLES

The next thing to do is to get iptables to generate a default ruleset file for us. This is needed because it will get included into the new file you will be creating. This allows you to keep all of your existing iptables rules while adding the additional country blocking rules to it.

We don't want the standard rules file that can be launched as a script. We want the one that iptables can create for us. This will match the same format as the one that countryiptables.php generates and is able to be loaded into the running kernel much faster. So, the next step is to do the following from a command prompt:

iptables-save > defaultrules

Note: you must name it exactly as "defaultrules" or the program won't find it. You'll have to know if it was found or not. That's explained later on.

A new file named 'defaultrules' will be created in the current directory. It's easiest if you issued this command right from your country directory. If not, be sure to copy the file to the directory. This file contains all of your current rules that iptables is now using.

Actually, it's OK to skip this part and not create the defaultrules file. If you skip it, then there is just a slightly different command to use later on when we install the country blocking rules into the kernel. But, it's best to do this part so you have a complete new rules file with your old rules and the new rules. It's your choice.

7.3 Pick your countries

Now you get to decide who you like and who you don't like. So, point your browser to the countryiptables.php file:

You'll get a page displayed showing some buttons and all the available countries you can pick from. The first time you run this program, none of the countries will be selected. This means that you are not choosing to block any country yet.

Go through the list and pick the countries you want to block. There is a checkbox next to each country name.

You'll notice 4 buttons displayed in a row. Here's the description of each one:

Clear All - clicking on this button will clear all the country selections. Use this button to clear all of your existing selections when you want to pick just one or two countries.

Select All - clicking on this button will select all of the countries. Use this and then deselect a country or two. You might want to block out the whole entire world all except for a few select countries.

Save As Defaults - when you are happy with your selections, click on this button to save your settings. Everytime you load this program, you'll have the same countries selected for further work.

Load Default Selections - click on this if you change your mind or need to revert back to your default country selections.

By default, this program will create iptables rules that will block the countries coming in on the "eth0" ethernet interface. You can keep this selection or select a different one such as "eth1" if that is the interface that is connected to the internet where all the incoming packets are arriving. Near the top, you'll see where you can select eth0, eth1, or eth2. You can also type in something different if your Linux distrubution uses a different naming convention.

Whichever interface you choose is the one where incoming packets will be blocked. After all, if this is a firewall machine, it will have at least two ethernet interfaces and there's no point in blocking countries coming in from your local network. On the other hand, you might have one interface connected to your local network and two connected to the internet. In that case, you can click on the checkbox that says "All except above interface". In that case, you will be blocking all the interfaces except for the one that you have selected.

If you're not sure what the name is of your interface, enter the following command from a command prompt:


If the information scrolls by and off the screen, send the info to the 'more' or the 'less' command like this:

ifconfig | less

Now you can read the info and find out what names are given for your ethernet interfaces (cards). You'll also see other helpful info such as the local IP address assigned to the card, the number of ingoing and outgoing packets, etc.

There are two selections to choose from depending on if you have a newer kernel or an older kernel. You can determine which one is right for you by trying the test command that is given earlier in these instructions. The iptables rules that will be created will end either with "DROP" for older kernels or "DNAT --to 0" for newer kernels.

7.4 Build the IPTABLES file

Now that you have all of the countries selected that you want to block, it's time to build a file that will be installed into the Linux kernel.

It's as simple as typing in a filename and clicking a button. In the text box near the top of the page, enter a filename to use for this file that is about to be created. You'll notice that a default filename has already been entered for you. You can change it if you'd like. Maybe you want to create several different country blocking files or maybe different files for different server machines.

Once you've chosen the filename, click on "Create File" and go get another Coke. Or get a Vernors or whatever you like. Actually, this process will go quite quickly on a fast server. A slow server might take 3-6 minutes. But it also depends on how many countries you have chosen and which countries they are. If you want to watch the progress of this file being created, go to a command prompt and get into the directory where your files are located and enter the following:

tail -f badiptlist.txt

...or whatever you entered for the filename to be created.

You'll be able to see the big list of iptables rules being created. You will be amazed at how big this list can be. On my system it contains over 10,000 lines of rules. My system created a file that is about 1MB in size.

You can load this file into a text editor and manually edit it if you'd like. This is where you can remove a block on a particular region and not actually block an entire country. Use the iptocountry.php program to help you pick and choose.

Anyway, once the file is finished being created, we have to go and install it into the Linux kernel. But this is easy, I'll show you how. You can do it right from the same directory unless your intentions are to use it on a different machine. In that case, copy it over to the intended computer.

Now, there are two versions of the command that we will use. It all depends on if you used a defaultrules file as described earlier or if you omitted that part. Let's assume you created a defaultrules file. If you failed to enter the correct name when the file was created, countryiptables.php didn't find it when it created the badiptlist.txt file. We need to know if it found it or not. The easiest way to find out is by looking at the beginning and/or ending of the badiptlist.txt file. Do this:

less badiptlist.txt

(or "more badiptlist.txt" or just load the file into a text editor of your choice)

Look for the line of text that says "*nat" at the beginning of the line. Most likely it will be the very first line. If it is followed by three lines that each begin with a colon ':', then your defaultrules file was found OK.

7.5 Load the kernel with the new rules

Now, let's load the new rule sets into the kernal. You will probably have to be logged in with root privileges to do this operation. If you can't do that, you'll have to get someone who can.

With the defaultrules file in use, do the following at a command prompt:

iptables-restore < badiptlist.txt

If you did not use the defaultrules file, do this instead:

iptables-restore -n < badiptlist.txt

The -n parameter tells iptables not to flush the existing rules. This will keep the rules that are already in the kernel and install the additional ones from our newly created badiptlist.txt file. You can also do this later on if you want to add one or two countries to the blocking rules that you are installing now. If so, just make sure the defaultrules file isn't accessible. Or go ahead and create a whole new complete file and install the whole thing without the -n parameter. Either way works.

On the other hand, with the defaultrules file included, then it's OK to have the existing rules flushed because we will be reinstalling them from the badiptlist.txt file.

On a fast server with some memory, this process of installing the badiptlist.txt file into the kernel will only take a few seconds, even if the file is huge. However, on a slow server or one that has very little memory, it will take much longer. My firewall machine is a 166mhz system with 256MB of ram. It takes in the 10000+ lines in about 5 seconds. But my DNS server is a 486-66 with only 36MB of memory. The first time I installed the 10000+ lines of rules, I thought something went wrong. It took over 15 minutes. So... be patient depending on your individual setup. I suspect the big difference is the amount of memory in the machine and not the processor speed. Amazingly, the old 486 took it all in and is handling it nicely. I had to install this on the DNS machine because that machine doesn't sit behind the firewall machine. As for the rest of the machines on my local network, they didn't need this installed because they all sit behind the firewall machine. The firewall machine does all the work of blocking for those machines.

7.6 Save for the next reboot

Now you think that maybe you have to write a script or something so that these new rules get installed into the kernal each time your machine reboots. Not so. You can have iptables save the newly installed rules for you and automatically use them at every reboot. Your system might vary from how I'll describe mine, and if so, you'll have to do a little digging to figure it out. But I'm sure it's similar. On my Debian system, I just do the following from a command prompt as root:

/etc/init.d/iptables save active

Iptables will then save the rules from the kernel to a file that will be loaded during bootup. This part goes quickly, even on the slow (and low memory) 486. And it pulls the data in during bootup quickly as well, even on the slow 486.

If you're Linux distribution also uses the /etc/init.d/ method during bootup, then you can probably do the above, however, your system might be different. If so, read on. (otherwise, skip to the next section)

As an example, on a recent SUSE Linux system, I've done the following:

First create a directory where the 'active' file should reside. A good place might be in the /var/lib/iptables/ if that exists on your system. If not, you can create that directory. You'll have to be logged in as 'root' to do this. Do the following two commands from a command prompt (actually don't do the first one if the /var/lib/iptables/ directory already exists):

mkdir /var/lib/iptables
iptables-save > /var/lib/iptables/active

You have now saved the entire set of rules from the kernel into a file called 'active' in the /var/lib/iptables/ directory. Next, we need a way for this to be loaded in by default whenever the machine has to be rebooted. There is a file you can edit to add anything you'd like performed during bootup. It's called 'boot.local' and can be found in the /etc/rc.d/ directory. Using a text editor, add the following line in this file:

iptables-restore /var/lib/iptables/active

Check your particular Linux distribution to find out where you can add something like the above to be performed during bootup. They don't all do things the same exact way. I've described how you can do this with Debian and SUSE. Other systems might use one of these two methods, while others will use something different. Do a little digging, I'm sure you can figure it out.

Next Previous Contents