With all of the scanning / noise on the Internet, it’s nice to get rid of a large chunk of it simply by blocking an entire country’s worth of IP space. To do that you can simply use a kernel module for iptables called “xtables-addons”. On Debian/Ubuntu it’s pretty easy to get going, just apt-get install the needed perl library and the addons themselves:

apt-get install libtext-csv-xs-perl xtables-addons-common

!Warning: This does require proper linux headers to be available to compile the kernel module. In the case of where these aren’t availabe (like Linode’s special kernel), you will need to find another way to get the correct headers installed.

Then download the Maxmind geo database, the location of the xt_geoip_dl tool that does this is dependent on the installed version of xtables-addons. For my testing I have found it in /usr/src/xtables-addons-2.6/geoip/ as well as /usr/lib/xtables-addons/ YMMV.

cd /usr/src/xtables-addons-2.6/geoip/
./xt_geoip_dl

You should see it downloading the IP databases:

--2016-10-28 13:55:24--  http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz
Length: 1303811 (1.2M) [application/octet-stream]
Saving to: ‘GeoIPv6.csv.gz’

GeoIPv6.csv.gz                                  100%[=========================================================================================================>]   1.24M  --.-KB/s   in 0.004s

2016-10-28 13:55:24 (321 MB/s) - ‘GeoIPv6.csv.gz’ saved [1303811/1303811]

--2016-10-28 13:55:24--  http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
Saving to: ‘GeoIPCountryCSV.zip’

GeoIPCountryCSV.zip                             100%[=========================================================================================================>]   2.04M  --.-KB/s   in 0.006s

2016-10-28 13:55:24 (326 MB/s) - ‘GeoIPCountryCSV.zip’ saved [2137625/2137625]

FINISHED --2016-10-28 13:55:24--
Total wall clock time: 0.1s
Downloaded: 2 files, 3.3M in 0.01s (324 MB/s)
Archive:  GeoIPCountryCSV.zip
  inflating: GeoIPCountryWhois.csv

After that, you need to “build” the lists by performing the following command in that same directory (one install didn’t automatically make the directory so ensure it’s there with the mkdir command):

mkdir -p /usr/share/xt_geoip
./xt_geoip_build -D /usr/share/xt_geoip *.csv

After that you are off the the races and you can simply use the geoip module as so now:

iptables -A INPUT -m geoip --src-cc CN -j DROP
iptables -A INPUT -m geoip --src-cc HK -j DROP
iptables -A INPUT -m geoip --src-cc RU -j DROP
iptables -A INPUT -m geoip --src-cc KR -j DROP

Or you can go the other route and just allow from your country:

iptables -A INPUT -m geoip --src-cc PL -m tcp -p tcp --dport 22 -j ACCEPT

When looking up how to do this many people recommended updating the GeoIP database once a month. To do this I made a really simple bash script that just repeats all the things I did and added it to a monthly cron job:

File: 0update_maxmind

#!/bin/bash

rm -f /usr/src/xtables-addons-2.6/geoip/*.csv
rm -rf /usr/share/xt_geoip/*
cd /usr/src/xtables-addons-2.6/geoip/
./xt_geoip_dl
./xt_geoip_build -D /usr/share/xt_geoip *.csv

Setting the cronjob:

chmod +x 0update_maxmind
mv 0update_maxmind /etc/cront.monthly/

References I found useful: