
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)
RedHat based system (CentOS, RHEL, Fedora)
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 http://downloads.sourceforge.net/project/xtables-addons/Xtables-addons/xtables-addons-2.13.tar.xz
# 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/

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.


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 :-)
Hello, when i am try to add iptables command its give me error
iptables: No chain/target/match by that name.
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?
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.
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
When using command : ./xt_geoip_build GeoIPCountryWhois.csv
I get This: Can't locate Text/CSV_XS.pm 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.
Hi Alex,
Did you try installing Text::CSV_XS for Perl?
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/xtables10.so):
# vi /usr/local/lib/pkgconfig/xtables.pc
--------------
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib64/xtables
includedir=${prefix}/include
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 :)
Thanks Carl
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)
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.
You can use these scripts from Martin Schmitt to create a legacy formatted database again https://github.com/mschmitt/GeoLite2xtables It converts the current Maxmind GeoIP database into a format that can be used with the xtables addon.
Hi Karl,
That's nice. Thanks for sharing.
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
Hi Pietro
Did u try using 'pf', put IP ranges in files and load them as tables
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
Hi Pietro,
Looks need to build and update iptables http://www.linuxfromscratch.org/blfs/view/svn/postlfs/iptables.html
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
To whom it may concern:
It appears that https://sourceforge.net/projects/xtables-addons/files/ has new(er) versions available compare to the ones used in the HowTo.
It also appears that Ubuntu 20.04 does not have a "tables-dev" package readily available.
Questions and/or feedback is welcomed. Thanks in advance.
Apparently, building on RedHat (at least CentOs 7.8) is not supported I got compilation errors :
...
xt_TARPIT.c:295:3: erreur: too few arguments to function 'NF_HOOK'
...
I found an explanation here : https://marc.info/?l=netfilter-devel&m=145279481226268&w=2
I tried to download newer version of xtables-addons, but they need a more recent version of xtables...
This article rocks! No more spam from RU, CN, HK, etc. for me!!
Also, I found this perl script to be indispensable for converting the modern GeoIP2 stuff to a format usable by xt_geoip. https://github.com/mschmitt/GeoLite2xtables
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.