Документация по ОС FreeBSD Суббота, 18.05.2024, 15:35
Приветствую Вас Гость | RSS
Меню сайта

Категории каталога
Apache [58]
DNS [25]
FTP [27]
Mail [74]
Samba [24]
Squid [46]
SSH [23]
VPN [35]
РРР [20]
Net [173]

Главная » Статьи » Сеть » Net

Сбор статистики по трафику на FreeBSD при помощи ng_ipacct [2009]
ng_ipacct – Netgraph IP accounting

Для работы этого примера необходимо иметь подгруженные модули:

  • ng_ipacct.ko
  • ng_ipfw.ko
  • ng_ksocket.ko

Убедиться в их наличии можно командой:

/sbin/kldstat

Id Refs Address Size Name
1 11 0xc0400000 35e5f8 kernel
...
3 1 0xc4ceb000 3000 
ng_ipacct.ko
4 1 0xc4cee000 4000 
ng_ksocket.ko
5 1 0xc4d6d000 2000 
ng_ipfw.ko

Если модули не загружены, то можно пересобрать ядро добавив следующее:

options NETGRAPH
options NETGRAPH_ETHER
options NETGRAPH_SOCKET
options NETGRAPH_TEE

options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT
options IPFIREWALL_FORWARD
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=1000

либо загрузить это модулями:

/sbin/kldload /boot/kernel/ng_ipfw.ko

/sbin/kldload /boot/kernel/ng_ipacct.ko

/sbin/kldload /boot/kernel/ng_ksocket.ko

Устанавливаем порт /usr/ports/net-mgmt/ng_ipacct:

cd /usr/ports/net-mgmt/ng_ipacct

make install clean


В /etc/rc.conf добавляем:

ng_ipacct_enable="YES"
ng_ipacct_modules_load="YES"

Для примера будем собирать трафик для подсети 172.16.5.0/24 с интерфейса bge1

Итак сам скрипт на PERL, пусть он находится в папке /scripts и называется ipacctd_ng.pl

#! /usr/bin/perl

$rul=64000; #номер начального правила в файере
$iface="bge1"; #интерфейс
$threshold=100000; #максимальное количество записей
$verbose="1"; #расширенная статистика
$savetime="1"; #метка юникс тайма в файл статистики
$nodename=sprintf("ipacct_%s",$iface); #имя ноды
$hookprefix=$iface; #крючочки (хуки) в нетграф ;-) 

if($ARGV[0] ne "start" and $ARGV[0] ne "show" and $ARGV[0] ne "stop" and $ARGV[0] ne "restart"){
 error();
}else{
 if($ARGV[0] eq "stop"){ #stop
 stop_ng_ipacctd($nodename);
 }elsif($ARGV[0] eq "show"){ #дампим трафик в файл
 #проверяем загружен ли ipacctd
 if(check_ipacctd($iface,$rul)==0){
 stop_ng_ipacctd($nodename);
 `/bin/sleep 3`;
 start_ng_ipacctd($nodename,$hookprefix,$rul,$iface,$verbose,$threshold,$savetime);
 }else{
 $cmd=sprintf("/usr/local/sbin/ipacctctl %s:%s checkpoint",$nodename,$hookprefix);
 `$cmd`;
 $cmd=sprintf("/usr/local/sbin/ipacctctl %s:%s show",$nodename,$hookprefix);
 `$cmd`;
 $cmd=sprintf("/usr/local/sbin/ipacctctl %s:%s clear",$nodename,$hookprefix);
 `$cmd`;
 }
 }elsif($ARGV[0] eq "start"){
 start_ng_ipacctd($dbh,$nodename,$hookprefix,$rul,$iface,$verbose,$threshold,$savetime);
 }elsif($ARGV[0] eq "restart"){
 stop_ng_ipacctd($nodename);
 `/bin/sleep 3`;
 start_ng_ipacctd($dbh,$nodename,$hookprefix,$rul,$iface,$verbose,$threshold,$savetime);
 }
}

