From: Philip Prindeville <philipp@xxxxxxxxxxxxxxxxxxxxx> Add a tool for retrieiving the IPv4 or IPv6 (or both!) CIDR ranges for a given country, which can then be injected into an ipset if one doesn't want to use (or have available) the xt_geoip extension. Signed-off-by: Philip Prindeville <philipp@xxxxxxxxxxxxxxxxxxxxx> --- geoip/Makefile.am | 4 +- geoip/xt_geoip_fetch | 93 ++++++++++++++++++++++++++++++++++++++++++ geoip/xt_geoip_fetch.1 | 30 ++++++++++++++ 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/geoip/Makefile.am b/geoip/Makefile.am index aa28c3d21c6e489bb20c8165ecfec2259e0ee438..d2a3313204f97d77178918621310d3a0fa817511 100644 --- a/geoip/Makefile.am +++ b/geoip/Makefile.am @@ -2,4 +2,6 @@ pkglibexec_SCRIPTS = xt_geoip_build xt_geoip_dl -man1_MANS = xt_geoip_build.1 xt_geoip_dl.1 +bin_SCRIPTS = xt_geoip_fetch + +man1_MANS = xt_geoip_build.1 xt_geoip_dl.1 xt_geoip_fetch.1 diff --git a/geoip/xt_geoip_fetch b/geoip/xt_geoip_fetch new file mode 100755 index 0000000000000000000000000000000000000000..4a35760b77c9509347a3846f37eeb9574aeb9883 --- /dev/null +++ b/geoip/xt_geoip_fetch @@ -0,0 +1,93 @@ +#!/usr/bin/perl +# +# Utility to query GeoIP database +# Copyright Philip Prindeville, 2018 +# +use Getopt::Long; +use Socket qw(AF_INET AF_INET6 inet_ntop); +use warnings; +use strict; + +sub AF_INET_SIZE() { 4 } +sub AF_INET6_SIZE() { 16 } + +my $target_dir = "."; +my $ipv4 = 0; +my $ipv6 = 0; + +&Getopt::Long::Configure(qw(bundling)); +&GetOptions( + "D=s" => \$target_dir, + "4" => \$ipv4, + "6" => \$ipv6, +); + +if (!-d $target_dir) { + print STDERR "Target directory $target_dir does not exit.\n"; + exit 1; +} + +# if neither specified, assume both +if (! $ipv4 && ! $ipv6) { + $ipv4 = $ipv6 = 1; +} + +foreach my $cc (@ARGV) { + if ($cc !~ m/^([a-z]{2}|a[12]|o1)$/i) { + print STDERR "Invalid country code '$cc'\n"; + exit 1; + } + + my $file = $target_dir . '/' . uc($cc) . '.iv4'; + + if (! -f $file) { + printf STDERR "Can't find data for country '$cc'\n"; + exit 1; + } + + my ($contents, $buffer, $bytes, $fh); + + if ($ipv4) { + open($fh, '<', $file) || die "Couldn't open file for '$cc'\n"; + + binmode($fh); + + while (($bytes = read($fh, $buffer, AF_INET_SIZE * 2)) == AF_INET_SIZE * 2) { + my $start = inet_ntop(AF_INET, substr($buffer, 0, AF_INET_SIZE)); + my $end = inet_ntop(AF_INET, substr($buffer, AF_INET_SIZE)); + print $start, '-', $end, "\n"; + } + close($fh); + if (! defined $bytes) { + printf STDERR "Error reading file for '$cc'\n"; + exit 1; + } elsif ($bytes != 0) { + printf STDERR "Short read on file for '$cc'\n"; + exit 1; + } + } + + substr($file, -1) = '6'; + + if ($ipv6) { + open($fh, '<', $file) || die "Couldn't open file for '$cc'\n"; + + binmode($fh); + + while (($bytes = read($fh, $buffer, AF_INET6_SIZE * 2)) == AF_INET6_SIZE * 2) { + my $start = inet_ntop(AF_INET6, substr($buffer, 0, AF_INET6_SIZE)); + my $end = inet_ntop(AF_INET6, substr($buffer, AF_INET6_SIZE)); + print $start, '-', $end, "\n"; + } + close($fh); + if (! defined $bytes) { + printf STDERR "Error reading file for '$cc'\n"; + exit 1; + } elsif ($bytes != 0) { + printf STDERR "Short read on file for '$cc'\n"; + exit 1; + } + } +} + +exit 0; diff --git a/geoip/xt_geoip_fetch.1 b/geoip/xt_geoip_fetch.1 new file mode 100644 index 0000000000000000000000000000000000000000..df19ccaf303492a473ea32f26828d55b57606bc6 --- /dev/null +++ b/geoip/xt_geoip_fetch.1 @@ -0,0 +1,30 @@ +.TH xt_geoip_fetch 1 "2018-08-21" "xtables-addons" "xtables-addons" +.SH Name +.PP +xt_geoip_fetch \(em search packed format database for networks +.SH Syntax +.PP +\fI/usr/libexec/xt_geoip/\fP\fBxt_geoip_fetch\fP [\fB\-D\fP +\fItarget_dir\fP] [ \fB-4\fP | \fB-6\fP ] \fIcountry\fI ... +.SH Description +.PP +xt_geoip_fetch dumps the networks listed in each packed database +associated with the given countries. +.PP Options +.TP +\fB\-D\fP \fItarget_dir\fP +Specify a target directory into which the files are to be put. +.TP +\fB-4\fP +Enumerate IPv4 addresses. +.TP +\fB-6\fP +Enumerate IPv6 addresses. +.SH Application +.PP +Shell commands to enumerate Canadian IPv4 networks: +.PP +xt_geoip_fetch \-D /usr/share/xt_geoip -4 CA +.SH See also +.PP +xt_geoip_build(1) -- 2.17.1