iptables geoip match on debian lenny

The geoip iptables extension allows you to filter, nat or mangle packets based on the country’s source or destination. This does exactly what the geoip apache module does, or the regular geoip binary, but at the iptables level. I would not go into the details why you would want to use that, but there are many ‘positive’ ways it can be useful… For example myself I use it in a project where we want to serve customized content for different countries. Since this is a high traffic site running on many web servers behind a loadbalanced setup, we prefer to split this at the loadbalancer level and not at apache level, to simplify our setup. We serve customized content to the US based visitors, while for the other countries we serve another international site.

Now this has been working fine for a long time now, using the original geoip module and patch-o-matic-ng method of installation (similar to what is very well described here). Still, this is unmaintained, and starting with kernel 2.6.22 it is no longer working. There is a patch that will make it work with a newer kernel, but if you run iptables 1.4.x this will again fail and even if there are some manual walkarounds this is still not the best solution.

The solution is called Xtables-addons. Xtables-addons is the successor to patch-o-matic-ng. Likewise, it contains extensions that were not, or are not yet, accepted in the main kernel/iptables packages. Xtables-addons is different from patch-o-matic in that you do not have to patch or recompile the kernel, sometimes recompiling iptables is also not needed. The latest version 1.12 supports: iptables >= 1.4.1 and kernel-source >= 2.6.17.

The installation is very simple and requires only the following steps exemplified on a debian lenny machine (kernel 2.6.26 and iptables 1.4.2):

1. Install the needed dependencies: kernel headers and iptables dev:

aptitude install linux-headers-2.6.26-1-amd64 iptables-dev

libtext-csv-xs-perl will be also needed if you plan to update the database (normally you will want this to be able to update the db from time to time):

aptitude install libtext-csv-xs-perl

2. Download the xtables-addons package and the supplied database (or the sources to build your own):

wget http://switch.dl.sourceforge.net/sourceforge/xtables-addons/xtables-addons-1.12.tar.bz2
wget http://jengelh.medozas.de/files/geoip/geoip_iv0_database-20090201.tar.bz2

3. Configure and compile the package. There are several iptables modules included; you can leave them all enabled or choose to compile and install only the ones needed. For this edit the mconfig file and leave only the ones you want:

build_CHAOS=m
build_DELUDE=m
build_DHCPADDR=m
build_ECHO=
build_IPMARK=m
build_LOGMARK=m
build_SYSRQ=m
build_TARPIT=m
build_TEE=m
build_condition=m
build_fuzzy=m
build_geoip=m
build_ipp2p=m
build_ipset=m
build_length2=m
build_lscan=m
build_quota2=m

Compile and install:

./configure --with-xtlibdir=/lib/xtables
make
make install

this will add the iptables extension /lib/xtables/libxt_geoip.so and the kernel module in /lib/modules//extra/xt_geoip.ko

4. Now we have to put the geoip database files under the expected location (/var/geoip); this is hardcoded in the code, but you can change it if really needed and recompile. I would like to add that even if this uses the same geoip source (the free GeoLite Country database) as the original geoip iptables module, but the format has changed. You can either get the database from the source, or build your own with the supplied script. Once you have that copy the files to /var/geoip

wget http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
unzip GeoIPCountryCSV.zip
./runme.sh
cp -R var/geoip/ /var/

That’s it! All you have to do is use the module based on your needs. The syntax is the same as the original geoip iptables module:
[!] –src-cc, –source-country country[,country…] = Match packet coming from (one of) the specified country(ies)
[!] –dst-cc, –destination-country country[,country…] = Match packet going to (one of) the specified country(ies)
NOTE:  The country is inputed by its ISO3166 code.

We use something like this to mark and send each type of traffic to its own destination:

iptables -t mangle -A PREROUTING -p tcp -m geoip --src-cc US -d <IP> --dport 80 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p tcp -m geoip ! --src-cc US -d <IP> --dport 80 -j MARK --set-mark 2

I hope you found this article useful, and as me, are grateful that Xtables-addons project took over the patch-o-matic-ng broken modules and made them available on current distributions. Xtables-addons was also accepted in debian repository (in testing) and this will make it even simpler to install and use in the future.

comments powered by Disqus