Country-based packet filtering with iptables

Posted by imagine on Tue 17 Apr 2007 at 17:59

Tags: ,

Bruteforce attacks shouldn't pose a real security risk to any server but are still annoying and clog up your logfiles. Many methods to block these break-in attempts exist, like BlockHosts, Fail2ban or rate-limiting incoming connections. However, on my search I also came across one tool for which I couldn't find an easy guide: geoip. geoip is a module for netfilter/iptables and allows you to filter packets based on the country they come from or go to. Following is a step-by-step guide on how to install geoip.

Obviously the module can also be used for other things than just blocking bruteforce attacks. For example for what the original author calls "racist routing", that is to prevent users from certain countries from accessing your webserver or whatever. But as always it's up to everyone individually what he uses it for.

First off let me say that I don't administrate servers for a living but only do this in my spare time, so be warned. If you find any errors or wrongdoings please correct them in the comments.

I'll use Debian 4.0 in this howto, but in principle it should work with most others GNU/Linux distribution too. I also tried it on Ubuntu 6.10, where it works with very minor changes. Of course you'll have to use something else than apt-get on non-Debian systems, but people who spend their time setting up iptables-rules will probably figure this out for themselves.
What we'll need for geoip to work is a new kernel module, a library for iptables and a file with the IP-to-country mapping. There will be no kernel recompilation.

1. Preparations

First get the sources of the kernel you use. If you use the standard kernel of Etch that currently is:

# apt-get install linux-source-2.6.18
apt-get will put a compressed archive containing the source code in /usr/src/, which we will extract:
# tar xjf /usr/src/linux-source-<VERSION>.tar.bz2 -C /usr/src/
Replace <VERSION> by the version number of your kernel, in Etch it's currently 2.6.18. Since the source code is about 300MB big, this will take some time.

Next get the source code of iptables. We won't recompile iptables, but we need the sources to build the necessary library. We'll create a temporary directory to work in:

# mkdir ~/geoip
# cd ~/geoip/
# apt-get source iptables
You must have the dpkg-dev package installed to use the last command.

Now only the geoip-files are missing:

# wget http://people.netfilter.org/peejix/patchlets/geoip.tar.gz
To apply them we need the netfilter tool patch-o-matic-ng from http://ftp.netfilter.org/pub/patch-o-matic-ng/snapshot/. If you use a very old kernel, you may have to pick an older version, but other than that the newest snapshot is fine. At the moment that is:
# wget http://ftp.netfilter.org/pub/patch-o-matic-ng/snapshot/patch-o-matic-ng-20070414.tar.bz2
Extract patch-o-matic-ng:
# tar xjf patch-o-matic-ng-20070414.tar.bz2
Then extract the geoip-files into a subfolder of the new patch-o-matic-ng-directory:
# tar xzf geoip.tar.gz -C patch-o-matic-ng-20070414/patchlets/

2. Patching

Patch the kernel and the iptables source code with patch-o-matic-ng:

# cd patch-o-matic-ng-20070407/
# KERNEL_DIR=/usr/src/linux-source-<VERSION>/ IPTABLES_DIR=~/geoip/iptables-<VERSION>/iptables/ ./runme geoip
Again, replace both <VERSION>-tags with the appropriate versions of your kernel and iptables. At the moment of this writing the version of iptables in Etch is 1.3.6.0debian1.
If everything's right, patch-o-matic-ng will present you an explanation of the geoip-patch and ask if you want to apply it. Answer y, patch-o-matic-ng will then print a success message and exit.

3. Building and installing the geoip kernel module

To build, we need the build-essential package or anything similar which will provide us with gcc, make, etc:

# apt-get install build-essential
Because we need a configuration file for the kernel, we will just use the configuration of the currently running kernel:
# cd /usr/src/linux-source-<VERSION>/
# make oldconfig
During the configuation process make will ask:
geoip match support (IP_NF_MATCH_GEOIP) [N/m/?] (NEW)
Type m to use it as a module.

Prepare the build process of the kernel modules:

