How to Block IPs from Countries using Iptables Geoip Addons

geoip block ip iptables

We'll learn how we can block traffic originated from specific country IPs using GeoIP database and linux iptables. Iptables is a command based utility program for configuring the linux kernel firewall which is implemented within the Netfilter project. Whereas GeoIP is a collection of IPs corresponding with the geographical locations where the geographical location is mapped with the IP addresses allocated at those specific organization, city, state and countries. The geographical co-ordinates in the GeoIP database are the often near the center of the population so it should not be used to identify a particular address or household. And with the help of a module called xt_geoip consisting in an iptables extension xtables-addon and the GeoIP database, we'll perform country-based traffic filtering which helps us block or allow the traffic from a specific country.

Upgrading and Installing Dependencies

First of all, we'll need to upgrade our linux system and then we'll move ahead for the installation of the dependencies that is required for xtables-addons. In order to do so, we'll run the following commands respective to the distributions running in our machine.

Debian based system (Debian, Ubuntu, Linux Mint)

# apt-get update && apt-get upgrade # apt-get install iptables-dev xtables-addons-common libtext-csv-xs-perl pkg-config

RedHat based system (CentOS, RHEL, Fedora)

# yum update # yum install gcc-c++ make automake kernel-devel-`uname -r` wget unzip iptables-devel perl-Text-CSV_XS

Installing Xtables-addons

Once our system is upgraded and dependencies are installed, we'll now install the xtables-addons in our machine. To do so, we'll download the latest tarball from the official xtables-addons project site using wget. Once it's downloaded, we'll extract the tarball, then compile and install it in our machine.

# wget
# tar xf xtables-addons-2.13.tar.xz
# cd xtables-addons-2.13
# ./configure
# make
# make install

Allow SeLinux from loading modules (RedHat based System)

As the RedHat based linux distributions ie CentOS, RHEL, Fedora has selinux enabled by default, we'll need to adjust the selinux policy as follows. Otherwise, SeLinux will prevent iptables from loading xt_geoip module.

# chcon -vR --user=system_u /lib/modules/$(uname -r)/extra/*.ko
# chcon -vR --type=lib_t /lib64/xtables/*.so

Install GeoIP Database

Next, we'll run a module called xt_geoip that comes with the xtables-addons extension which downloads the GeoIP database from MaxMind and converts it into a binary form recognized by xt_geoip. Once it's downloaded, we'll build it and move them to the required xt_geoip path ie /usr/share/xt_geoip/  .

# cd geoip
# ./xt_geoip_dl
# ./xt_geoip_build GeoIPCountryWhois.csv
# mkdir -p /usr/share/xt_geoip/
# cp -r {BE,LE} /usr/share/xt_geoip/
install geoip database

Block traffic to and from a Country

If everything went as expected, we should now be able to use our firewall utilities program iptables to use the geoip module.

Using Iptables

Here's the basic syntax for using iptables with geoip module in order to block traffic originating from or destined to a country. Here, we need to use two-letter ISO3166 code in place of country , for eg., US for United States, IE for Ireland, IN for India, CN for China and so on.

# iptables -m geoip --src-cc country[,country...] --dst-cc country[,country...]
Now, if we want to block incoming traffic from India (IN) and United States (US), the following iptables command should do.
# iptables -I INPUT -m geoip --src-cc IN,US -j DROP
If we want to block all incoming non-US traffic on our server, we need to execute the following.
# iptables -I INPUT -m geoip ! --src-cc US -j DROP
ping non us blocked

Here's a screenshot I had taken when I tried to ping to the server from non-US network. I wasn't getting any replies from the ping. As the iptables configs were applied on the runtime and weren't saved, after I rebooted the server, then I got ping replies from the server.
ping success after reboot

If we want to block outgoing traffic destined to India (IN), we need to run the following command.
# iptables -A OUTPUT -m geoip --dst-cc IN -j DROP

Using firewalld

If we are running systemd based system and we have firewalld as frontend controller for iptables, we can also use firewalld for the above job respectively.

# firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -m geoip --src-cc IN,UN -j DROP

# firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -m geoip ! --src-cc US -j DROP

# firewall-cmd --direct --add-rule ipv4 filter OUTPUT 0 -m geoip --dst-cc IN -j DROP

Iptables with GeoIP module is very essential for preventing DOS, DDOS attacks originating from certain countries. This is also very efficient when you want to restrict the access to your particular website/server from a certain country. So, having GeoIP module installed with iptables-addons is a must to have setup for allowing or restricting certain countries. So, if you have any questions, suggestions, feedback please write them in the comment box below. Thank you ! Enjoy :-)

