Инструменты пользователя

Инструменты сайта


doc:os:freebsd:ng_ipacct:ng_ipacct

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
doc:os:freebsd:ng_ipacct:ng_ipacct [d.m.Y H:i] dbehterevdoc:os:freebsd:ng_ipacct:ng_ipacct [d.m.Y H:i] (текущий) – внешнее изменение 127.0.0.1
Строка 1: Строка 1:
 ====== Подсчет траффика с помощью ng_ipacct ====== ====== Подсчет траффика с помощью ng_ipacct ======
  
-Советую для начала прочитать, что такое netgraph.+Советую для начала прочитать, что такое netgraph. Например, вот [[http://www.opennet.ru/base/net/all_about_netgraph.txt.html|здесь]].
  
 Среда окружения: Среда окружения:
Строка 16: Строка 16:
 </code> </code>
  
-Порядок действий:+===== Порядок действий =====
  
 **1.** Устанавливаем порты: **1.** Устанавливаем порты:
Строка 30: Строка 30:
 mkdir -p /var/scripts/ng_stat/etc mkdir -p /var/scripts/ng_stat/etc
 mkdir /var/scripts/ng_stat/bin mkdir /var/scripts/ng_stat/bin
 +mkdir /var/scripts/ng_stat/log
 </code> </code>
  
Строка 96: Строка 97:
 # Читаем конфиг. файл. # Читаем конфиг. файл.
 ######################### #########################
-open (CONFIG, "/usr/local/script/ng_stat/etc/ng_stat.conf");+open (CONFIG, "/var/scripts/ng_stat/etc/ng_stat.conf");
  
 while (<CONFIG>) { while (<CONFIG>) {
Строка 550: Строка 551:
 # Читаем конфиг. файл. # Читаем конфиг. файл.
 ######################### #########################
-open (CONFIG, "/usr/local/script/ng_stat/etc/ng_stat.conf");+open (CONFIG, "/var/scripts/ng_stat/etc/ng_stat.conf");
 while (<CONFIG>) { while (<CONFIG>) {
     $comment = '#';     $comment = '#';
Строка 667: Строка 668:
 **8.** Cоздаем скрипт /var/scripts/ng_stat/bin/ng_stat_in.pl: **8.** Cоздаем скрипт /var/scripts/ng_stat/bin/ng_stat_in.pl:
 <code> <code>
 +#!/usr/bin/perl -w
  
 +use DBI;
 +use Time::localtime;
 +use POSIX ":sys_wait_h";
 +
 +#########################
 +# Список основных переменных
 +#########################
 +my $serverdb = "test";
 +my $dbname = "test";
 +my $dbuser = "test";
 +my $dbpass = "test";
 +my $table_auth = "test";
 +my $table_proto = "test";
 +my $listen_host = "test";
 +my @listen_interf;
 +my $iface_set = "no";
 +my @ng_modules;
 +my $ng_modules_def = "netgraph,ng_ether,ng_socket,ng_tee,ng_ipacct";
 +my $threshold = 5000;
 +my $ipacct_log = '/var/scripts/ng_stat/log/ng.log';
 +my @ipacct_arr;
 +my @ipacct_arr_in;
 +##########################
 +# Читаем конфиг. файл.
 +#########################
 +open (CONFIG, "/var/scripts/ng_stat/etc/ng_stat.conf");
 +
 +while (<CONFIG>) {
 +    $comment = '#';
 +    if(/^$comment/) {
 +#    print "Коментарий\n";
 +    }
 +    else {
 +    my ($param,$arg) = split("=",$_);
 +    chomp $param;
 +    chomp $arg;
 +    $param =~ s/[\s\t]+//g;
 +    $arg =~ s/[\s\t]+//g;
 +    if ($param eq "server_db"){
 +        $serverdb = $arg;
 +    }
 +    if ($param eq "db_name"){
 +        $dbname = $arg;
 +    }
 +    if ($param eq "db_user") {
 +        $dbuser = $arg;
 +    }
 +    if ($param eq "db_pass") {
 +        $dbpass = $arg;
 +    }
 +    if ($param eq "table_auth") {
 +        $table_auth = $arg;
 +    }
 +    if ($param eq "table_protocols") {
 +        $table_proto = $arg;
 +    }
 +    if ($param eq "stat_file") {
 +        $ipacct_log = $arg;
 +    }
 +    if ($param eq "listen_host") {
 +        $listen_host = $arg;
 +    }
 +    if ($param eq "listen_interfaces") {
 +        my $coma = ',';
 +        if ($arg =~ m/$coma/ ) {
 +            @listen_interf=split($coma,$arg);
 +            }
 +        else {
 +        @listen_interf = $arg;
 +        }
 +    }
 +    if ($param eq "ng_modules") {
 + my $coma = ',';
 +        if ($arg =~ m/$coma/ ){
 +            @ng_modules = split($coma,$arg);
 +        } else {
 +
 +            @ng_modules = split ($coma,$ng_modules_def);
 +        }
 +
 +    }
 +    if ($param eq "threshold") {
 +        $threshold = $arg;
 +    }
 +
 +    }
 +}
 +close (CONFIG);
 +
 +#########################
 +# Проверяем время.
 +#########################
 +$gm = localtime();
 +$year = ($gm->year()) + 1900;
 +$mounth = ($gm->mon()) + 1;
 +$mday = $gm->mday();
 +$date = "$mday-$mounth-$year";
 +$hour = $gm->hour();
 +$min = $gm->min();
 +$sec = $gm->sec();
 +$hour=sprintf("%02d",$hour);
 +$min=sprintf("%02d",$min);
 +$sec=sprintf("%02d",$sec);
 +$time = "$hour\:$min\:$sec";
 +$table_date = "$year\_$mounth";
 +
 +if (!defined $listen_interf[0]) {
 +    print "Установите пожалуйста в режим прослушивания хотя бы один интерфейс.\n";
 +}
 +else {
 +
 + while (@listen_interf){
 + $interface = shift @listen_interf;
 + my $pid;
 + $pid = fork;
 + if (defined $pid) {
 + if ($pid == 0){
 +#$IPACCTCTL ${IFACE}_ip_acct:$IFACE checkpoint
 + exec "/usr/local/sbin/ipacctctl $interface\_ip_acct:$interface checkpoint" or die "Ошибка передачи записи в checkpoint-базу!\n";
 + exit;
 + }
 + }
 + else {
 + print "Фатальная ошибка ветвления!\n.................\n";
 + die "Разделение на процессы не возможно.\n Принудительный выход из дочернего процесса: $!\n";
 + }
 + do {
 + $kid = waitpid $pid,0;
 + if ($kid == -1) {
 + print "Дочерних процессов в системе нет или система не поддерживает их.\n Ошибка!" and die "Выход!\n";
 + } elsif ($kid == 0) {
 + print "Задан не блокирующий вызов и процесс еще не завершен!\n";
 + }
 + } until $kid=$pid;
 +
 + undef $pid;
 +
 + $pid = fork;
 + if (defined $pid) {
 + if ($pid == 0){
 +#$IPACCTCTL ${IFACE}_ip_acct:$IFACE show >> $DIR/$SDIR/$NAME
 + exec "/usr/local/sbin/ipacctctl $interface\_ip_acct:$interface show >> $ipacct_log\.$interface" or die "Ошибка передачи записей из checkpoint-базы в файл!\n";
 + exit;
 + }
 + }
 + else {
 + print "Фатальная ошибка ветвления!\n.................\n";
 + die "Разделение на процессы не возможно.\n Принудительный выход из дочернего процесса: $!\n";
 + }
 + do {
 + $kid = waitpid $pid,0;
 + if ($kid == -1) {
 + print "Дочерних процессов в системе нет или система не поддерживает их.\n Ошибка!" and die "Выход!\n";
 + } elsif ($kid == 0) {
 + print "Задан не блокирующий вызов и процесс еще не завершен!\n";
 + }
 + } until $kid=$pid;
 +
 + undef $pid;
 +
 + $pid = fork;
 + if (defined $pid) {
 + if ($pid == 0){
 +#$IPACCTCTL ${IFACE}_ip_acct:$IFACE clear
 + exec "/usr/local/sbin/ipacctctl $interface\_ip_acct:$interface clear" or die "Ошибка при очистке checkpoint-базы! \nБаза не очищена. Возможно переполнение. Очистите базу в ручную\n";
 + exit;
 + }
 + }
 + else {
 + print "Фатальная ошибка ветвления!\n.................\n";
 + die "Разделение на процессы не возможно.\n Принудительный выход из дочернего процесса: $!\n";
 + }
 + do {
 + $kid = waitpid $pid,0;
 + if ($kid == -1) {
 + print "Дочерних процессов в системе нет или система не поддерживает их.\n Ошибка!" and die "Выход!\n";
 + } elsif ($kid == 0) {
 + print "Задан не блокирующий вызов и процесс еще не завершен!\n";
 + }
 + } until $kid=$pid;
 +
 + undef $pid;
 +
 + $TMPLOG= "$ipacct_log\.$interface";
 + open (TMPLOG, "$TMPLOG");
 + $TMPLOG =~ s/\||`|&&|<|>//gi; #Очистка ряда символов | ` && < > из пути к файлу.
 + while (<TMPLOG>){
 + $tmp_log_line=$_;
 + chomp $tmp_log_line;
 + $tmp_log_line = "$tmp_log_line $date $time $listen_host $interface";
 + push @ipacct_arr,$tmp_log_line;
 + }
 + close (TMPLOG);
 + truncate ($TMPLOG,0);
 +
 +
 + undef $pid;
 + }
 +
 + open (IPCTLOG,">>$ipacct_log");
 + while (@ipacct_arr){
 +
 + $line_arr = shift @ipacct_arr;
 + $line_arr = "$line_arr\n";
 + print IPCTLOG $line_arr;
 +
 + }
 + close(IPCTLOG);
 +
 + &parse_log_file;
 + &check_in_mysql;
 + &insert_data_db;
 +}
 +
 +sub check_in_mysql {
 +
 +my ($dbh,$sth,$count);
 +$dbh = DBI->connect("DBI:mysql:host=$serverdb;database=$dbname","$dbuser","$dbpass")
 +                or &error_connection;
 +$sth = $dbh->prepare("SHOW tables");
 +$sth->execute ();
 +my @row;
 +my $tables;
 +while (@row = $sth->fetchrow_array) {
 + foreach $tables (@row){
 + push @dbtables, $tables;
 + }
 +}
 +$crt_tbl="yes";
 +while (@dbtables) {
 + $table = shift @dbtables;
 + if (defined $table) {
 + if ($table eq $table_date) {
 + $crt_tbl="no";
 + }
 + }
 +}
 +
 +if ($crt_tbl eq "yes") {
 + print "Создаем таблицу\n";
 + &crt_table_log;
 +}
 +
 +$sth->finish;
 +$dbh->disconnect;
 +
 +}
 +
 +sub error_connection {
 +
 +print "Проверьте правильность имени и пароля на базу в MySQL, ее существование\n";
 +print "Возможной причиной так же может являться то, что сервер временно не доступен\n";
 +print "Будет произведено копирование всех данных в файл:\n\n$ipacct_log \n\n";
 +print "Накопление статистики в файл не лимитипровано, но это может повлечь за собой";
 +print " всплеск нагрузки на сеть и сервера. По этому обратите внимание на данное";
 +print " сообщение и выясните конкретную причину.\n";
 +foreach $line_arr(@ipacct_arr_in) {
 + open (DUMPFILE, ">>$ipacct_log");
 + $line_arr = "$line_arr\n";
 + print DUMPFILE $line_arr;
 + close (DUMPFILE);
 +}
 +die "Выход.\n";
 +
 +}
 +
 +sub crt_table_log {
 +
 + my ($dbh,$sth,$count);
 + $dbh = DBI->connect("DBI:mysql:host=$serverdb;database=$dbname","$dbuser","$dbpass"
 + or &error_connection;
 + $select = "CREATE  TABLE $table_date (ip_from varchar(255),s_port varchar(128),ip_to varchar(255),d_port   varchar(128), proto varchar(32), packets int(8), bytes int(16) default 0,date_ins varchar(32), time_ins time,host  varchar(128), interface varchar(8),index (ip_from),index (ip_to),index (proto),index (packets), index (bytes),index (host), index (time_ins), index (date_ins), index (interface))";
 + $sth = $dbh->prepare("$select");
 + $sth->execute ();
 + $sth->finish;
 + $dbh->disconnect;
 +
 +}
 +
 +sub insert_data_db {
 +my ($dbh,$sth,$count);
 +$dbh = DBI->connect("DBI:mysql:host=$serverdb;database=$dbname","$dbuser","$dbpass")
 +                or &error_connection_in;
 +$insert = "INSERT INTO $table_date (ip_from,s_port,ip_to,d_port,proto,packets,bytes,date_ins,time_ins,host,interface) VALUES (?,?,?,?,?,?,?,?,?,?,?)";
 +
 +$sth = $dbh->prepare("$insert");
 +#print "$insert\n";
 +while (@ipacct_arr_in) {
 + $line_in = shift @ipacct_arr_in;
 + ($ip_from,$s_port,$ip_to,$d_port,$proto,$packets,$bytes,$date_ins,$time_ins,$host,$interface)=split(/[\s\t]+/,$line_in);
 + if (!defined $proto){
 + $proto="0";
 + }
 + if (!defined $packets){
 + $packets="0";
 + }
 + if (!defined $bytes){
 + $bytes="0";
 + }
 + $sth->execute ($ip_from,$s_port,$ip_to,$d_port,$proto,$packets,$bytes,$date_ins,$time_ins,$host,$interface);
 +}
 +
 +$sth->finish;
 +$dbh->disconnect;
 +}
 +
 +sub parse_log_file {
 +open (PARSFILE, "$ipacct_log");
 +while ($line_parse=<PARSFILE>) {
 +        chomp $line_parse;
 +        $line_parse =~ s/[\s\t]+/\t/g;
 +        push @ipacct_arr_in, $line_parse;
 +}
 +close (PARSFILE);
 +truncate ("$ipacct_log",0);
 +}
 +
 +exit(0);
 </code> </code>
 +
 +**8.1** Делаем скрипт исполняемым.
 +
 +**8.2** Выполняем скрипт. Смотрим на ошибки. 
 +
 +Итак, за каждый месяц должна автоматически создаваться табличка со столбцами:
 +<code>
 ++-----------------+--------+-----------------+--------+-------+---------+---------+----------+----------+-----------+-----------+
 +| ip_from         | s_port | ip_to           | d_port | proto | packets | bytes   | date_ins | time_ins | host      | interface |
 ++-----------------+--------+-----------------+--------+-------+---------+---------+----------+----------+-----------+-----------+
 +</code>
 +
 +**8.3** Помещаем вызов скрипта ng_stat_in.pl в крон:
 +<code>
 +*/15 * * * * root /var/scripts/ng_stat/bin/ng_stat_in.pl
 +</code>
 +
 +TAG: {{tag> ng_ipacct FreeBSD}} 
 +
 +~~DISCUSSION~~
/var/www/wiki.itcall.ru/data/attic/doc/os/freebsd/ng_ipacct/ng_ipacct.1302370942.txt.gz · Последнее изменение: d.m.Y H:i (внешнее изменение)