Ubuntu, Iptables and GeoIP

Xtables-addons (http://xtables-addons.sourceforge.net/) is a set of extensions for iptables that adds some interesting features. In particular, geoip matching on sources and destinations IP.

Installation is quite easy:

apt-get install xtables-addons-common xtables-addons-dkms libnet-cidr-lite-perl libtext-csv-perl

Next step is to download GeoIP informations and build the data-files.

The operation can be done by hand:

root@host01:~# /usr/lib/xtables-addons/xt_geoip_dl
root@host01:~# cd GeoLite2-Country*
root@host01:~# /usr/lib/xtables-addons/xt_geoip_build
root@host01:~# mv *.iv? /usr/share/xt_geoip
root@host01:~# cd ..
root@host01:~# rm GeoLite2-Country*

Or with a script, that can be scheduled as cron task:

 root@host01:~#  echo "0  1    * * 0   root    /usr/local/bin/GeoLite2-Country-Update.sh" >> /etc/crontab
#!/bin/bash
#
# /usr/local/bin/GeoLite2-Country-Update.sh
#
#-------------------------------------------------------------------------------

tmpDir=`mktemp -d`
xtGeoipDir="/usr/share/xt_geoip"
xt_geoip_dl="/usr/lib/xtables-addons/xt_geoip_dl"
xt_geoip_build="/usr/lib/xtables-addons/xt_geoip_build"
this=`basename $0`

[ -d "$xtGeoipDir" ] || mkdir $xtGeoipDir

logger "$0: workdir $tmpDir"
cd $tmpDir
logger "$0: downloading geoip db updates"
$xt_geoip_dl >/dev/null 2>&1

if [ -d GeoLite2-Country* ]
then
        cd GeoLite2-Country*
        logger "$0: building geoip db"
        $xt_geoip_build >/dev/null 2>&1
        logger "$0: updating geoip db in $xtGeoipDir"
        mv *.iv? $xtGeoipDir
else
        logger "$0: download failed"
fi

rm -rf $tmpDir

#EOF#

Following, an example firewall configuration script. The purpose is to log and drop all incoming ssh connections not in a list of trusted networks and outside my country (Yes. I live in Italy).

#!/bin/bash

# Trusted Networks
trustedNetworks="10.1.1.0/24 10.10.10.0/24 10.20.30.0/24"

iptables -F
iptables -X
iptables -N LOG_N_DROP

iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT

# Accept incoming connections from $trustedNetworks
for src in $trustedNetworks
do
 iptables -A INPUT -p tcp -s $src --dport 22 -j ACCEPT
done

# Accept connections from the country I live in.
iptables -A INPUT -p tcp --dport 22 -m geoip --src-cc IT -j ACCEPT
# For connection outside my country, jump to LOG_N_DROP chain.
iptables -A INPUT -p tcp --dport 22 -m geoip ! --src-cc IT -j LOG_N_DROP

# Log all traffic entering the LOG_N_DROP chain and drop it.
iptables -A LOG_N_DROP -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
iptables -A LOG_N_DROP -j DROP

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

Note: geoip accepts ISO 3166-1 alpha-2 country codes, eg.: IT, DE, FR, US, …

root@host01:~# man xtables-addons
[ ... ]
   geoip
       Match a packet by its source or destination country.

       [!] --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 ISO-3166 code.

       The extra files you will need is the binary database files. They are generated from a country-subnet database with the geoip_build_db.pl tool that is shipped with the source package, and which should be available in compiled packages in  /usr/lib(exec)/xta‐
       bles-addons/. The first command retrieves CSV files from MaxMind, while the other two build packed bisectable range files:

       mkdir -p /usr/share/xt_geoip; cd /tmp; $path/to/xt_geoip_dl;

       $path/to/xt_geoip_build -D /usr/share/xt_geoip GeoIP*.csv;

       The shared library is hardcoded to look in these paths, so use them.

[ ... ]

Leave a Reply