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