Table des matières
detection de l'agression
Ici se trouve les scripts permettant de détecter l'agression. Cela nécessite la librairie DBI. Nous y avons ajouté une création de fichier RRD, pour les amateurs.
mise_en_quarantaine.pl
#!/usr/bin/perl use DBI(); use strict; use Sys::Syslog qw(:DEFAULT setlogsock); use POSIX qw(setsid); use RRDs; ######################################################################### # # Paramétrage de l'application # # my $repertoire="/usr/local/etc/quarantaine"; my $rotation_max=1000; my $defaut_max_par_minute=5; my $defaut_max_par_heure=5; my $defaut_max_par_heure_interne=10; my $defaut_max_par_jour=20; my $sleep=30; my $syslog_facility="local6"; my $syslog_ident="quarantaine"; my $syslog_priority="warning"; my $RRD="/usr/local/etc/quarantaine/quarantaine.rrd"; ######################################################################## # # Variables normales # my (%attr,$option,$verbose,$key,$value,$action); my $syslog_socktype = 'unix'; # inet, unix, stream, console my $syslog_options="pid"; my $ip; my $line; my $file; my $ref; my $nb_attaquants_in; my $nb_attaquants_out; my $nb_rrd=0; my $timestamp; my $dbh; my $sth; my ($interne,$destination,$raison); my %tab_old; my %tab_actuel; my $chaine_attaquants=""; my $ancienne_chaine_attaquants=""; my $attaquant; my $retour; my ($now,$minute_avant,$heure_avant,$jour_avant); daemonize(); setlogsock $syslog_socktype; openlog $syslog_ident, $syslog_options, $syslog_facility; db_connect(); while (1) { # # On repère les maximum par minute, heure et jour # $now=time(); $minute_avant=$now-600; $heure_avant=$now-3600; $jour_avant=$now-86400; $sth = $dbh->prepare("(SELECT ip,COUNT(*) AS cip FROM ip_dangereuses WHERE interne=0 AND (timestamp > (NOW() - INTERVAL 1 HOUR)) GROUP BY ip HAVING cip>=$defaut_max_par_heure) UNION (SELECT ip,COUNT(*) AS cip FROM ip_dangereuses WHERE interne=0 AND (timestamp > (NOW() - INTERVAL 1 DAY)) GROUP BY ip HAVING cip>=$defaut_max_par_jour) UNION (SELECT ip,COUNT(distinct destination) AS cip FROM ip_dangereuses WHERE interne=1 AND (timestamp > (NOW() - INTERVAL 1 HOUR)) GROUP BY ip HAVING cip>=$defaut_max_par_heure_interne) "); if (! $sth->execute()) { syslog $syslog_priority, "%s", "Reconnexion a la base de donnees"; sleep(10); db_connect(); $sth->execute(); } # # Petite manipulation pour récupérer une liste triee # d'IP contrevenantes distinctes # undef(%tab_actuel); while ($ref=$sth->fetchrow_hashref()) { $ip=$ref->{'ip'}; $tab_actuel{$ip}=1; } $chaine_attaquants=""; $nb_attaquants_in=0; $nb_attaquants_out=0; foreach $attaquant (sort(keys(%tab_actuel))) { $chaine_attaquants.="$attaquant\n"; if ($attaquant =~ /^((193\.49\.(48|50|51|52|53|54|55|58))|(192\.93\.172)|(10\.)|(192\.168\.)|(194\.254\.(254|255)))/o) {$nb_attaquants_in++;} else {$nb_attaquants_out++;} } # # Comparaison entre l'ancienne et la nouvelle liste # if ($chaine_attaquants ne $ancienne_chaine_attaquants) { open(ATTAQUANT,">$repertoire/quarantaine.lst"); print ATTAQUANT "$chaine_attaquants"; close(ATTAQUANT); $ancienne_chaine_attaquants=$chaine_attaquants; $chaine_attaquants=~ s/ /,/g; $chaine_attaquants=~ s/\n/,/g; $chaine_attaquants=~ s/,$//; syslog $syslog_priority, "%s", $chaine_attaquants; $retour=`$repertoire/propagation.sh`; } # $nb_rrd++; if ($nb_rrd > 9) { RRDs::update ("$RRD","--template","in:out","$now:$nb_attaquants_in:$nb_attaquants_out"); $nb_rrd=0; } sleep($sleep); } $dbh->disconnect(); ############################################################################ # # Routines # sub db_connect() { $dbh = DBI->connect( "DBI:mysql:database=gestion_reseau;host=bdd.univ-tlse1.fr", "utilisateur", "mot de passe", {'RaiseError' => 1} ); if (!$dbh) { die ("Erreur de connexion à la base gestion_reseau"); } } sub daemonize { chdir '/' or die "Can't chdir to /: $!"; open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!"; open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!"; defined(my $pid = fork) or die "Can't fork: $!"; exit if $pid; setsid or die "Can't start a new session: $!"; umask 0; my $myname=$0; $0=$myname; }
Le script init
/etc/init.d/quarantaine.server
#!/bin/sh # # mise_en_quarantaine Start/Stop quarantaine.server # # chkconfig: 2345 38 62 # description: quarantaine is a very lightweight network intrusion detection tool \ # processname: mise_en_quarantaine.pl # Source function library. . /etc/init.d/functions lockfile="/var/lock/subsys/mise_en_quarantaine" prog="Quarantaine" executable="/usr/local/etc/quarantaine/mise_en_quarantaine.pl" RETVAL=0 start() { echo -n $"Starting $prog: " daemon $executable $OPTIONS RETVAL=$? echo [ $RETVAL -eq 0 ] && touch $lockfile return $RETVAL } stop() { echo -n $"Stopping $prog: " killproc $executable RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f $lockfile return $RETVAL } dostatus() { status $executable } restart() { stop start } condrestart() { [ -e $lockfile ] && restart } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) dostatus ;; restart|reload) restart ;; condrestart) condrestart ;; *) echo "Usage: $0 {start|stop|status|restart|condrestart}" exit 1 esac exit $RETVAL