Часто возникает необходимость оценить насколько загружен выходной канал и кем из пользователей он загружен.
Следующий скрипт обрабатывает поток данных от tcpdump, выводит информацию об активных
соединениях, и скорости обмена по пользователям и суммарно:
#!/usr/bin/perl
# Исходные данные:
# Шаблон нашей подсети:
$us_net='10.0.0';
# IP шлюза (наш IP)
$us_ip='10.0.0.161';
# слушаем адаптер:
$interface = 'eth0' ;
# Открываем поток от tcpdump -n -i ..
open(FILE,'-|', 'tcpdump -n -i ' . $interface ) || die "Cant open file";
# Запоминаем время:
$oldt1=$oldt=time;
while(<FILE> )
{
# анализируем входной поток:
if(/([0-9]{1,3}\.[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+) \> ([0-9]{1,3}\.[0-9.]+)\: ([CEUAPRSF.]+) /)
{
$from_ip=$1;
$to_ip=$2;
$type_of_pkt=$3;
$input=0;
$output=0;
# выделяем размер данных в пакете
if( / [0-9]+\:[0-9]+\(([0-9]+)\)/ ){ $output= $1; };
# добавляем пазмер IP заголовка
$output+= 20;
# если это пакет не от пользовоталя, а к пользователю
if( ( $to_ip =~ /^$us_net/ && ! ($to_ip =~ /^$us_ip/) ) )
{
# перестраиваем вход/выход
$input=$output; $output=0;
$c=$from_ip;
$from_ip=$to_ip;
$to_ip=$c;
}
$tt=time;
# Проверяем, если это последний пакет соединения
if($type_of_pkt =~ /F/ )
{
# запоминаем время
$CON{"$from_ip $to_ip"}[3]=time;
}
else
{
# если мы узнаем об этом соединении впервые:
if( $CON{"$from_ip $to_ip"}[2] == 0 )
{
# запоминаем и инициализируем его параметры:
# счетчики входа и выхода
$CON{"$from_ip $to_ip"}[0]=0;
$CON{"$from_ip $to_ip"}[1]=0;
# время начала анализа
$CON{"$from_ip $to_ip"}[2]=$tt;
# время завершения соединения
$CON{"$from_ip $to_ip"}[3]=0;
}
# увеличиваем счетчики
$CON{"$from_ip $to_ip"}[0]+=$input;
$CON{"$from_ip $to_ip"}[1]+=$output;
}
# не анализируем SSH трафик ( -- пердпологается что мы сами
# запускаем этот скрипт через SSH соединение)
if( $to_ip ne "$us_ip.22" )
{
# увеличиваем общие счетчики
$all_in+=$input;
$all_out+=$output;
# для каждого пользователя нашей сети
if( $from_ip =~ /($us_net.*)\.[0-9]+/ )
{
# ведем отдельный счетчик:
$ip=$1;
$USERS{$ip}[0] += $input;
$USERS{$ip}[1] += $output;
}
}
}
# Не чаще чем раз в секунду
if(time != $oldt ){
$oldt=time;
# выводим собранную информацию:
print "\n---- From ------------- To ----------------------- In ------------- Out ------ Time\n";
# для каждого соединения:
foreach $ip (keys %CON)
{
# если соединение уже закрыто:
if($CON{$ip}[3])
{
$calk_time=$CON{$ip}[3]-$CON{$ip}[2];
printf "\%-40s\t\%8u \t\%8u \t$t closed\n",$ip,$CON{$ip}[0],$CON{$ip}[1];
# Удаляем информацию о соединении через 10 секунд после закрытия:
delete @CON{$ip} if( ($oldt-$CON{$ip}[3]) > 10);
}
else
{
# соединение все еще открыто
$calk_time=$oldt-$CON{$ip}[2];
printf "\%-40s\t\%8u \t\%8u \t$t\n",$ip,$CON{$ip}[0],$CON{$ip}[1] ;
# Чтобы не загромождать экран удаляем информацию о соединениях существующих
# дольше 30 секунд по которым обмен меньше 100 байт в секунду:
delete @CON{$ip} if( $calk_time > 30 && ( ($CON{$ip}[1] + $CON{$ip}[0])/$calk_time < 100 ) ) ;
}
}
# если мы набрали статистику как минимум за 5 секунд
if( ($x=$oldt-$oldt1) >= 5 )
{
# выводим ее:
print "-- IP ----------- CPS in ---- CPS out --\n";
# для каждого пользователя
foreach $ip (keys %USERS)
{
# усредняем за секунду:
$input=$USERS{$ip}[0]/$x;
$output=$USERS{$ip}[1]/$x;
if( ($input+$output) >= 0.1 ){ printf "\%-16s\%8u \%8u\n",$ip,$input,$output; }
# апроксимируем за 4 секунды:
$USERS{$ip}[0]=$input*4;
$USERS{$ip}[1]=$output*4;
}
# сумарный трафик: усредняем за секунду:
$input=$all_in/$x;
$output=$all_out/$x;
printf "CPS: in:%.1f\tout:%.1f\n",$input,$output;
# сумарный трафик: апроксимируем за 4 секунды:
$all_in=$input*4;
$all_out=$output*4;
$oldt1=$oldt-4;
}
$oldt=time;
}
};
Пример результата работы скрипта:
---- From ------------- To ----------------------- In ------------- Out ------ Time
10.0.0.40.1707 10.0.0.161.3128 617 407 10
10.0.0.12.53435 198.65.166.156.443 20 24 12
10.0.0.4.2030 64.12.163.132.80 20 20 12
10.0.0.40.1705 10.0.0.161.3128 2876 672 10
10.0.0.40.1701 10.0.0.161.3128 558 593 0 closed
10.0.0.40.1706 10.0.0.161.3128 834 601 0 closed
10.0.0.12.51428 198.65.166.166.5222 20 24 12
10.0.0.40.1704 10.0.0.161.3128 241 607 0 closed
10.0.0.40.1700 10.0.0.161.3128 623 418 1 closed
10.0.0.40.1703 10.0.0.161.3128 242 620 1 closed
10.0.0.44.1653 10.0.0.161.3128 647 244 20 closed
10.0.0.160.1496 10.0.0.161.3128 20 126 32
10.0.0.12.35777 216.239.51.125.5222 20 42 12
10.0.0.12.48391 10.0.0.161.22 13340 1528 282
10.0.0.12.53637 205.188.9.248.5190 1529 414 237
10.0.0.4.2031 64.12.163.132.80 960 1225 282
10.0.0.40.1699 10.0.0.161.3128 27230 916 1 closed
10.0.0.40.1702 10.0.0.161.3128 518 449 1 closed
-- IP ----------- CPS in ---- CPS out --
10.0.0.160 0 0
10.0.0.40 1904 342
10.0.0.44 9 5
10.0.0.4 1 1
10.0.0.99 0 0
10.0.0.12 5 7
CPS: in:1921.4 out:358.6
|
Задать вопросы и высказать предложения по защите сети вы можете на нашем форуме
|