grosse mise jour

darcs-hash:20020207083250-a279a-8b385c6ade091c34835319ecf9e9cddb026bf9bb.gz
This commit is contained in:
stransky 2002-02-07 09:32:50 +01:00
parent 0251e928a9
commit 6165b51cd2

View file

@ -2,16 +2,14 @@
## ##
## Analyse.pl ## Analyse.pl
## ##
## Made by Tab <rv@crans.org> ## Made by Vincent HANQUEZ <rv@crans.org>
## ##
## Started on Tue 09 Oct 2001 01:28:25 AM CEST tab ## Started on Tue 09 Oct 2001 01:28:25 AM CEST tab
## Last Update mer 30 jan 2002 19:56:00 CET Nicolas STRANSKY ## Last Update jeu 07 fév 2002 08:47:59 CET Nicolas STRANSKY
##
## ##
## This program is free software; you can redistribute it and/or modify ## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by ## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or ## the Free Software Foundation; only version 2 of the License
## (at your option) any later version.
## ##
## This program is distributed in the hope that it will be useful, ## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of ## but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -24,214 +22,229 @@
## ##
## ##
## AUTEUR: Tab ## AUTEUR: Tab
## MAINTAINERS: Nico, Tab ## MAINTAINERS: Tab, Nicolas STRANSKY
## ##
## DESCRIPTION: analyse permet de creer des resumes des fichiers de ## DESCRIPTION: analyse permet de creer des resumes des fichiers de
## log cree par net-acct. Net-acct est un daemon qui permet de logguer toutes ## log cree par net-acct. Net-acct est un daemon qui permet de logguer toutes
## les connexions effectues. ## les connexions effectues.
## ##
## SYNOPSIS: analyse (-d|-u) [-h <host>] [-m <to>] [-n <nb>] [-f <file>] ## SYNOPSIS: analyse [-d] [-h <host>][-m <to>][-n <nb>][-f <file>]
##
## VERSION: 0.35
## ##
## VERSION: 0.2
## ##
use strict; use strict;
use IO::Socket; use File::stat;
use POSIX qw(strftime);
use AppConfig qw(:expand :argcount);
require Mail::Send;
my $inputfile = "/var/log/net-acct/net-acct.log.0";
my $host = "";
my $download = 0;
my $nombre_line_affiche = -1;
my $dns_resolve = 1;
my $ip_interne = "138\.231\.1(3[6-9]|4[0-3])\."; my $ip_interne = "138\.231\.1(3[6-9]|4[0-3])\.";
## Do not modify after
my $VERSION = 0.35;
my $AUTEUR = "Vincent HANQUEZ (aka Tab)";
my $pattern_ip =
"[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}";
my ($opt_download, $opt_upload) = 0;
my $opt_dnsresolve = 1;
my $opt_normalize = 1;
my $opt_config = 1;
my $opt_file = "/var/log/net-acct/net-acct.log.0";
my $opt_configfile = "/etc/analyse.conf";
my $opt_host = "";
my $opt_mail = "";
my $opt_number = -1;
my $bad_arg = 0;
$opt_upload = 1;
######## ERROR GEST ######## ######## ERROR GEST ########
# USAGE: affiche en cas d'erreur dans les arguments. # USAGE: affiche en cas d'erreur dans les arguments.
sub usage sub usage
{ {
print "Usage:\tanalyse (-d) [-h <host>][-m <to>][-n <nb>][-f <file>]\n\n"; print "Usage:\tanalyse (-d) [-h <host>][-m <to>][-n <nb>][-f <file>]\n\n";
print "\t-d, --download\tTri la base sur le download\n"; print "\t-d, --download\tTri la base sur le download\n";
print "\t-h, --host\tResume des connexions effectues par la machine <host IP>\n"; print "\t-h, --host\tResume des connexions effectues par la machine <host>\n";
print "\t-n, --nombre\tChoisi le nombre de lignes affichees\n"; print "\t-n, --nombre\tChoisi le nombre de lignes affichees\n";
print "\t-f, --file\tSpecifie le fichier qui sera analyse\n"; print "\t-m, --mail\tEnvoie la sortie par mail a <to>\n";
print "\t --nodns\tNe resout pas les noms DNS\n"; print "\t-f, --file\tSpecifie le fichier qui sera analyse\n";
print "\t --help\tAffiche cette aide\n"; print "\t-c, --config\tSpecifie le fichier de configuration\n";
print "\n"; print "\t --nodns\tNe resout pas les noms DNS\n";
print "par defaut si l'option n'existe pas:\n"; print "\t --nonorm\tNe transforme pas les nombres en forme plus lisible (Ko, Mo, Go)\n";
print "\tdownload = on tri sur l'upload\n"; print "\t --today\tChiffres du jour, analyse de /var/log/net-acct/net-acct.log\n";
print "\tnombre = tout est affiche\n"; print "\t --noconfig\tNe charge pas les options du fichier de config\n";
print "\tfile = analyse de /var/log/net-acct/net-acct.log.0\n"; print "\t --help\tAffiche cette aide\n";
print "\n";
print "par defaut si l'option n'est pas utilise:\n";
print "\tdownload = on tri sur l'upload\n";
print "\tnombre = tout est affiche\n";
print "\tfile = analyse de /var/log/net-acct/net-acct.log.0\n";
print "\tconfig = par defaut /etc/analyse.conf";
exit (1); exit (1);
} }
# SETOPT: gerer les options..
sub setopt
{
my ($opt_name, $opt_param) = @_;
if ($opt_name =~ /f/)
{ $opt_file = $opt_param; }
elsif ($opt_name =~ /h/)
{ $opt_host = $opt_param; }
elsif ($opt_name =~ /n/)
{ $opt_number = $opt_param; }
elsif ($opt_name =~ /c/)
{ $opt_configfile = $opt_param; }
elsif ($opt_name =~ /m/)
{ $opt_mail = $opt_param; }
}
# Readconfig
sub read_configfile
{
my $info = stat($opt_configfile) || die("Unable to open $opt_configfile");
my $config = AppConfig->new(
'normalize',
'dnsresolve',
'network' => { ARGCOUNT => 1 }
);
$config->file($opt_configfile);
$opt_normalize = $config->normalize();
$opt_dnsresolve = $config->dnsresolve();
$ip_interne = $config->network();
}
########## FCT ###########
# SHOW_ALL: affiche toutes les machines
sub show_all sub show_all
{ {
my $id; my %db;
my %up_db;
my %down_db;
my $max;
my ($nb_to_print, $sort_by_upload) = @_; my ($nb_to_print, $sort_by_upload) = @_;
open INPUT, $inputfile; # creation de la base
while (my $line = <INPUT>) { open (INPUT, $opt_file) || die ("Unable to open $opt_file");
my ($src_ip, $dst_ip, $size) = (split "\t", $line)[2,4,6]; while (my $line = <INPUT>) {
if ($src_ip =~ /$ip_interne/ ) { my ($src_ip, $dst_ip, $size) = (split "\t", $line)[2,4,6];
$up_db{$src_ip} += $size; if ($src_ip =~ /$ip_interne/ )
} { $db{$src_ip}->{up} += $size; }
if ($dst_ip =~ /$ip_interne/ ) { if ($dst_ip =~ /$ip_interne/ )
$down_db{$dst_ip} += $size; { $db{$dst_ip}->{down} += $size; }
} }
} close(INPUT);
close(INPUT);
if ($nb_to_print == -1) # Nombre d'entree a afficher
{ $nb_to_print = (my @nb = (keys %up_db)); } if ($nb_to_print == -1)
{ $nb_to_print = (my @nb = (keys %db)); }
$max = (keys %up_db)[0]; my $max = (keys %db)[0];
if ($sort_by_upload) {
for (my $dec=$nb_to_print; $dec > 0; $dec--) { # tris sur upload ou download
foreach my $ip (keys %up_db) { my $way1 = "up";
if ($up_db{$max} <= $up_db{$ip}) my $way2 = "down";
{ $max = $ip; } if ($sort_by_upload == 0)
} { $way1 = "down"; $way2 = "up"; }
print normalize($up_db{$max})." (".normalize($down_db{$max}).")\t".ip_to_name($max)."\n" if $up_db{$max} > 0;
$up_db{$max} = 0; # on affiche $nb_to_print entree, en ayant trier les machines
} for (my $dec = $nb_to_print; $dec > 0; $dec--)
} else { {
for (my $dec=$nb_to_print; $dec > 0; $dec--) { foreach my $ip (keys %db)
foreach my $ip (keys %down_db) { {
if ($down_db{$max} <= $down_db{$ip}) if (defined($db{$ip}->{$way1}) &&
{ $max = $ip; } $db{$max}->{$way1} <= $db{$ip}->{$way1})
} { $max = $ip; }
print normalize($down_db{$max})." (".normalize($up_db{$max}). }
")\t".ip_to_name($max)."\n" if $down_db{$max} > 0; print normalize($db{$max}->{$way1})." (".
$down_db{$max} = 0; normalize($db{$max}->{$way2}).")\t".
} ip_to_name($max)."\n" if ($db{$max}->{$way1} > 0);
} $db{$max}->{$way1} = 0;
}
} }
#############################
# GET_HOST_INFO: Affiche les informations sur une machine
sub get_host_info sub get_host_info
{ {
my $up_size = 0; my $total_size;
my $down_size = 0; my %db;
my %up_loc_db; my ($ip_search) = @_;
my %down_loc_db;
my %up_dist_db;
my %down_dist_db;
my $max;
my ($ip_search) = @_;
open INPUT, $inputfile;
while (my $line = <INPUT>) { $total_size->{UPLOAD} = 0; $total_size->{DOWNLOAD} = 0;
my ($src_ip, $src_port, $dst_ip, $dst_port, $size) =
(split "\t", $line)[2,3,4,5,6];
if ($src_ip eq $ip_search) {
$up_size += $size;
$up_loc_db{$src_port} += $size;
$up_dist_db{$dst_port} += $size;
}
if ($dst_ip eq $ip_search) {
$down_size += $size;
$down_loc_db{$dst_port} += $size;
$down_dist_db{$src_port} += $size;
}
}
close(INPUT);
print "--- Info for $ip_search ---"; # Must unresolve name
print "\n "; if (!($ip_search =~ /$pattern_ip/))
print "\nUpload: \t".normalize($up_size); { $ip_search = name_to_ip($ip_search); if ($ip_search eq "0") { return (-1); } }
print "\nPorts locaux: ";
$max = (keys %up_loc_db)[0]; # create db
for (my $dec=5; $dec > 0; $dec--) { open (INPUT, $opt_file) || die ("Unable to open $opt_file");
foreach my $port (keys %up_loc_db) { while (my $line = <INPUT>) {
if ($up_loc_db{$max} <= $up_loc_db{$port}) my ($src_ip, $src_port, $dst_ip, $dst_port, $size) =
{ $max = $port; } (split "\t", $line)[2,3,4,5,6];
} if ($src_ip eq $ip_search) {
print "$max(".normalize($up_loc_db{$max}).") " $total_size->{UPLOAD} += $size;
if ($up_loc_db{$max} > 0); $db{$src_port}->{UPLOAD_LOCAL} += $size;
$up_loc_db{$max} = 0; $db{$dst_port}->{UPLOAD_DIST} += $size;
}
print "\nPorts distants: ";
$max = (keys %up_dist_db)[0];
for (my $dec=5; $dec > 0; $dec--) {
foreach my $port (keys %up_dist_db) {
if ($up_dist_db{$max} <= $up_dist_db{$port})
{ $max = $port; }
} }
print "$max(".normalize($up_dist_db{$max}).") " if ($dst_ip eq $ip_search) {
if ($up_dist_db{$max} > 0); $total_size->{DOWNLOAD} += $size;
$up_dist_db{$max} = 0; $db{$dst_port}->{DOWNLOAD_LOCAL} += $size;
$db{$src_port}->{DOWNLOAD_DIST} += $size;
}
}
close (INPUT);
# printing info
print "--- Info for $ip_search ---";
print "\n";
foreach my $type ("UPLOAD", "DOWNLOAD")
{
print $type.": \t".normalize($total_size->{$type})."\n";
foreach my $location ("LOCAL", "DIST")
{
print "PORT $location: ";
my $max = (keys %db)[0];
for (my $dec=5; $dec > 0; $dec--) {
foreach my $port (keys %db) {
if (defined($db{$port}->{$type."_".$location}) &&
(! defined($db{$max}->{$type."_".$location}) ||
$db{$max}->{$type."_".$location} <=
$db{$port}->{$type."_".$location}))
{ $max = $port; }
}
print "$max(".normalize($db{$max}->{$type."_".$location}).") "
if ($db{$max}->{$type."_".$location} > 0);
$db{$max} ->{$type."_".$location} = 0;
}
print "\n";
}
print "\n";
} }
print "--- Calculs ---\n";
print "\n "; print "Upload pur:\t".
print "\nDownload:\t".normalize($down_size); normalize($total_size->{UPLOAD} - $total_size->{DOWNLOAD}/20);
print "\nPorts locaux: "; foreach my $type ("UPLOAD", "DOWNLOAD")
$max = (keys %down_loc_db)[0]; {
for (my $dec=5; $dec > 0; $dec--) { print "\nTAUX $type:\t";
foreach my $port (keys %down_loc_db) { print normalize($total_size->{$type}/24)."/h - ";
if ($down_loc_db{$max} <= $down_loc_db{$port}) print normalize($total_size->{$type}/1440)."/min - ";
{ $max = $port; } print normalize($total_size->{$type}/86400)."/s";
}
print "$max(".normalize($down_loc_db{$max}).") "
if ($down_loc_db{$max} > 0);
$down_loc_db{$max} = 0;
} }
print "\n";
print "\nPorts distants: ";
$max = (keys %down_dist_db)[0];
for (my $dec=5; $dec > 0; $dec--) {
foreach my $port (keys %down_dist_db) {
if ($down_dist_db{$max} <= $down_dist_db{$port})
{ $max = $port; }
}
print "$max(".normalize($down_dist_db{$max}).") "
if ($down_dist_db{$max} > 0);
$down_dist_db{$max} = 0;
}
print "\n ";
print "\n--- Quelques Calculs (Purement Informatif) ---";
print "\nUpload pur:\t".normalize($up_size - $down_size/20);
print "\nTaux download:\t";
print normalize($down_size/24)."/h - ";
print normalize($down_size/1440)."/min - ";
print normalize($down_size/86400)."/s";
print "\nTaux upload:\t";
print normalize($up_size/24)."/h - ";
print normalize($up_size/1440)."/min - ";
print normalize($up_size/86400)."/s";
print "\n\nCategoria:\t".categorie($up_size, $down_size);
print "\n(info: 20 mo download = 1 mo upload)";
} }
#sub get_db_for_host
#{
# open INPUT, $inputfile;
# my $id_port;
# my $id_ip;
#
# my ($host) = @_;
#
# print "--- Info $host ---\n";
#
# if ($option_get_upload == 1)
# { $id_ip = 2; $id_port = 3; }
# else
# { $id_ip = 4; $id_port = 3; }
#
# while (my $line = <INPUT>) {
# my ($ip, $port, $size) = (split "\t", $line)[$id_ip,$id_port,6];
# if ($ip =~ $host) {
# $db{$port} += $size;
# }
# }
#}
########################### ###########################
######### TOOLKIT ######### ######### TOOLKIT #########
# normalize: transforme un nombre, en un nombre suivi d'un prefixe # normalize: transforme un nombre, en un nombre suivi d'un prefixe
@ -239,116 +252,130 @@ sub get_host_info
sub normalize sub normalize
{ {
my ($nb) = @_; my ($nb) = @_;
if (defined $nb) { if ($opt_normalize)
if ($nb < 0) {
{ return ("0o"); } if (defined $nb) {
if ($nb > (1024*1024*1024)) if ($nb < 0)
{ return ((int($nb*100/(1024*1024*1024))/100)."Go"); } { return ("0o"); }
elsif ($nb > (1024*1024)) if ($nb > (1024*1024*1024))
{ return (int($nb/(1024*1024))."Mo"); } { return ((int($nb*100/(1024*1024*1024))/100)."Go"); }
elsif ($nb > 1024) elsif ($nb > (1024*1024))
{ return (int($nb/(1024))."Ko"); } { return (int($nb/(1024*1024))."Mo"); }
else elsif ($nb > 1024)
{ return ($nb."o"); } { return (int($nb/(1024))."Ko"); }
} else
{ return ($nb."o"); }
return ("0o"); }
return ("0");
} else
{
if (defined $nb)
{ return ($nb); }
else
{ return (0); }
}
} }
# ip_to_name: resout le nom associe a l'ip donne en argument # ip_to_name: resout le nom associe a l'ip donne en argument
sub ip_to_name sub ip_to_name
{ {
my ($ip) = @_; my ($ip) = @_;
my $ret; my $ret;
my $host_name; my $host_name;
my $aliases; my $aliases;
my $addrtype; my $addrtype;
my $length; my $length;
my @addrs; my @addrs;
if ($dns_resolve) { if (!($ip =~ /$pattern_ip/))
my $ipaddr = pack("C4", split(/\./, $ip)); { return ($ip); }
if (($host_name, $aliases, $addrtype, $length, @addrs)
= gethostbyaddr($ipaddr, 2)) { if ($opt_dnsresolve) {
return ($host_name); my $ipaddr = pack("C4", split(/\./, $ip));
} else if (($host_name, $aliases, $addrtype, $length, @addrs)
{ return ("$ip [lookup failed]"); } = gethostbyaddr($ipaddr, 2))
} { return ($host_name); }
return ($ip); else
{ return ("$ip [lookup failed]"); }
}
return ($ip);
} }
sub categorie # name_to_ip: deresout le nom
sub name_to_ip
{ {
my $upload_pure; my ($host) = @_;
my ($upload, $download) = @_; my $line = "";
if ($host =~ /$pattern_ip/)
$upload_pure = $upload - $download/20; { return ($host); }
open (COM, "host $host | awk '{print \$3}' |");
if ($upload_pure < 200*1024*1024) $line = <COM>;
{ return ("OK"); } close (COM);
if ($upload_pure < 300*1024*1024) if (! ($line =~ /$pattern_ip/))
{ return ("Avertissement"); } { print "host $host don't exist aborting\n"; return ("0");}
if ($upload_pure < 1000*1024*1024) chomp($line);
{ return ("Deconnexion 2 semaines"); } return ($line);
if ($upload_pure < 3000*1024*1024)
{ return ("Deconnexion 1 mois"); }
return ("Adios");
} }
# print_host_info: on affiche $nb (@_) ports pour l'hote. ##########################################################################
#sub print_host_info
#{
# my ($nb) = @_;
# my $max;
#
# if ($nb == -1)
# { $nb = (my @nb = (keys %db)); }
#
# for (my $dec=$nb; $dec > 0; $dec--) {
# foreach my $port (keys %db) {
# if ($db{$max} <= $db{$port})
# { $max = $port; }
# }
# print "port $max:\t".normalize($db{$max})."\n"
# if ($db{$max} > 0);
# $db{$max} = 0;
# }
#}
########################### # Lit les options de la ligne de commande
########## MAIN ########### use Getopt::Long;
Getopt::Long::config ("bundling");
Getopt::Long::GetOptions
(
'v|version' => sub { print "analyse version $VERSION\n$AUTEUR\n"; },
'd|download' => sub { $opt_download = 1; $opt_upload = 0; },
'u|upload' => sub { $opt_upload = 1; $opt_download = 0; },
'c|config=s' => \&setopt,
'h|host=s' => \&setopt,
'f|file=s' => \&setopt,
'm|mail=s' => \&setopt,
'n|number=s' => \&setopt,
'help' => \&usage,
'nodns' => sub { $opt_dnsresolve = 0; },
'nonorm' => sub { $opt_normalize = 0; },
'noconfig' => sub { $opt_config = 0; },
'today' => sub { $opt_file = "/var/log/net-acct/net-acct.log"; }
) or $bad_arg = 1;
## Options if ($bad_arg == 1)
for (my $ct = 0; $ct < @ARGV; $ct++) { usage(); }
my ($mail_msg, $mail_fh);
# Lit les options du fichier de config
# sauf si --noconfig est utilise
if ($opt_config)
{ read_configfile(); }
# Begin Mail ?
if ($opt_mail ne "")
{ {
if ($ARGV[$ct] eq '-d' || $ARGV[$ct] eq '--download') { $mail_msg = new Mail::Send;
$download = 1; $mail_fh = $mail_msg->open();
} elsif ($ARGV[$ct] eq '-h' || $ARGV[$ct] eq '--host') { $mail_msg->to($opt_mail);
if ($ARGV[$ct+1] =~ /[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}/) $mail_msg->subject("[ANALYSE]");
{ $host = $ARGV[$ct+1]; $ct++; } close (STDOUT);
else { $host = inet_ntoa((gethostbyname($ARGV[$ct+1]))[4]); $ct++; } open (STDOUT, ">/tmp/analyse_mail");
#else { usage(); } # C'est quand meme chiant de pas pouvoir utiliser les hostnames ! Allez, on implémente :) -- Nico
} elsif ($ARGV[$ct] =~ '-n' || $ARGV[$ct] eq '--nombre') {
if ($ARGV[$ct+1])
{ $nombre_line_affiche = $ARGV[$ct+1]; $ct++; }
else { usage(); }
} elsif ($ARGV[$ct] eq '-f' || $ARGV[$ct] eq '--file') {
if ($ARGV[$ct+1])
{ $inputfile = $ARGV[$ct+1]; $ct++; }
else { usage(); }
} elsif ( $ARGV[$ct] =~ '--nodns') {
$dns_resolve = 0;
} elsif ( $ARGV[$ct] =~ '--help') {
usage();
}
} }
if ($host ne "") { # Main Part
get_host_info($host); if ($opt_host ne "")
} else { { get_host_info($opt_host); }
show_all($nombre_line_affiche, !$download); else
{ show_all($opt_number, $opt_upload); }
# Close Mail
if ($opt_mail ne "")
{
close (STDOUT);
open (FH, "/tmp/analyse_mail") || die ("argh not possible !\n");
while (my $line = <FH>)
{ print $mail_fh $line; }
close (FH);
$mail_fh->close();
} }
exit (0); exit (0);