Recent Posts


« | Main | »

Linux GeoIP Firewall via iptables (xtables-addons)

By Dale Reagan | September 13, 2011

Getting xtables-addons  with GeoIP working under Fedora (Red Hat) Linux was a bit of a hassle…  Note – xtables-addons is NOT standard (yet) for Linux iptables; it is considered to be experimental so installing it on a production system may not be appropriate.  I  hope that the GeoIP addon will soon become a standard feature.

There are a number of posts on this site covering the use of GeoIP (geographical IP address resource monitoring and access control) technologies.  During 2011, a significant number of reported system and network breaches have been written about along with a number of news articles about country-specific/nation-sponsored cracking type activities.  Who Cares? (pause for a bit of reflection…)

So, what is Xtables-addons?

“Xtables-addons is a package that obsoletes the old patch-o-matic repository for the Linux kernel and iptables. Instead of patching the kernel source, extensions are built as modules and thus allow extending kernels without recompilation.”

It includes a number of firewall (iptables) add-ons including one for using a GeoIP data-set to assist in filtering connections from known geographic IP space.  The GeoIP add-on requires that a CSV data set be downloaded and converted into a binary hash table (using a Perl library/tool.)  As of 9/2011 the included modules are:

Name v4 v6 Notes
xt_ACCOUNT supplants Intra2net’s ipt_ACCOUNT 1.15 with extra kernel version support
xt_CHAOS  Causes  confusion  on  the  other  end  by doing odd things with incoming packets.
xt_DELUDE  DELUDE target will reply to a SYN packet with SYN-ACK, and to all other packets with an RST. This will terminate the connection much like REJECT, but  network scanners doing TCP half-open discovery can be spoofed to make them belive the port is open rather than closed/filtered.
xt_DHCPMAC  In conjunction with ebtables, DHCPMAC can be used to  completely  change  all  MAC addresses  from  and  to  a  VMware-based  virtual machine.
xt_IPMARK replaces pom-ng’s ipt_IPMARK
xt_LOGMARK  LOGMARK target will log packet and connection marks to syslog.
xt_RAWNAT  RAWDNAT target will rewrite the destination address in  the  IP  header,  much like the NETMAP target.
xt_STEAL  Like  the DROP target, but does not throw an error like DROP when used in the OUTPUT chain.
xt_SYSRQ The SYSRQ target allows to remotely trigger sysrq on the local  machine  over  the network.  This  can be useful when vital parts of the machine hang, for example an oops in a filesystem causing locks to be not released and processes to  get  stuck as  a result — if still possible, use /proc/sysrq-trigger. Even when processes are stuck, interrupts are likely to be still processed, and  as  such,  sysrq  can  be triggered through incoming network packets.
xt_TARPIT  Captures  and  holds  incoming  TCP  connections  using  no  local  per-connection resources. Connections are accepted, but immediately switched to the persist state (0 byte window), in which the remote side stops sending data and asks to  continue every  60-240  seconds.
xt_TEE (merged into Linux 2.6.35)
xt_condition replaces pom-ng’s ipt_condition
xt_fuzzy This module matches a rate limit based on a fuzzy logic controller (FLC).
xt_geoip replaces Nicolas Bouliane’s original ipt_geoip with a new optimized lookup, broader kernel version support and IPv6 GeoIP database lookup
xt_iface  Allows you to check interface states.
xt_ipp2p xt_ipp2p 0.10 replaces ipt_ipp2p 0.8.2 from
xt_ipv4options replaces pom-ng’s ipt_ipv4options
xt_length2 This module matches the length of a packet against a specific value  or  range  of values.
xt_lscan Detects  simple low-level scan attemps based upon the packet’s contents.
xt_pknock port knocking support
xt_psd port scan detection
xt_quota2 Simple counters

After successfully installing xtables-addons the man page can be viewed with:  man xtables-addons.