###функция выводящая аргументы запуска==============================
sub error{
 printf "\nUsage: (start|stop|restart|show)";
 exit;
}

###функция start==================================================
sub start_ng_ipacctd{
 $net="172.16.5.0/24";
 #проверяем загруженность модулей
 @modules=("ng_ipacct.ko","ng_ipfw.ko","ng_ksocket.ko");
 foreach(@modules){
 if(chk_mdl($_)==0){
 `/sbin/kldload $_`;
 }
 }
 #формирование ноды нетграфа
 $cmd_ng=sprintf("/usr/sbin/ngctl -f- <<-SEQ
 mkpeer ipacct ctl ctl
 name .:ctl %s
 mkpeer %s: ksocket %s_in inet/raw/divert
 name %s:%s_in %s_in
 msg %s_in: bind inet/0.0.0.0:3021
 mkpeer %s: ksocket %s_out inet/raw/divert
 name %s:%s_out %s_out
 msg %s_out: bind inet/0.0.0.0:3022
 rmhook .:ctl",$nodename,$nodename,$hookprefix,$nodename,$hookprefix,$nodename,$nodename,$nodename,$hookprefix,$nodename,$hookprefix,$nodename,$nodename);

 `$cmd_ng`;
 $cmd=sprintf("/usr/local/sbin/ipacctctl %s:%s dlt RAW",$nodename,$hookprefix);
 `$cmd`;
 $cmd=sprintf("/usr/local/sbin/ipacctctl %s:%s verbose %s",$nodename,$hookprefix,$verbose);
 `$cmd`;
 $cmd=sprintf("/usr/local/sbin/ipacctctl %s:%s threshold %s",$nodename,$hookprefix,$threshold);
 `$cmd`;
 $cmd=sprintf("/usr/local/sbin/ipacctctl %s:%s savetime %s",$nodename,$hookprefix,$savetime);
 `$cmd`;

 #формируем правила в фаирволе IPFW для перенаправления трафика в ноду нетграфа
 $cmd=sprintf("/sbin/ipfw add %s divert 3021 ip from %s to any",$rul,$net);
 `$cmd`;
 $cmd=sprintf("/sbin/ipfw add %s divert 3022 ip from any to %s",$rul,$net);
 `$cmd`;
 print "ipacct has started..\n";
}

###функция stop==================================================
sub stop_ng_ipacctd{
 `sh /etc/rc.firewall`;
 $cmd=sprintf("/usr/sbin/ngctl shutdown %s:",$nodename);
 `$cmd`;
 print "ipacct has stoped..\n";
}

###функция проверки загрузки модулей================================
sub chk_mdl{
 $chk=`/sbin/kldstat | /usr/bin/awk '/$_/ {print 1}'`;
 if(!$chk){
 return 0;
 }else{
 return 1;
 }
}

###функция проверки ipacctd========================================
sub check_ipacctd{
 $ch1=$ch2=$ch3=0;
 $cmd=sprintf("/usr/sbin/ngctl list | grep %s_in",$iface); #проверяем входящий хук нетграфа
 $check=`$cmd`;
 if($check){
 $ch1=1;
 }

 $cmd=sprintf("/usr/sbin/ngctl list | grep %s_out",$iface); #проверяем исходящий хук нетграфа
 $check=`$cmd`;
 if($check){
 $ch2=1;
 }

 $cmd=sprintf("/sbin/ipfw show | grep divert"); #проверяем наличие правил в файерволе
 $check=`$cmd`;
 if($check){
 $ch3=1;
 }

 $all_ch=$ch1+$ch2+$ch3;
 if ($all_ch < 3){
 return 0; #чего-то явно не хватает
 }else{
 return 1; #все ОК!
 }
}

После старта мы можем посмотреть правила в фаирволе:


/sbin/ipfw show 64000
64000 1551459105 504714065010 divert 3021 ip from 172.16.5.0/24 to any
64000 2103320289 2367292643626 divert 3022 ip from any to 172.16.5.0/24

По команде:

/usr/sbin/ngctl list

можем посмотреть ноды и хуки нетграфа:

There are 7 total nodes:
Name: ngctl12701 Type: socket ID: 000c36ff Num hooks: 0
Name: ipacct_bge1_out Type: ksocket ID: 00097d52 Num hooks: 1
Name: ipacct_bge1_in Type: ksocket ID: 00097d51 Num hooks: 1
Name: ipacct_bge1 Type: ipacct ID: 00097d50 Num hooks: 2
Name: ipfw Type: ipfw ID: 0005f4a3 Num hooks: 0
Name: bge1 Type: ether ID: 00000002 Num hooks: 0
Name: bge0 Type: ether ID: 00000001 Num hooks: 0

Сделаем еще один маленький скриптик, который будет нам складывать статистику в файл.

Назовем его trafgen.pl

#!/usr/bin/perl

$tmp="/usr/local/var/trafd/tmp"; #папка для логов
opendir DIR,$tmp or mkdir $tmp;
closedir DIR;
$log=sprintf("%s/ipacctd.log",$tmp);
system("/scripts/ipacctd_ng.pl show >> $log"); #вызываем наш предыдущий скрипт с аргументом show

в /etc/crontab добавляем строчку:


*/5 * * * * root /scripts/trafgen.pl >/dev/null

Формат данны файла статистики при включенных опциях verbose=1 и savetime=1:
src_IP src_Port dst_IP dst_Port Proto packets bytes unixtime

Пример данных в фале:

172.16.5.211 57349 95.132.7.128 19904 6 1069 822400 1239961920
172.16.5.102 2208 217.118.24.17 7777 6 321 14958 1239961920
172.16.5.91 64835 92.100.50.249 59039 6 426 596900 1239961920
172.16.5.209 64829 77.41.95.94 43768 17 1 58 1239961923
172.16.5.76 1425 195.218.181.123 80 6 4 976 1239961924
172.16.5.188 61651 195.50.197.187 63375 6 1 48 1239961925
172.16.5.220 28988 94.179.59.61 20473 6 5 747 1239961929
....
80.252.240.202 11417 172.16.5.108 60682 17 1 47 1239961922
78.37.156.14 1451 172.16.5.220 28988 6 6 685 1239961922
97.84.143.186 17834 172.16.5.209 64829 17 2 134 1239961922
77.234.8.71 36523 172.16.5.220 28988 17 1 95 1239961924
195.189.47.2 2987 172.16.5.220 28988 17 1 131 1239961925
195.230.112.239 63403 172.16.5.220 28988 6 6 801 1239961930
60.220.156.222 27808 172.16.5.157 34613 17 4 504 1239961932
93.186.239.96 80 172.16.5.101 2720 6 3 358 1239961933

Обратите внимание, что сначала идет трафик исходящий и лишь затем входящий!!!
Все, дальше зависит только от полета Вашей фантазии (или извращенности :-) )

Вы можете обрабатывать файлы и складировать их в БД (напрмер MySQL) и т.п.

Плюсы от использования ng_ipacct:

  • держит большие объемы трафика
  • меньшая загрузка cpu по сравнению с обычным ipacct (/usr/ports/net-mgmt/ipacctd)

P.S. После пересборки ядра обязательно пересобрать порт /usr/ports/net-mgmt/ng_ipacct (если он был установлен до этого)

Чтиво:

  • man 4 ipacct
  • man 8 ipfw
  • man 4 netgraph
  • man 4 ng_ipfw


Источник: http://subnets.ru/blog/?p=920
Категория: Net | Добавил: oleg (01.12.2009) | Автор: Folio
Просмотров: 911 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Beastie

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
links

Copyright MyCorp © 2024