Создание  
  О компании  Программ Устройств   Linux    
  Контакты   Обучение  
    Инвестиционные проекты

LsoL

  Обслуживание    
  Продукция     Советы  
   

Полезные советы: Оценка текущего трафика, проходчщего через шлюз

Часто возникает необходимость оценить насколько загружен выходной канал и кем из пользователей он загружен. Следующий скрипт обрабатывает поток данных от 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




Задать вопросы и высказать предложения по защите сети вы можете на нашем форуме