#!/usr/bin/perl # messages から ssh 攻撃元のの一覧を出力 use Getopt::Std ; use Net::IPAddress ; my %opt = ( 's' => "SSHDENY" , 'f' => "/var/log/messages:/var/log/messages.1" , 'x' => 30 , # SPAMと判定する閾値 'm' => 24 , # サブネットマスク 'F' => 0 , # ipset を消す ) ; getopts( "s:f:x:m:F" , \%opt ) ; my $ipset_cmd = "/usr/sbin/ipset" ; my $ipset = $opt{'s'} ; my @mail_log_file = split( /:/ , $opt{'f'} ) ; my $max_allow = $opt{'x'} ; my $net_mask = $opt{'m'} ; my %host_count = () ; if ( $opt{'F'} ) { # -F ipsetを削除するだけ system( "$ipset_cmd destroy $ipset" ) ; exit( 0 ) ; } sub allow_list { my ( $ip ) = @_ ; return 1 if ( Net::IPAddress::mask( $ip , 8 ) eq "127.0.0.0" ) ; return 1 if ( Net::IPAddress::mask( $ip , 16 ) eq "192.168.0.0" ) ; return 0 ; } foreach $log ( @mail_log_file ) { open FH , $log or die( "Can't open file '$log'" ) ; while( my $line = ) { if ( $line =~ / kernel:.*\[iptables hash drop\]:.* SRC=(.*?) .* DPT=22 / ) { if ( Net::IPAddress::validaddr( $1 ) ) { my $host = Net::IPAddress::mask( "$1" , $net_mask ) ; if ( !defined( $host_count{$host} ) ) { $host_count{$host} = 1 ; } else { $host_count{$host}++ ; } } } } close FH ; } system( "$ipset_cmd create $ipset hash:net -exist" ) ; my $text = "" ; foreach my $h ( sort { $a <=> $b } keys %host_count ) { if ( !allow_list( $h ) ) { my $c = $host_count{$h} ; if ( $c > $max_allow ) { #print "$h $c\n" ; system( "$ipset_cmd add $ipset $h/$net_mask -exist" ) ; } } } ### Local Variables: ### ### mode: perl ### ### tab-width: 4 ### ### End: ###