Когда я в конференции ru.unix.solaris поинтересовался чем можно считать трафик, то мне предложили на выбор несколько вариантов. От подсчёта с помощью правил файрвола, до установки gnu-программ. Учитывая, что Solaris поддерживает библиотеку pcap
, теоретически можно использовать любые системы учёта трафика построенные на её основе. Но хотелось использовать родные средства Solaris’а. И они есть – extended accounting
. Вообще-то, extended accounting
это отдельная песня. Это очень мощное средство позволяющее учитывать используемые ресурсы позадачно и попроцессно. А в составе системы поддержки QoS и учитывать трафик. В начале меня несколько насторожил тот факт, что для поднятия учёта надо поднимать и систему QoS, но, подумав, понял, в этом есть определённый смысл. Например, хотя бы в том, что если мы что-то и продаём, то это должно быть определённого качества. 🙂
Как включить extended accounting
подробно описано в руководстве по Solaris’у. Единственная замеченная мной неточность, заключается в том, что при внесении сконфигурированных данных с помощью ipqosconf
для модуля ipgpc создаётся класс default. Вот он почему-то не описан. И, честно говоря, как отключить его создание я не знаю. Не в одном найденном мной примере он не упоминается. Поборол я это дело простым описанием оного в своём конфигурационном файле:
fmt_version 1.0
action {
module ipgpc
name ipgpc.classify
params {
global_stats TRUE
}
class {
name default
next_action acct
enable_stats TRUE
}
action {
module flowacct
name acct
params {
global_stats TRUE
timer 10000
timeout 10000
max_limit 2048
next_action continue
}
}
Как видите, это очень простая конфигурация, предусматривающая полный контроль всего проходящего трафика. В примерах показаны куда как более навороченные конфигурации позволяющие, например, контролировать и выделяемую полосу пропускания к определенным сетевым ресурсам – хоть компьютерам, хоть сервисам.
Следующим этапом надо было научиться извлекать данные из файла в который складываются данные по трафику. Можно просто взять пример из документации, и натравить его на наш файл и получить некую информацию. Но она несколько неудобоварима для восприятия. Поэтому, пришлось подкорректировать этот перловый скрипт для получения статистики в более осмысленном виде. Для его работы пришлось доставить пакет NetAddr-IP
взятый со CPAN’а. Вот что получилось в итоге:
#!/usr/perl5/5.6.1/bin/perl
use strict;
use Sun::Solaris::Exacct qw(:EXACCT_ALL);
use NetAddr::IP ':aton';
die("Usage is dumpexacct <exacct file>\n") unless (@ARGV == 1);
# Open the exact file and display the header information.
my $ef = ea_new_file($ARGV[0], &O_RDONLY) || die(error_str());
printf("Creator: %s\n", $ef->creator());
printf("Hostname: %s\n\n", $ef->hostname());
# Dump the file contents
while (my $obj = $ef->get()) {
dump_object($obj);
}
# Report any errors
if (ea_error() != EXR_OK && ea_error() != EXR_EOF) {
printf("\nERROR: %s\n", ea_error_str());
exit(1);
}
exit(0);
sub dump_object {
my ($obj) = @_;
my @cat = $obj->catalog()->value();
my %rec = ();
if ($obj->type() == &EO_ITEM) {
my $val = $obj->value();
if (ref($val)) {
# сюда, в нашем случае, скорее всего, ни когда не попадём
dump_object($val);
} else {
# А отсюда возврат в вызов расположенный ниже
return ($cat[2], $val);
}
} else {
foreach my $val ($obj->value()) {
# Вот тот самый вызов в который возвращаемся по return’у
my ($c, $v) = dump_object($val);
if($c eq 'EXD_FLOW_V4SADDR'){$rec{'saddr'} = inet_aton($v)}
elsif($c eq 'EXD_FLOW_V4DADDR'){$rec{'daddr'} = inet_aton($v)}
elsif($c eq 'EXD_FLOW_SPORT'){$rec{'sport'} = $v}
elsif($c eq 'EXD_FLOW_DPORT'){$rec{'dport'} = $v}
elsif($c eq 'EXD_FLOW_PROTOCOL'){$rec{'proto'} = $v}
elsif($c eq 'EXD_FLOW_DSFIELD'){$rec{'dsfld'} = $v}
# Здесь localtime стоит только для отладки.
elsif($c eq 'EXD_FLOW_CTIME'){$rec{'ctime'} = localtime $v}
elsif($c eq 'EXD_FLOW_LSEEN'){$rec{'lseen'} = $v}
elsif($c eq 'EXD_FLOW_NBYTES'){$rec{'nbytes'} = $v}
elsif($c eq 'EXD_FLOW_NPKTS'){$rec{'npkts'} = $v}
}
}
# Здесь делаем какую-либо обработку полученных данных. Например, выводим на экран
if (defined $rec{'npkts'} ) {
printf("%s %s %s %s %s %s %s %s\n",
$rec{'ctime'}, $rec{'saddr'}, $rec{'daddr'},
$rec{'sport'}, $rec{'dport'}, $rec{'proto'},
$rec{'nbytes'}, $rec{'npkts'}, $rec{'lseen'}, $rec{'dsfld'});
}
}
#--------------------
sub inet_aton {
my $a = shift;
my $ip = new NetAddr::IP($a);
return $ip;
}
Этот скрипт выводит статистику так как я привык её видеть. У меня пока остались вопросы по ротации файла, из которого мы берём эти данные, но мысли о том как её реализовать уже есть. Будем попробовать.
молодая поросль отвечает - прячьте объемную техническую статью за тизером, пользуйтесь тегом ! статью не осилил из-за отсутствия квалификации
fixed
теперь на блоге красиво-то как! 🙂
Уведомление: Software Development Guide