21 Comments... add one

  1. Hey Arun,

    Thank you for the tutorial, I tried to configure it for CentOS 7.4.xxxx after I downloaded the 2.13.tar.xz, but I suspect this version is not supported for kernel-headers-3.10.0-693.5.2.el7.x86_64 as the ./configure results in the below error.

    checking kernel version that we will build against... make: *** /lib/modules/3.10.0-693.5.2.el7.x86_64/build: No such file or directory. Stop.

    This is a fresh CentOS install with the pre-reqs installed from the yum snippet you've included. It appears the support for this seems to have phased out a while ago. Are you aware of suitable replacement package for this?

  2. Are you using firewalld? Which OS? Just above the comments and ads is a firewall-cmd snippet for iptable related commands, try those and see if you get any traction.

  3. Please help. I've been pulling my hair out trying to make this work. Everything works up to the make command. I've tried both 1.47 & 2.13 to no avail. This is what I get...

    -sh-4.1$ make
    make all-recursive
    make[1]: Entering directory `/usr/share/xtables-addons-2.13'
    Making all in extensions
    make[2]: Entering directory `/usr/share/xtables-addons-2.13/extensions'
    Xtables-addons 2.13 - Linux make[3]: *** No rule to make target `kernelrelease'. Stop.
    make[2]: *** [modules] Error 2
    make[2]: Leaving directory `/usr/share/xtables-addons-2.13/extensions'
    make[1]: *** [all-recursive] Error 1
    make[1]: Leaving directory `/usr/share/xtables-addons-2.13'
    make: *** [all] Error 2

  4. When using command : ./xt_geoip_build GeoIPCountryWhois.csv
    I get This: Can't locate Text/ in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at ./xt_geoip_build line 8.
    BEGIN failed--compilation aborted at ./xt_geoip_build line 8.

  5. For those installing on CentOS 7.5 - Make sure you disarm SeLinux
    # setenforce 0
    Also make sure you have the iptables-devel package installed:
    # yum install iptables-devel

    Locate the pkg-config lib directory (should have your .pc files in it):
    # find / -name *.pc

    Create a pc file with your xtables version in it (you can find that by checking the library name for example - /usr/lib64/
    # vi /usr/local/lib/pkgconfig/xtables.pc

    Name: xtables
    Description: xtables libraries
    Version: 10.0.0
    Libs: -L${libdir} -lxtables
    Libs.private: -ldl
    Cflags: -I${includedir}


    Set the PKG_CONFIG_PATH environment variable:
    # export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/

    Now you can run your ./configure

    Note, I used xtables-addons-2.14 and built it with no errors. Hope this helps someone :)

  6. Hello!!! great and usefull article. But any way to mix country and port?
    I need to allow only from my country incoming connections on my server in standard SIP port TCP 5060 (is a commonly atacked port)

  7. Any idea how to update GeoIP database since the Maxmind is no longer supporting "Legacy Databases"? From 2nd January 2019 this xtables addon is not working - these two CSV files don't exist.

  8. I don't know how can i do the same thing on freebsd 12 in 2019, i find in the net but no solutions, i received too much attacks, hope you can help me, thanks in advance

  9. I have this problem
    configure: error: Package requirements (xtables >= 1.6.0) were not met:

    Requested 'xtables >= 1.6.0' but version of xtables is 1.4.21

  10. Debian 9

    make all-recursive
    make[1]: Entering directory '/root/xtables-addons-3.7'
    Making all in extensions
    make[2]: Entering directory '/root/xtables-addons-3.7/extensions'
    Xtables-addons 3.7 - Linux make[3]: Entering directory '/root/xtables-addons-3.7/extensions'
    make[3]: *** /lib/modules/4.9.0/build: No such file or directory. Stop.
    make[3]: Leaving directory '/root/xtables-addons-3.7/extensions'
    Makefile:463: recipe for target 'modules' failed
    make[2]: *** [modules] Error 2
    make[2]: Leaving directory '/root/xtables-addons-3.7/extensions'
    Makefile:495: recipe for target 'all-recursive' failed
    make[1]: *** [all-recursive] Error 1
    make[1]: Leaving directory '/root/xtables-addons-3.7'
    Makefile:380: recipe for target 'all' failed
    make: *** [all] Error 2

  11. Do you have any example to use the IP2Location LITE database?

    We are using the free version because it is more accurate in some cases.


Leave a Comment