iptables + geoip amb Debian Squeeze

Objectiu:

Bloquejar rangs d’adreces segons el país d’origen mitjançant iptables i geoip.

Procediment:

D’una banda instal·lem els mòduls necessaris d’xtables_addons:

$ apt-get install xtables-addons-common xtables-addons-source
$ module-assistant --verbose --text-mode auto-install xtables-addons

Amb aquestes dues comandes tenim els mòduls instal·lats al nostre sistema. Podem verificar que, amb la següent comanda, iptables dona informació del mòdul geoip:

$ iptables -m geoip --help

Ara només queda instal·lar les dades relatives als rangs d’adreces. Per fer-ho descarregarem la informació de MaxMind i la convertim al format que el mòdul instal·lat entén:

$ mkdir -p /usr/src/geoip
$ cd /usr/src/geoip
$ wget http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip;
$ unzip GeoIPCountryCSV.zip;

A continuació convertim les dades descarregades. Per fer-ho podem utilitzar el següent script perl. Per a l’execució farà falta un paquet extra:

$ apt-get install libtext-csv-xs-perl

Script a crear com l’arxiu: /usr/src/geoip/build.pl:

#!/usr/bin/perl
#
#	Converter for MaxMind CSV database to binary, for xt_geoip
#	Copyright © Jan Engelhardt , 2008
#
#	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";
my $target_dir = ".";

&Getopt::Long::Configure(qw(bundling));
&GetOptions(
	"D=s" => \$target_dir,
	"b"   => sub { $mode = "NN"; },
);

if (!-d $target_dir) {
	print STDERR "Target directory $target_dir does not exist.\n";
	exit 1;
}

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",
		scalar(@{$country{$iso_code}}),
		$iso_code, $names{$iso_code};

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

L’executem amb la comanda següent:

$ ./build.pl GeoIPCountryWhois.csv

Finalment movem les dades generades a la carpeta on el mòdul d’iptables espera trobar-les:

$ mkdir -p /usr/share/xt_geoip/{BE,LE}
$ mv *.iv0 /usr/share/xt_geoip/LE

Per curar-nos en salut, si no coneixem la nostra arquitectura, podem instal·lar també els rangs en el format BE:

$ ./build.pl -b GeoIPCountryWhois.csv
$ mv *.iv0 /usr/share/xt_geoip/BE

En aquest moment ja podem crear les regles a iptables:

$ iptables -A INPUT -m geoip --src-cc ES -j DROP

Aquesta regla, per exemple, bloquejarà tots els paquets d’adreces d’Espanya.

Nota important:

Quan s’ha executat la comanda ‘module-assistant’ s’ha obtingut un paquet .deb que depen de la versió del kernel actual al sistema. Si aquesta versió canvia la comanda s’ha de tornar a executar per tornar a instal·lar els moduls altrament tindrem errors en l’execució de les comandes iptables.