# make modules_prepare
Then compile the modules. Unfortunately I don't know how to compile only the geoip module, so we'll have to compile all netfilter modules until someone has a better idea:
# make -C $(pwd) M=net/ipv4/netfilter/ modules

If all went well, ipt_geoip.ko should have been created in net/ipv4/netfilter/. We copy it to the other modules of our current kernel:

# cp net/ipv4/netfilter/ipt_geoip.ko /lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/
Activate the new module:
# depmod
# modprobe ipt_geoip
# echo "ipt_geoip" >> /etc/modules

4. Building and installing the iptables library

Build the shared object:

# cd ~/geoip/iptables-<VERSION>/iptables/
make KERNEL_DIR=/usr/src/linux-source-<VERSION>/  extensions/libipt_geoip.so
As before, substitute <VERSION> with the version of iptables and the kernel.

Copy the created file to the other iptables libraries:

cp extensions/libipt_geoip.so /lib/iptables/

5. Creating the IP-country mapping

We will use the freely available database from MaxMind. It has a claimed accuracy of 98% and is updated once a month. If that's not enough, you can buy a more accurate version from MaxMind.
Download the file and extract it:

# cd ~/geoip/
# wget http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
# unzip GeoIPCountryCSV.zip
As you can check with an editor, the extracted file is a list of comma separated values. Since seeking through such a list is pretty slow, we will convert the file into binary format using csv2bin, a tool also supplied by the author of geoip.
# wget http://people.netfilter.org/peejix/geoip/tools/csv2bin-20041103.tar.gz
# tar xzf csv2bin-20041103.tar.gz
# cd csv2bin/
# make
# ./csv2bin ../GeoIPCountryWhois.csv
That will create two files, geoipdb.bin and geoipdb.idx, which the geoip module expects in /var/geoip.
# mkdir /var/geoip
# mv geoipdb.* /var/geoip/

6. Using iptables with geoip support

That was it, you can now filter packets on a country basis:

# # Block access to your SSH daemon except from Afghanistan
# iptables -A INPUT -p tcp --dport 22 -m geoip ! --src-cc AF -j REJECT
# # Block pinging hosts in France, Italy, Spain
# iptables -A OUTPUT -p icmp -m geoip --dst-cc FR,IT,ES -j REJECT
# # Help
# iptables -m geoip --help

If you want, you can delete the ~/geoip/ and /usr/src/linux-source-<VERSION> directories now.

 

 


Posted by fsateler (200.83.xx.xx) on Tue 17 Apr 2007 at 20:43
[ View Weblogs ]
To actually use the configuration used by your currently running kernel, in debian you should do (right behore make oldconfig)
cp /boot/config-$(uname -r) .config
--------
Felipe Sateler

[ Parent | Reply to this comment ]

Posted by imagine (87.177.xx.xx) on Fri 20 Apr 2007 at 22:59
Thanks, but is this recommended?
make oldconfig created an exact copy of /boot/config-$(uname -r) (except the timestamp of course) also without copying the file first. So I wonder if this step can be omitted.

[ Parent | Reply to this comment ]

Posted by fsateler (200.83.xx.xx) on Sat 21 Apr 2007 at 19:41
[ View Weblogs ]
Maybe the Debian kernels come patched to do that, I hadn't noticed. Using a vanilla kernel won't copy it AFAIK.
--------
Felipe Sateler

[ Parent | Reply to this comment ]

Posted by Anonymous (83.161.xx.xx) on Wed 18 Apr 2007 at 01:04
Racist routing IS a problem though, and it DOES get encouraged by such modules.
You don't block a whole country because of a bruteforce attack. However, here
are some situations where you can encounter it:

http://news.netcraft.com/archives/2004/10/26/bush_campaign_web_si te_rejects_nonus_visitors.html
http://newsvote.bbc.co.uk/2/hi/technology/3958665.stm

I can't think of anything positive to do with this technology.

[ Parent | Reply to this comment ]

