Gentoo IPTables Xtables-addons Block countries

Jump to navigationJump to search


Because there are kinda' tons of infected japan and pakistan computers which try to send spam to me ( or use me as a relay ). My postfix is set up to block relay but that still has to check against dnsbl lists for each ip.


Use geoip with iptables !

I'm using gentoo so patch-o-matic doesn't seem to be integrated yet.

Step 1. Get the latest xtables-addons from and unpack

Step 2. Go to your unpacked xtables-addons dir and do

./configure --with-xtlibdir=/lib/xtables # this is where my gentoo puts his modules
make install

On my arm gentoo boxen I have this package masked which is needed for the next steps...

echo "dev-perl/Text-CSV_XS **" >> /etc/portage/package.keywords
emerge Text-CSV_XS

Step 3. Get the ip->country database and set it up right.

mkdir ~/geoip
cd ~/geoip
tar -xjf geoip_src.tar.bz2
cp -r var/geoip/* /var/geoip/'s contents:

#!/bin/bash -ex

rm -Rf var
mkdir -p var/geoip/{BE,LE};
pushd var/geoip/BE;
../../../ -b ../../../GeoIPCountryWhois.csv;
pushd var/geoip/LE;
../../../ ../../../GeoIPCountryWhois.csv;
find var -print0 | sort -z | tar -T- --null --no-r --owner=root \
        --group=root -cvjf geoip_iv0_database.tar.bz2;
tar --no-r --owner=root --group=root -cvjf geoip_src.tar.bz2 \
        GeoIPCountryWhois.csv's contents:

#       Converter for MaxMind CSV database to binary, for xt_geoip
#       Copyright © CC Computer Consultants, 2008
#       Contact: Jan Engelhardt <>
#       Use -b argument to create big-endian tables.
use Getopt::Long;
use IO::Handle;
use Text::CSV_XS; # or trade for Text::CSV
use strict;

my %country;
my %names;
my $csv = Text::CSV_XS->new({binary => 0, eol => $/}); # or Text::CSV
my $mode = "VV";

&GetOptions("b" => sub { $mode = "NN"; });

while (my $row = $csv->getline(*ARGV)) {
        if (!defined($country{$row->[4]})) {
                $country{$row->[4]} = [];
                $names{$row->[4]} = $row->[5];
        my $c = $country{$row->[4]};
        push(@$c, [$row->[2], $row->[3]]);
        if ($. % 4096 == 0) {
                print STDERR "\r\e[2K$. entries";

print STDERR "\r\e[2K$. entries total\n";

foreach my $iso_code (sort keys %country) {
        printf "%5u ranges for %s %s\n",
                $iso_code, $names{$iso_code};

        open(my $fh, ">".uc($iso_code).".iv0");
        foreach my $range (@{$country{$iso_code}}) {
                print $fh pack($mode, $range->[0], $range->[1]);
        close $fh;

And you're done