#!/usr/bin/perl # # mi@v3.sk @ 2011, WTF-PL # # Obtain maxmind's geoip database. # wget "http://geolite.maxmind.com/download/geoip/database/GeoLiteCount"\ # "ry/GeoIP.dat.gz" -O - | gzip -d > GeoIP.dat # # --replace Substitute ip with GeoIP(XX) pattern. # --regexp Supply custom matching pattern. Name back refference as IP. # --filter Filter by this country names. Can be specified multiple # times for multiple matches. # --incl Include only filtered. # --excl Exclude only filtered. # # EXAMPLES: # # * Print only slovak and france addresses # ./gbc.pl error.log --filter FR --filter SK --incl # # * Print without private (and unknown) addresses # TODO: private network class resolution: A,B,C,... # ./gbc.pl error.log --filter __ --excl # # * Print gzipped logs and replace addresses to human readable form and # exclude private (and unknown) and US addesses # zcat error*log*gz | ./gbc.pl --replace --filter __ --filter US \ # --excl | less # use strict; use warnings; use Geo::IP; use Getopt::Long; my @filter; my $incl; my $excl; my $replace; #my $re = 'client:\s(?\d+\.\d+\.\d+\.\d+)'; my $re = '(?\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'; my $x = -1; GetOptions ( "filter=s" => \@filter, "incl!" => \$incl, "excl!" => \$excl, "replace" => \$replace, "regexp=s" => \$re, ); $x = 1 if ($#filter + 1 and $excl); $x = -1 if ($#filter + 1 and $incl); my $gi = Geo::IP->open("GeoIP.dat", GEOIP_STANDARD); my %country = (); my $country; $country{$_} = 0 for (@filter); my $client; while (<>) { while (/$re/g) { $client = $+{IP} ? $+{IP} : $1; $country = $gi->country_code_by_addr($client); $country = "__" unless defined $country; s/$client/GeoIP($country)/g if ($replace); if ($#filter >= 0) { if (defined $country{$country} and $x eq -1) { print; } if (not defined $country{$country} and $x eq 1) { print; } } else { print; } } }