#!/usr/bin/perl #H# This script poles the PeerGuardian2 IP lists. #H# It writes them to /etc/pf/pg2.txt #H# which is in the format that pf uses for tables. #H# There are exceptions and additional IPs stored in 2 hashes: #H# %Exceptions and %BadGuys #H# #H# Also note that this script pulls in both the p2p and spyware lists #H# even though one is a .zip file and the other is a .gz file. #H# #H# Here are the pf rules to implament this and block connections: #H# table persist file "/etc/pf/pg2.txt" #H# block in quick log on dc1 proto {tcp udp} from to dc1 #H# block return in quick log on dc0 proto {tcp udp} from any to #H# #H# Also note that you will need to increase the max size of a pf table #H# with something like: #H# set limit table-entries 400000 #H# The number needs to be at least 2x bigger than you think because you need #H# space to reload the tables. use Net::CIDR::Lite; my $cidr = Net::CIDR::Lite->new; chdir ("/tmp"); # backup the old file just in case something goes FUBAR system ("/usr/local/bin/gcp -f /etc/pf/pg2.txt /etc/pf/pg2.txt.old"); # a list of exceptions that don't get firewalled. %Exceptions=(); $Exceptions{"216.151.153.0/24"}="Astraweb"; $Exceptions{"207.246.207.0/24"}="Astraweb"; $Exceptions{"91.189.90.143"}="Torrent server for Ubuntu"; $Exceptions{"192.168.100.0/24"}="My subnet"; $Exceptions{"64.161.254.20"}="Freenode"; $Exceptions{"140.211.166.3"}="Freenode"; $Exceptions{"154.35.200.44"}="Freenode"; $Exceptions{"91.189.90.143"}="Torrent server for Ubuntu"; $Exceptions{"195.214.216.38"}="Freedb CDDB"; # a blacklist of known spammers %Spammers=(); #$BadGuys{"66.35.244.0/24"}="Sent me a Sprint spam"; # check for verbosity if ($ARGV[0] eq "-v") { $Verbose="Y"; $MVParams="-fv"; $RMParams="-fv"; } else { $Verbose="N"; $MVParams="-f"; $RMParams="-f"; } # URLs for lists %FTP=(); %FileFormat=(); $FTP{"p2p"}="http://peerguardian.sourceforge.net/lists/p2p.php"; $FTP{"spy"}="http://peerguardian.sourceforge.net/lists/spy.php"; $FileFormat{"p2p"}="7zip"; $FileFormat{"spy"}="7zip"; $FinalFileName{"p2p"}="level1"; $FinalFileName{"spy"}="spyware"; $DateString=`date +%Y%m%d%H%M%s`; chomp $DateString; $TempFile="/tmp/temp.kmk.fwpg2.$DateString"; $CIDRCount=0; foreach $NIC (keys(%FTP)) { #print (FILE "#IPs from $NIC not listed as US or CA\n"); if ($Verbose eq "Y") { print "Getting IPs from $NIC...\t"; } if ($FileFormat{$NIC} eq "gzip") { open (LIST, "wget -q -O- $FTP{$NIC} | gzip -cd |") or die "Could not get IP list from $NIC\n"; } elsif ($FileFormat{$NIC} eq "zip") { system ("wget -q -O- $FTP{$NIC} > $TempFile"); open (LIST, "/usr/local/bin/unzip -p $TempFile |"); } elsif ($FileFormat{$NIC} eq "7zip") { system ("wget -q -O- $FTP{$NIC} > $TempFile"); system ("/usr/local/bin/7za e -o/tmp -y $TempFile > /dev/null 2>/dev/null"); open (LIST,"/tmp/$FinalFileName{$NIC}"); } $Count=0; while () { $IPRange=$_; chomp $IPRange; chop $IPRange; $IPRange =~ s/.*://; if ($IPRange =~ /^\d+\.\d+\.\d+\.\d+-\d+\.\d+\.\d+\.\d+/) { $Count++; $RangeCount++; $cidr->add_range($IPRange); } else { print "I didn't like $IPRange\n"; } } close (LIST); if ($FileFormat{$NIC} eq "zip") { system ("rm -f $TempFile"); } if ($FileFormat{$NIC} eq "7zip") { system ("rm -f $TempFile /tmp/$FinalFileName{$NIC}"); } if ($Count <= 1) { close (FILE); system ("/usr/local/bin/grm $RMParams /etc/pf/pg2.txt.new"); die ("Can't get records from $NIC\n"); } if ($Verbose eq "Y") { print "added $Count.\n"; } } close (FILE); if ($Verbose eq "Y") { print "Merging connected CIDR blocks...\n"; } open (FILE, ">/etc/pf/pg2.txt.new"); $MergedCIDRCount=0; @cidr_list = $cidr->list; foreach $Block (@cidr_list) { print (FILE "$Block\n"); $MergedCIDRCount++; } print (FILE "#Known BadGuys\n"); foreach $IP (keys (%BadGuys)) { print (FILE "$IP\n"); } print (FILE "#Exceptions\n"); foreach $IP (keys (%Exceptions)) { print (FILE "!$IP\n"); } close (FILE); system ("/usr/local/bin/gmv $MVParams /etc/pf/pg2.txt.new /etc/pf/pg2.txt"); if ($Verbose eq "Y") { print "Total Ranges added: $RangeCount\n"; print "Total CIDR block after merging: $MergedCIDRCount.\n"; }