The man page provides simple details for the above ‘add-ons’ – for xtables-addons geoip the current entry is:

       Match a packet by its source or destination country.

       [!] --src-cc, --source-country country[,country...]
              Match packet coming from (one of) the specified country(ies)

       [!] --dst-cc, --destination-country country[,country...]
              Match packet going to (one of) the specified country(ies)

       NOTE:  The country is inputed by its ISO-3166 code.

       The  extra  files you will need is the binary database files.
They are generated from a country-subnet database with the tool that should be available in
/usr/lib(exec)/xtables-addons/ . The resulting files MUST be
moved to  /usr/share/xt_geoip/  as  the  shared  library  is
statically  looking  for  this  pathname 
(e.g. /usr/share/xt_geoip/LE/de.iv0).

Ok, looks like relatively simple ‘rule’ options – let’s try the install.

Using FC 13 (Fedora, RH Linux) Installing via Yum seemed to work, however:

Ok, trying to Download, compile and install the ‘latest version’:

“The IPv6 update in Xtables-addons 1.33 changed the filenames slightly; the database files now carry extensions .iv6 and .iv4 (short for Integer Vector, since that is what those files essentially are). Be sure to use the xt_geoip_build script from xtables-addons 1.33 to generate the IV files for xt_geoip 1.33.”

With Fedora (FC 13) the result of yum install of xtables-addons – (GeoIP) is that it  does not work (at least, not in early September of 2011) – the other addons were not tested.

One Solution to get xtables-addons geoip working with FC13:

  1. install via yum:  yum install xtables-addons
  2. download prior version of xtables-addons (as noted above, a version prior to 1.33) and extract the DB tool program – the old tool is named: ; the new tool is named: xt_geoip_build
  3. generate needed files and move into required folders
  4. test, test, test..

The packed data files are placed in sub-folders (and, after looking at the source, the ‘BE/LE’ folders are for ‘big endian/little endian’ which implies that the data files are indeed different…)  *.iv4 ~=  IPv4 space; *.iv6 ~= IPv6 space; *.iv0 ~= (most likely) IPv4 space – (guessing about this…)

-rw-r--r--. 1 root root 13776 Sep 11 20:57 BE/CN.iv0
-rw-r--r--. 1 root root 13776 Sep 11 20:55 BE/CN.iv4
-rw-r--r--. 1 root root  4544 Sep 11 20:55 BE/CN.iv6
-rw-r--r--. 1 root root 13776 Sep 11 20:57 LE/CN.iv0
-rw-r--r--. 1 root root 13776 Sep 11 20:55 LE/CN.iv4
-rw-r--r--. 1 root root  4544 Sep 11 20:55 LE/CN.iv6

Ok, xtables-addons is installed on FC 13, data files are ‘packed’, now what?  Time for some simple rules & testing.  Reviewing previous/related posts on this site is suggested; in a previous post GeoIP filtering via iptables was discussed but it required that you extract IP addresses/ranges and create rules for them – which can quickly require thousands of iptables rules.  Using xtables-addons should be simpler.  Based on the man page info (above) adding new rules is as simple as inserting/appending a single DROP rule into an existing iptables filter or using a custom-chain approach as shown below:

### clear old rules for custom CHAIN
iptables -t filter -F GEO-SCRUB
### drop the chain
iptables -t filter -X GEO-SCRUB
### create a new chain called 'GEO-SCRUB'
iptables -N GEO-SCRUB
### now we use '-A' to APPEND rules to the chain GEO-SCRUB
### 1) log the packet & country info and 2) 'drop' the connection
### limit logging (otherwise log files can quickly consume disk space...)
### note that 'rsyslog' (or equivalent) must be configured to capture the data (see below)
iptables -A GEO-SCRUB -m geoip --src-cc CN -m limit --limit 5/minute -j LOG --log-level 7 --log-prefix 'GeoIP FW Ban CN: '
iptables -A GEO-SCRUB -m geoip --src-cc CN -j DROP
iptables -A GEO-SCRUB -m geoip --src-cc KR -m limit --limit 5/minute -j LOG --log-level 7 --log-prefix 'GeoIP FW Ban KR: '
iptables -A GEO-SCRUB -m geoip --src-cc KR -j DROP
### attach above to INPUT & FORWARD (skip if already done...)
### in this case, insert as the first rule (use -A to append...)
iptables -I INPUT -j GEO-SCRUB
iptables -I FORWARD -j GEO-SCRUB
iptables -nvL | more ## review the changes

