If you've run fail2ban
on any of your servers, see fail2ban with Shorewall, you'll quickly find out that a majority of the banned IPs will originate from many of the same countries, usually China. One of the techniques I previously used to block out an entire country's network range was to use ipsets. I used custom bash scripts to pull down zone information from http://www.ipdeny.com/ipblocks/ and import them into separate ipsets for countries I wanted. There were certain limitations with this solution, however, such as maintaining up to date ipsets across multiple servers, some issues with Shorewall losing the ipsets across reboots or restarts, and the US netblock space being to large to fit into a single ipset.
Shorewall version 4.5.4 introduced the ability to support GeoIP 2-character ISO 3166 country codes. This method is far more efficient and easier to maintain as the GeoIP database holds all the netblocks for all the countries in the world in an offline hashed database.
xt_geoip module installation
The first step is to install the xt_geoip
kernel module which allows you to reference two letter country codes (e.g. US, CN, UK, CA, FR, etc.) in iptables
or Shorewall.
This module can be found in the xtables-addons-common 2.3-1
package, but do not install this default package to use the xt_geoip
module. I probably spent over 4 hours trying to figure out why my virtual machine was crashing every time a rule triggered the use of the xt_geoip
module only to find out that there's a verified bug that causes a kernel panic.
Patrick Domack PPA to the rescue
Fortunately, if you read the bug comments, a user by the name of Patrick Domack provided his own PPA with a packaged version of xtables-addons-common
version 2.6-1~ppa1
which fixes this bug.
Add the PPA with apt-add-repository ppa:patrickdk/general-lucid
:
root@ubuntu:~# add-apt-repository ppa:patrickdk/general-lucid Packages used for my personal productions systems where newer versions or special patches are needed. More info: https://launchpad.net/~patrickdk/+archive/ubuntu/general-lucid Press [ENTER] to continue or ctrl-c to cancel adding it gpg: keyring `/tmp/tmp24yt3e8g/secring.gpg' created gpg: keyring `/tmp/tmp24yt3e8g/pubring.gpg' created gpg: requesting key 4D79B5B5 from hkp server keyserver.ubuntu.com gpg: /tmp/tmp24yt3e8g/trustdb.gpg: trustdb created gpg: key 4D79B5B5: public key "Launchpad PPA for Patrick Domack" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) OK
apt-get update
to update the repository and verify the new version of xtables-addons-common
is available:
root@ubuntu:~# apt-get update root@ubuntu:~# apt-cache show xtables-addons-common Package: xtables-addons-common Source: xtables-addons Priority: extra Section: admin Installed-Size: 326 Maintainer: Pierre ChifflierArchitecture: amd64 Version: 2.6-1~ppa1
Install xtables-addons-common
and verify the correct version is installed:
root@ubuntu:~# aptitude -yvV install xtables-addons-common root@ubuntu:~# dpkg -l | grep xtables-addons-common ii xtables-addons-common 2.6-1~ppa1 amd64 Extensions targets and matches for iptables [tools, libs]
Building the GeoIP database for xt_geoip
The package will install two scripts in the /usr/lib/xtables-addons
directory:
root@ubuntu:~# ls /usr/lib/xtables-addons/ xt_geoip_build xt_geoip_dl
- According to http://xtables-addons.sourceforge.net/geoip.php the "
xt_geoip_dl
simply calls wget on the hardcoded URLs and unpacks the retrieved files into the current directory. Then usext_geoip_build
to transform the CSV into the packed format"
The xt_geoip_dl
script uses the unzip
utility to unpack the a .csv
file, install unzip
if it isn't already:
root@ubuntu:~# aptitude -yvV install unzip
Change into /tmp
and run /usr/lib/xtables-addons/xt_geoip_dl
:
root@ubuntu:/tmp# /usr/lib/xtables-addons/xt_geoip_dl
Note that both iptables
and shorewall
will look for the GeoIP database in the /usr/share/xt_geoip
directory, by default it is not created. Also, the build script requires the libtext-csv-xs-perl
module to parse the .csv
file.
Create the /usr/share/xt_geoip
directory and install the required perl module:
root@ubuntu:/tmp# mkdir /usr/share/xt_geoip root@ubuntu:/tmp# aptitude -yvV install libtext-csv-xs-perl
Run the build script to create the GeoIP database from the .csv
files and place the them in the /usr/share/xt_geoip
directory:
root@ubuntu:/tmp# /usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip *.csv
Loading the module and configuring Shorewall
Load the kernel module and verify it was loaded:
root@ubuntu:~# modprobe xt_geoip root@ubuntu:~# lsmod | grep ^xt_geoip xt_geoip 12775 0
For verification I'm going to add a rule to reject and log any ping from my virtual machine to any address in the United States. Note, I wouldn't recommend blocking all of U.S. in production, because the IP addresses to Google for other countries are still considered U.S. based. Though whitelisting the U.S. address space may be useful in some environments.
Edit the /etc/shorewall/rules
file:
Ping(REJECT):info $FW net:^[US]
- The format for referencing countries is
^[<Country Code>]
. - Multiple countries can be specified in the brackets, e.g.
^[US,FR,CA,UK]
. - See http://shorewall.net/ISO-3661.html for more information.
Check and restart Shorewall:
root@ubuntu:/etc/shorewall# shorewall check root@ubuntu:/etc/shorewall# shorewall restart
Now we'll test ping to www.google.com
:
root@ubuntu:/etc/shorewall# ping -n -c 2 www.google.com PING www.google.com (64.233.185.105) 56(84) bytes of data. From 192.168.1.100 icmp_seq=1 Destination Host Unreachable From 192.168.1.100 icmp_seq=1 Destination Host Unreachable --- www.google.com ping statistics --- 0 packets transmitted, 0 received, +2 errors
Working as intended. Let's see what Shorewall logged:
Feb 6 23:34:27 ubuntu kernel: [ 942.806263] Shorewall:fw2net:REJECT:IN= OUT=eth0 SRC=192.168.1.100 DST=64.233.185.104 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=9477 DF PROTO=ICMP TYPE=8 CODE=0 ID=5713 SEQ=1 Feb 6 23:34:27 ubuntu kernel: [ 942.807537] Shorewall:fw2net:REJECT:IN= OUT=eth0 SRC=192.168.1.100 DST=64.233.185.104 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=9478 DF PROTO=ICMP TYPE=8 CODE=0 ID=5713 SEQ=1 Feb 6 23:35:26 ubuntu kernel: [ 1002.101682] Shorewall:fw2net:REJECT:IN= OUT=eth0 SRC=192.168.1.100 DST=64.233.185.105 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=63477 DF PROTO=ICMP TYPE=8 CODE=0 ID=5730 SEQ=1 Feb 6 23:35:26 ubuntu kernel: [ 1002.101924] Shorewall:fw2net:REJECT:IN= OUT=eth0 SRC=192.168.1.100 DST=64.233.185.105 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=63478 DF PROTO=ICMP TYPE=8 CODE=0 ID=5730 SEQ=1
And for more verification, to see it isn't blocking IP addresses that are non-US owned, we'll ping www.pcengines.ch
:
root@ubuntu:/etc/shorewall# ping -n -c 2 www.pcengines.ch PING www.pcengines.ch (213.133.104.38) 56(84) bytes of data. 64 bytes from 213.133.104.38: icmp_seq=1 ttl=51 time=297 ms 64 bytes from 213.133.104.38: icmp_seq=2 ttl=51 time=296 ms --- www.pcengines.ch ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 296.200/296.846/297.493/0.845 ms
Conclusion
Using GeoIP support in Shorewall is a much quicker way to blacklist or whitelist large country IP address ranges, when compared to using just ipsets. Though this does not diminish the use cases of ipsets, as they are very useful in many different solutions which I will eventually cover in the future.
I got an error on this command, "modprobe xt_geoi"
ReplyDeletemodprobe: ERROR: ../libkmod/libkmod.c:556 kmod_search_moddep() could not open moddep file '/lib/modules/4.1.0-x86_64-linode59/modules.dep.bin'
This comment has been removed by the author.
Delete24 hours and I'm one step closer to solving this problem! I found linode was using it's own kernel. I moved to Grub 2, which allows me to run a distribution provided kernel. Now when I run "modprobe xt_geoip", I get this:
Deletemodprobe: FATAL: Module xt_geoip not found.
In order to install the correct kernel module you need to additionally run the following command -
Deletemodule-assistant auto-install xtables-addons-source
This will download and install software to compile your own kernel module. Running this should go through and install the correct module however half way through it will warn of an error. When asked simply select
"CONTINUE Skip and continue with the next operation"
and it goes through fine!
You can then run 'modprobe xt_geoip'
Also I ran
apt-get install libxtables10 xtables-addons-common xtables-addons-dkms libtext-csv-xs-perl
rather than just
apt-get install xtables-addons-common
though I don't know if that is needed...