Posted by Nilshar (82.238.xx.xx) on Wed 18 Apr 2007 at 09:30
[ View Weblogs ]
Some Swiss bank do that too.

[ Parent | Reply to this comment ]

Posted by raf (131.130.xx.xx) on Wed 18 Apr 2007 at 10:53

and now to something completely non-techie:

speaking of "racist routing" seems to me to be multi-dimensional rubbish. the article presents a technology, that gives you the ability to alter the behaviour of your firewall based on certan ip-ranges. paralleling ip-ranges with countries, and countries with nationalities, or countries with "races" (a concept without a scientific basis, but a long discriminatory history) is politically speaking simply non-sense. i'm definitely unable to think of any explanatory value of the word "race" in this context.

what's next? elitist routing, class-based routing, os-based routing (... -m geoip ! --src-os un*x -j REJECT)

sorry, but also technical articles should be based on a certain amount of critical scrutiny.

raf

[ Parent | Reply to this comment ]

Posted by Anonymous (85.130.xx.xx) on Wed 18 Apr 2007 at 11:14
It's not the technology that makes decisions on whether or why to filter certain "races", as you alluded ;) Here comes the infamous saying "Guns don't kill people. People kill people"

[ Parent | Reply to this comment ]

Posted by legooolas (87.237.xx.xx) on Wed 18 Apr 2007 at 13:33
I can think of a positive thing: How about if you only tend to login to a machine from a particular country, but from various IPs in that country?
This way, you can limit say ssh to only allow IPs in the UK.
That seems pretty useful to me.

[ Parent | Reply to this comment ]

Posted by Anonymous (84.56.xx.xx) on Wed 18 Apr 2007 at 16:26
Yeah, that's completly true!

I'm using atm a /etc/hosts.deny which blocks the whole Asian-IP's... and why?
Because I'll NEVER login from this part of this world and thus no one else should.

[ Parent | Reply to this comment ]

Posted by Anonymous (203.91.xx.xx) on Fri 20 Apr 2007 at 01:38
You know you want to shell into your machine, you know that you arent in an over seas country - so you block ssh to non-local ip addresses.

Similarly, you make have an 'intranet' for your roving employees. Rather than solving it with everyones blanket soltuion - ie a VPN solution (massive overkill), you can just block http/https from non-local ip addresses.

You could even block your VPN ports from non-local.

[ Parent | Reply to this comment ]

Posted by ericrox (24.141.xx.xx) on Fri 20 Apr 2007 at 01:47
[ View Weblogs ]
I can completly see this a great option for a non-global company that wants to limit remote access or attempt to minimize spam. RBL's, Reverse lookups, geographic filtering all seem like a good use of technology to me to avoid spam. Locking down remote access also seems standard. Restricting specific connections to partner or vendor subnets isn't discrimination against the other subnets, just good security.

I do like the term "rascist routing" sounds real dramatic..

[ Parent | Reply to this comment ]

Posted by imagine (87.177.xx.xx) on Fri 20 Apr 2007 at 23:37
Yes, geoip can be used to mitigate bruteforce attacks and it can also be used to discriminate users from certain countries. What you wrote was all correct, but for me, it's not the answer to the question which really matters.
In my opinion it's not about right or wrong, used or abused, problem or not, not if geoip is good or bad, but more about your point of view, your personal belief or more general your philosophy of life.
I don't think censorship or the withholding of knowledge creates a better or safer world. I believe in full disclosure, not only of security issues but of any non-personal information. But there were already so many articles written for and against it, that everything I could write here would just be a repetition, so I'm not going to dig into it any further.

[ Parent | Reply to this comment ]

Posted by Anonymous (67.188.xx.xx) on Sun 17 Feb 2008 at 19:33
There are three races on this planet: Caucasoid, Negroid and Mongloid, and from what I read in this article, nothing targets any of them.
Iptables can't filter races, radio stations, tv channels or anything else that isn't an IP packet.
Can't think of anything positive to do with this technology? Not surprising considering your opening statement.

[ Parent | Reply to this comment ]