Notes for this iptables xtables-addons geoip filtering example

Possible testing approaches

  1. create one or more entries for private IP space using the same CSV format found in the GeoIP data input files
  2. run the data-packing tool to create your new ‘country’
  3. install the file
  4. create a rule to log/blog access  for your ‘test country’
  5. test, test, test

My input data for my ‘new country’ in the file Geoip.txt.csv (See CSV docs for Maxmind GeoIP data):


I pack the data to get a new file (XX.xv0): Geoip.txt.csv

Next ‘install’ the file for my custom country and add rules for the ‘new country’ to the existing GEO-SCRUB CHAIN:

iptables -I GEO-SCRUB -m geoip --src-cc XX -j LOG --log-level 7 --log-prefix 'GeoIP FW Test XX: '

Test the new iptables rule by accessing the server from your ‘new country’ (i.e. a system within the designated IP range on your internal network.)  For the rule above ‘logging’ is the only action – you would need to add a DROP rule to test ‘blocking’…

Note that the IP-Numbers for the IP-Addresses listed above are ‘guesses’ and resulted in firewall log entries on my system; your mileage should vary, at least a bit.  🙂

And, yes, I do use a custom script to generate rules from a simple list of GeoIP country codes, i.e. the list below contains countries with rampant SPAMMING/Hacking – based on a review of log files – so access is simply denied:


1 A1 Anonymous_Proxy 102 138,698
2 A2 Satellite_Provider 2,524 768,845
3 CN China 1,722 330,999,853
4 KR Korea_Republic_of 708 112,151,194
5 UA Ukraine 2,622 10,022,408
6 RU Russian_Federation 4,842 39,809,064
7 PL Poland 3,600 18,337,794
8 RO Romania 1,214 11,217,529
9 CZ Czech_Republic 998 8,012,133
10 TW Taiwan 517 35,476,077
11 BG Bulgaria 543 3,978,867
12 TH Thailand 417 8,605,506
13 IN India 1,784 34,969,254
14 HU Hungary 580 5,169,166
15 SA Saudi_Arabia 415 4,489,907
16 LT Lithuania 483 2,255,639
17 TR Turkey 943 14,072,882
18 ID Indonesia 842 18,800,342
19 LV Latvia 338 1,622,770
20 PH Philippines 502 5,603,851
21 SK Slovakia 381 2,517,416
22 SI Slovenia 467 2,558,951
23 MY Malaysia 560 6,382,617
24 BD Bangladesh 351 973,780
25 VN Vietnam 201 15,478,549
26 KZ Kazakhstan 204 2,188,950
27 BG Bulgaria 543 3,978,867
28 NG Nigeria 1,033 941,508
29,436 701,522,417

The numbers above were calculated from CSV file data. Note that after extracting ‘reserved’ network IPs from 2^32 total IPvb4 IP space that there are approximately 3,706,650,624 (3706.65 million) useable IPv4 IP addresses.  Entering 28 country codes is quite a bit less work/effort than entering rules for 29,436 ip ranges (which should work) while 7015.2 million rules probably would NOT work…


Topics: Computer Technology, Problem Solving, System and Network Security, Unix-Linux-Os, Virtual-Cloud Computing, Web Technologies | Comments Off on Linux GeoIP Firewall via iptables (xtables-addons)

Comments are closed.

YOUR GeoIP Data | Ip:
Continent: NA | Country Code: US | Country Name: United States
Region: | State/Region Name: | City:
(US only) Area Code: 0 | Postal code/Zip:
Latitude: 38.000000 | Longitude: -97.000000
Note - if using a mobile device your physical location may NOT be accurate...

Georgia-USA.Com - Web Hosting for Business