Par Serge.
Ce script permet de détecter toute tentative de connexion SSH en essayant toute une série de nom d'utilisateur et de mot de passe: technique dite "brute force".
Tout d'abord, modifiez la variable my @WHITELIST
pour ajoutez les adresse IP que vous ne voulez jamais blacklister (pour eviter de vous auto-blacklister).
Ensuite, le script execute un script externe à chaque détection d'attaque. Dans mon cas je relance mon script de firewall (/etc/rc.d/rc.firewall
) qui relis le fichier des IPs blacklister pour les prendre en compte. Vous pouvez bien sur faire executer le script de votre choix, pour cela modifiez la variable my $EVENT
en début du script
Enfin, lors de son execution vous devez passez 3 arguments à ce script:
/var/log/messages
pour la slackware./var/cache/force.db
/var/blacklist
Copier ce script dans un répertoire de votre choix (/usr/local/sbin
par exemple) et changez les permissions:
chmod 700 /usr/local/sbin/ssh_force.pl chown root:root /usr/local/sbin/ssh_force.pl
Puis editez, en root
la crontab (tapez contrab -u
) pour y placez cette ligne:
#ssh_force */1 * * * * /usr/local/sbin/ssh_force.pl /var/log/messages /var/cache/force.db /var/blacklist
pour que le script soit executer chaque minute.
#! /usr/bin/perl -W # # # Find and return IP of ssh brute attacks # This is done by incrementally reading the log file use strict; # # Min time between two check. # my $MINRESET = 55; # How many tries before blacklist IP my $THRESOLD = 5; # IPs or IP mask that will never be blacklisted my @WHITELIST=("127.0.0.1", "192.168.0", "82.244.5.110"); # Command to run if we have blacklisted some IPs my $EVENT="/etc/rc.d/rc.firewall restart"; if ( @ARGV < 3 ) { print <<EOF usage: ssh_user.pl <sshlog> <db file> where: <sshlog> Log file where ssh auth comes. <db file> File for logging statistics and timestamp data. <blacklist> File to store blacklisted IPs EOF ; exit; } my $logFile = $ARGV[0]; my $dbFile = $ARGV[1]; my $blacklist = $ARGV[2]; my $event=0; # Be sure that logfile exist (my @lf = stat $logFile) || die( "Cannot stat log file `".$logFile."'!" ); # If blacklist file does not exist, we create it my @bf = stat ($blacklist); if (! @bf) { open ( BLACKLIST, ">".$blacklist) || die ("Cannot write blacklist file `".$blacklist."'!" ); close ( BLACKLIST ); } # dbfile store the last position in logfile my @st = stat $dbFile; my $timeSinceUpdated=0; my $logPosition=0; my $dontblack; my %count; my $ip_cur; # Create dbfile if not exist if ( ! @st ) { $timeSinceUpdated = 99999999; $logPosition = 0; } else { # If dbfile exist, get the last cur pos and last check time $timeSinceUpdated = time()-$st[9]; open( DBFILE, $dbFile ) || die( "Cannot open db file `".$dbFile."'!" ); $logPosition=<DBFILE>; close( DBFILE ); if ( $logPosition > $lf[7] ) { # Log has been truncated since last run. $logPosition = 0; } } if ( $timeSinceUpdated > $MINRESET ) # We have to do the job { open( LOGFILE, $logFile ) || die( "Cannot open log file `".$logFile."'!" ); seek( LOGFILE, $logPosition, 0 ); while( <LOGFILE> ) { chomp(); @_ = split(); if ( /sshd/ && /Failed password for/) { $dontblack=0; # If user is invalid, IP is in 13 position, if user exist IP is in 11 position if ( $_[8] =~ /invalid/) { if ( $_[12] =~ /\d+\.\d+\.\d+\.\d+/ ) { ip_cur=$_[12]; $count{$ip_cur}++; } } else { if ( $_[10] =~ /\d+\.\d+\.\d+\.\d+/ ) { $ip_cur=$_[10]; $count{$ip_cur}++; } } open ( BLACKLIST, $blacklist) || die ("Cannot open blacklist file `".$blacklist."'!" ); while ( <BLACKLIST> ) { # IP is already blacklisted if ( /$ip_cur/ ) { $dontblack=1; } } close ( BLACKLIST ); foreach my $whiteip (@WHITELIST) { # IP is in whitelist if ( $ip_cur =~ /$whiteip/) { $dontblack=1; } } if ($dontblack == "0" && $count{$ip_cur}>=$THRESOLD) { # Ip must be blacklisted open ( BLACKLIST, ">>".$blacklist) || die ("Cannot write blacklist file `".$blacklist."'!" ); print BLACKLIST $ip_cur."\n"; $event=1; close ( BLACKLIST ); } } } # Store the pos and check time open( DBFILE, ">".$dbFile ) || die( "Cannot write to db file `".$dbFile."'!" ); print DBFILE tell(LOGFILE)."\n"; close( DBFILE ); } if ($event==1) { # We must run the command system ($EVENT); }
Thèmes : #administration #scripts #serge
Sauf indication contraire, ce document est placé sous licence CC-BY-SA 3.0.