Posted by Anonymous (98.211.xx.xx) on Wed 24 Dec 2008 at 11:22
Racist routing? Yeah, sure, let's call it that and here is why I want to be "racist" with my iptables. I work for a credit card firm. I _CANNOT_ do business with any country in Asia and the only countries in APNIC that I can do business with are Australia and New Zealand. Asia is well known for hacks, worms and spam. Russia too. India is our largest source of fraudulent sign ups. Why the fsck would I want to allow people from Asia, India (part of apnic) and Russia send a single packet to our site and increase liklyhood of spam, hacks and worms when I cannot perform legitimate business with them in the first place so yeah, call me a "racist" network admin all you want but decreasing our odds of hacks/worms/spam with anyone I cannot legitimately do business with seems like a damned good idea to me.

[ Parent | Reply to this comment ]

Posted by dwulff (71.85.xx.xx) on Mon 27 Aug 2012 at 22:56
It only makes sense that if a country has no business value, why be open to attack? We use an in-line appliance to block countries from our network by TechGuard. It processes equivalent to 12,000 IP ranges with no impact on latency or TCP connections. We cut the noise with a click on a map for ingress and egress traffic. Nothing racist about it.

[ Parent | Reply to this comment ]

Posted by Anonymous (80.101.xx.xx) on Tue 9 Nov 2010 at 18:57
This is just what I need to filter out everything from my development server except from me and the countries I work in.

There's nothing racist about it. I think you're confusing this with the ipt_race module that works like this:

# Block access to your SSH daemon except from indians
iptables -A INPUT -p tcp --dport 22 -m race ! --src-race indian -j REJECT
# Block pinging negros and hispanics
iptables -A OUTPUT -p icmp -m race --dst-race negro,hispanic -j REJECT
# Block access to your httpd daemon from overly politically correct caucasian
# twits (not really a race, but supported as they are exceptionally annoying
# and seem to pop up everywhere on the internet with their silly remarks)
iptables -A INPUT -p tcp --dport 80 -m race --src-race opcct -j REJECT
# Help
iptables -m race --help

[ Parent | Reply to this comment ]

Posted by Anonymous (220.239.xx.xx) on Thu 19 Apr 2007 at 11:02

The most effective method I have found for preventing these brute force attacks is to drop connections after a certain number of attempts within a certain amount of time (from a given IP address).

It seems that the attack machines assume that the host is no longer reachable and move onto other potential targets, so this method is better than rate limiting.

I think this has been covered in Debian Administration before, but I couldn't find the article, so here are the lines that I add to my /etc/network/interfaces file:

  up /sbin/iptables -A INPUT -m state --state NEW -p tcp --dport 22 -m recent --update --seconds 300 --hitcount 5 -j DROP
  up /sbin/iptables -A INPUT -m state --state NEW -p tcp --dport 22 -m recent --set -j ACCEPT
  down /sbin/iptables -F INPUT

This will allow 5 connections within 5 minutes (300s). Subsequent connections will be dropped.

[ Parent | Reply to this comment ]

Posted by imagine (87.177.xx.xx) on Fri 20 Apr 2007 at 23:02

> "I think this has been covered in Debian Administration before, but I couldn't find the article" It's the third link at the beginning of the article :)

[ Parent | Reply to this comment ]

Posted by ajt (85.211.xx.xx) on Sat 21 Apr 2007 at 00:13
[ View Weblogs ]
Rate limiting is good, except it doesn't work* in Sarge. I've not tested it in Etch, but I believe the bug in the kernel has been fixed.

* It does for a while, but after n days of continual use it stops working. See this thread here http://www.debian-administration.org/articles/187#comment_22

--
"It's Not Magic, It's Work"
Adam

[ Parent | Reply to this comment ]

Posted by Anonymous (12.4.xx.xx) on Tue 5 Jun 2007 at 17:29
> The most effective method I have found for preventing these brute force attacks
> is to drop connections after a certain number of attempts within a certain
> amount of time (from a given IP address).

Then I send fake packets pretending to be you and you are locked out your own box.

[ Parent | Reply to this comment ]

Posted by Anonymous (67.88.xx.xx) on Fri 20 Apr 2007 at 01:04
This is great thanks.

There are plenty of reasons where this can be used. Linux = Freedom and can't that mean I am free to block anybody I want.

If I am in a business and I only do business in the U.S. what would be wrong with doing this. Worse thing happens is somebody is not able to see a service I provide from a country I cannot provide it for.

Now here is my word of warning. I was blocking very large IP blocks at one time when our SPAM filter could not keep up. While it worked, I also got the complaint when employee's had family or children (exchange students) in countries and their email would not go through.

Thanks again for the great article, I did not know this existed.

[ Parent | Reply to this comment ]

Posted by Anonymous (89.102.xx.xx) on Sat 12 May 2007 at 05:44
proxy

[ Parent | Reply to this comment ]

Posted by Anonymous (24.172.xx.xx) on Wed 23 May 2007 at 17:25
Forgive the noob question...

Isn't it a bad thing to leave the sources on a production web server? I'd like to use this, but I'm leary of recompiling the sources, leave the sources on the server, etc.

Is it safe to do on a prod box?

[ Parent | Reply to this comment ]

Posted by imagine (87.177.xx.xx) on Thu 24 May 2007 at 00:04

Which sources do you mean?
From the arcticle: "If you want, you can delete the ~/geoip/ and /usr/src/linux-source-<VERSION> directories now."

However if you're unexperienced with compiling software, I wouldn't recommand to try this tutorial out on a production machine the first time.

[ Parent | Reply to this comment ]

Posted by Anonymous (91.124.xx.xx) on Mon 11 Jun 2007 at 20:16
# modprobe ipt_geoip

FATAL: Error inserting ipt_geoip (/lib/modules/2.6.9-55.ELsmp/kernel/net/ipv4/netfilter/ipt_geoip. ko): Invalid module format

[ Parent | Reply to this comment ]

Posted by Anonymous (195.144.xx.xx) on Mon 19 Nov 2007 at 08:02
Entering directory `/usr/src/kernels/2.6.11-1.1369_FC4-i686'
make[1]: *** No rule to make target `net/ipv4/netfilter/ip_conntrack_standalone.s', needed by `net/ipv4/netfilter/ip_conntrack_standalone.o'. Stop.
make: *** [_module_net/ipv4/netfilter] Error 2
make: Leaving directory `/usr/src/kernels/2.6.11-1.1369_FC4-i686'

..I need help! I can't compile this module! I've got this error on two Fedora's yet.

[ Parent | Reply to this comment ]

Posted by Anonymous (200.69.xx.xx) on Fri 23 Nov 2007 at 12:32
It is so useful !!! And it workss so well !!! Thank you !!!

[ Parent | Reply to this comment ]

Posted by Anonymous (80.52.xx.xx) on Tue 15 Jan 2008 at 14:17
Yes, many thanks :-).

Just instead of copying libipt_geoip.so to /lib/iptables/
i had to copy it to /usr/local/lib/iptables/
(Debian Etch 4.0)

Best regards,
k.

[ Parent | Reply to this comment ]

Posted by Anonymous (189.8.xx.xx) on Thu 11 Dec 2008 at 17:08
When im building the iptables library (module works fine):

extensions/libipt_geoip_sh.o: In function `_init':
libipt_geoip.c:(.text+0x10): multiple definition of `_init'
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crti.o:(.init+0x0): first defined here
collect2: ld returned 1 exit status

RedHat Linux 5 box, im trying to figure out how to fix this... If anyone has any idea, pleease :)

[ Parent | Reply to this comment ]

Posted by Anonymous (175.143.xx.xx) on Mon 8 Sep 2014 at 04:24
You will need to have a regular update list of IP address by country. You can get the free list from IP2Location Free Tools, google "ip2location firewall" for more information.

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

What do you use for configuration management?








( 279 votes ~ 1 comments )