#!/usr/bin/perl -w # # ssh-black.pl par Bernard FRIT le 18 février 2005 # # v.0.4 use strict; use Socket; # nom du programme my($PROG) = 'ssh-black.pl' ; # version du programme my($VER) = '0.4' ; ################## Configuration ############################################################ # path du fichier log a analyser my($LOG) = '/var/log/messages'; # path du répertoire contenant les Ips en cours d'analyse my($TMP) = '/root/tmp/Ips' ; # path du répertoire contenant les Ips blacklistées my($BLACK) = '/root/tmp/Ips-black' ; # nombre de tentatives autorisées my($MAX) = 3 ; # ajoutez ici vos Ips fixes si vous le souhaitez. my($LOCALNET) = '^(127\.0\.0\.1|192\.168\.0)'; # path d'Iptables my($IPTABLES) = '/sbin/iptables'; # chaines de caractères à rechercher dans les logs. my($REASONS) = '(Illegal user|illegal user|Failed password|failed password)'; ################## Fin de Config ############################################################ my($IP) = '[0-9]{1,3}(\.[0-9]{1,3}){3}'; my($HOST) = `uname -n` ; chop($HOST); $HOST =~ /^(.+)(\..+){0,3}/ ; $HOST = $1 ; my($INFO) = " $HOST $PROG v.$VER($$): "; print scalar localtime, $INFO, "Initializing...\n"; taillog(); sub taillog { my($offset, $name, $line, $ip, $reason); $offset = (-s $LOG); # Don't start at begining, go to end # $offset=0; while (1==1) { sleep(1); $| = 1; if ((-s $LOG) < $offset) { print scalar localtime,$INFO,"Log shrunk, resetting..\n"; $offset = 0; } open(TAIL, $LOG) || print STDERR "Error opening $LOG: $!\n"; if (seek(TAIL, $offset, 0)) { # found offset, log not rotated } else { # log reset, follow $offset=0; seek(TAIL, $offset, 0); } while ($line = ) { chop($line); if (($REASONS) && ($line =~ m/$REASONS/)) { $reason = $1; if ($line =~ m/($IP)/) { $ip = $1; if (evalIp($ip)) { print scalar localtime, $INFO, "$ip blacklisted (ssh: $reason) \n"; } } elsif ($line =~ m/from ([a-zA-Z0-9\.\-]+)/) { $ip = $1; if ($ip) { if (evalIp($ip)) { print scalar localtime, $INFO, "$ip blacklisted (ssh: $reason) \n"; } } else { print scalar localtime, $INFO, "Failed to find IP: $line\n"; } } else { print scalar localtime, $INFO, "Should have blocked?: $line\n"; } next; } } $offset=tell(TAIL); close(TAIL); } } sub evalIp { my($ip) = @_; my($cnt) = 1 ; if ($ip =~ m/$LOCALNET/) { return; } if (-e("$TMP/$ip")) { $cnt = `cat $TMP/$ip` ; chop($cnt) ; if (($cnt++>$MAX) and (!-e("$BLACK/$ip"))){ blockIp($ip) ; `mv $TMP/$ip $BLACK/$ip` ; return 1 ; } } `echo $cnt > $TMP/$ip` ; } sub blockIp { my($ip) = @_; my(@args) = ($IPTABLES, '-I', 'INPUT', '--source', $ip, '-j', 'REJECT', '--reject-with', 'icmp-host-prohibited'); # print "system(@args)\n"; system(@args) ; }