Hi all,
I've gotten a lot of help from the folks on this board, so I'm posting this to describe my method for blocking incoming traffic from specific countries using iptables and ipset on Debian Wheezy in the hope that it will be useful to someone. The easiest way to describe it is to walk through setting it up.
Support for ipset is now in the kernel in Wheezy, so now it's just an apt-get away. We also need a perl module for aggregating the CIDR zone files:
Code:
apt-get install ipset libnet-ip-perl
I use the country zone files published by the kind folks at
http://ipdeny.com/, along with Mark Suter's excellent "aggregate-cidr-addresses" utility (
http://www.zwitterion.org/software/aggr ... addresses/), so make some directories and get the files:
Code:
mkdir /usr/local/blockip
cd /usr/local/blockip
mkdir allzones
mkdir blockzones
wget http://www.zwitterion.org/software/aggregate-cidr-addresses/aggregate-cidr-addresses
chmod 744 aggregate-cidr-addresses
wget -O /usr/local/blockip/allzones/all-zones.tar.gz http://www.ipdeny.com/ipblocks/data/countries/all-zones.tar.gz
tar -C /usr/local/blockip/allzones/ -xzf /usr/local/blockip/allzones/all-zones.tar.gz
Now create symlinks in the /blockzones directory for the specific countries you want to block (apologies to our friends in China, Russia, and Ukraine...):
Code:
cd blockzones
ln -s ../allzones/cn.zone
ln -s ../allzones/ru.zone
ln -s ../allzones/ua.zone
cd ..
Create the set, then run the selected zones through aggregate-cidr-addresses and add them to the set:
Code:
ipset create countryset nethash
for i in $(cat /usr/local/blockip/blockzones/*.zone | /usr/local/blockip/aggregate-cidr-addresses); do ipset add countryset $i; done
check the set with "ipset list -t" if you want to verify your work, then set up an iptables rule to drop traffic from addresses in the set:
Code:
iptables -A INPUT -p tcp -m set --match-set countryset src -j DROP
That's it. If you create more sym links and want to update the set in-place, you can create a temporary set, swap it with the active set, and delete the temporary one thusly:
Code:
ipset create tempset
for i in $(cat /usr/local/blockip/blockzones/*.zone | /usr/local/blockip/aggregate-cidr-addresses); do ipset add tempset $i; done
ipset swap countryset tempset
ipset destroy tempset
Here's a script that I run from /etc/network/interfaces (" pre-up /usr/local/blockip/countryblock.sh") to enable on startup:
Code:
#!/bin/bash
basedir="/usr/local/blockip" ;
/usr/sbin/ipset create countryset nethash ;
for i in $(cat $basedir/blockzones/*.zone | $basedir/aggregate-cidr-addresses); do /usr/sbin/ipset add countryset $i ; done ;
/sbin/iptables -A INPUT -p tcp -m set --match-set countryset src -j DROP ;
And here's a script to update the ipdeny zone files; I run it from cron weekly:
Code:
#!/bin/bash
basedir="/usr/local/blockip" ;
[ -e $basedir/allzones/all-zones.tar.gz ] && mv $basedir/allzones/all-zones.tar.gz $basedir/allzones/all-zones.tar.old ;
wget -O $basedir/allzones/all-zones.tar.gz http://www.ipdeny.com/ipblocks/data/countries/all-zones.tar.gz ;
tar -C /usr/local/blockip/allzones/ -xzf /usr/local/blockip/allzones/all-zones.tar.gz
ipset create tempset nethash ;
for i in $(cat $basedir/blockzones/*.zone | $basedir/aggregate-cidr-addresses); do ipset add tempset $i ; done ;
ipset swap countryset tempset ;
ipset destroy tempset ;
ipset list -terse ;
exit ;
I imagine the same method could be used to block outbound connection attempts too. I will appreciate your comments.
Regards,
-Bart