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

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


doc:os:freebsd:ng_ipacct:ng_ipacct

Это старая версия документа!


Подсчет траффика с помощью ng_ipacct

Советую для начала прочитать, что такое netgraph.

Среда окружения:

  • ОС FreeBSD 8.2-Stable
  • MySQL server 5.1
  • обновленное дерево портов
  • Пересобранное ядро с опциями:
options    NETGRAPH
options    NETGRAPH_ETHER
options    NETGRAPH_IFACE
options    NETGRAPH_KSOCKET
options    NETGRAPH_SOCKET

Порядок действий:

1. Устанавливаем порты:

/usr/ports/databases/p5-DBI
/usr/ports/databases/p5-DBD-mysql51

Порт p5-DBD-mysql51 должен согласовываться с вашей установленной версией MySQL server.

2. Создаем необходимые каталоги:

mkdir -p /var/scripts/ng_stat/etc
mkdir /var/scripts/ng_stat/bin

3. Создаем БД, которая будет хранить сведения по траффику, пользователя nguser с паролем pass:

# mysql -p
create database ng_stat;
grant insert,create,update,select,delete on ng_stat.* to nguser@'localhost' identified by 'pass';

4. В /var/scripts/ng_stat/etc создаем файл ng_stat.conf следующего содержания:

# Имя сервера, где находиться база данных статистики
server_db = localhost
# Имя базы данных, где будет сохраняться статистика
db_name = ng_stat
# Имя пользователи для доступа к базе
db_user = nguser
# Пароль для доступа к базе
db_pass = pass
# Таблица для авторизации пользователей через WEB.
table_auth = ipacct_auth
# Таблица со списком протоколов, эквивалент /etc/protocols
table_protocols = protocols
# Имя хоста с которого снимается статистика
listen_host = localhost
# Имена интерфейсов, которые прослушиваются на компьютере.
# Указывать через запятую
listen_interfaces = xl0,xl1
# Загружаемые модули NETGRAPH, необходимые для интерфейсов,
# которые будет обслуживать программа
# По умолчанию загружаются следующие модули: netgraph,
# ng_ether,ng_socket,ng_tee,ng_ipacct
ng_modules = netgraph,ng_ether,ng_socket,ng_tee,ng_ipacct
# Какой трешхолд необходимо установить для работы системы.
# Отнеситесь внимательно к выбору этого параметра. Он
# означает сколько записей будет храниться в буфере
# По умолчанию значение равно 5000, но если у вас меньше
# 128 Мегабайт памяти  - уменьште его.
threshold = 10000

5. В папке bin создадим свой скрипт ng_stat_start.pl:

#!/usr/bin/perl -w

use DBI;
use POSIX ":sys_wait_h";
#use strict;
#########################
# Список основных переменных
#########################
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;
#########################
# Читаем конфиг. файл.
#########################
open (CONFIG, "/usr/local/script/ng_stat/etc/ng_stat.conf");

while (<CONFIG>) {
    $comment = '#';
    if(/^$comment/) {
#    print "Коментарий\n";
    }
    else {
    ($param,$arg) = split("=",$_);
    chomp $param;
    chomp $arg;
    my $razdel = "";
    $param =~ s/[\s\t]+/$razdel/g;
    $arg =~ s/[\s\t]+/$razdel/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 "listen_host") {
        $listen_host = $arg;
    }
    if ($param eq "listen_interfaces") {
	my $coma = ',';
	if (defined $arg) {
		$iface_set = "ok";
		if ($arg ne ""){
			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);

if (!defined $listen_interf[0]) {
    print "Установите пожалуйста в режим прослушивания хотя бы один интерфейс.\n";
}
else {

    &check_kld_modules;
    &listening;
    
}

sub check_kld_modules {
    my @modules;
    my $pid;
    my $ng_module_cfg;
    my $chk_ng_file = "/tmp/ng_file";
    my $check_ng = 'kldstat -v | grep ng';
    $check_ng = "$check_ng";# " > $chk_ng_file";
    my $check_netgraph = 'kldstat -v | grep netgraph';
    $check_netgraph = "$check_netgraph";#" >> $chk_ng_file";
#    $pid = fork;

@modules =split ("\n", `$check_ng && $check_netgraph`);
my $mod;
if (defined $modules[0]) {
	foreach my $modules (@modules) {
		$modules=~ s/\d+//g;
		if ($modules =~ s/.ko//g) {
		#
		}
		else {
			$modules =~ s/[\s\t]+//g;
			$mod = "$mod $modules ";
		}
	}
	chop $mod;
	
	foreach my $ng_modules (@ng_modules) {
		if ($mod=~m/$ng_modules/g){
		#	print "$mod содержит $ng_modules\n";
		}
		else {
			my ($pid,$kid);
			
			$pid = fork;
			if (defined $pid) {
				if ($pid == 0){
					print "Загрузка необходимого модуля ",$ng_modules,"\n";
					exec "/sbin/kldload $ng_modules > /dev/null 2>&1"  or die "Ошибка загрузки модуля $ng_modules !\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;
		}
	}
}
else {
	foreach my $ng_modules (@ng_modules) {
		my ($pid,$kid);
			
		$pid = fork;
		if (defined $pid) {
			if ($pid == 0){
				print "Загрузка необходимого модуля ",$ng_modules,"\n";
				exec "/sbin/kldload $ng_modules > /dev/null 2>&1"  or die "Ошибка загрузки модуля $ng_modules !\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;
		undef $pid;
	}
	
}
}

sub listening {
	my $pid;
    $ngctl = "/usr/sbin/ngctl";
	$ipacctctl = "/usr/local/sbin/ipacctctl";
    while (@listen_interf){
    
	$interface = shift @listen_interf;
#/usr/sbin/ngctl mkpeer ${IFACE}: tee lower right
        $mkpeer = "$ngctl mkpeer $interface\: tee lower right";
	$pid = fork;
	if (defined $pid) {
		if ($pid == 0){
			print "Создание и подключение нового NETGRAPH-узла к уже существующему:\n $mkpeer\n";
			exec "$mkpeer" or die "Ошибка создания нового узла NETGRAPH!\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;
	
#/usr/sbin/ngctl connect ${IFACE}: lower upper left	
        $connect = "$ngctl connect $interface\: lower upper left";
	
	$pid = fork;
        if (defined $pid) {
                if ($pid == 0){
			print "Соединение двух NETGRAPH-узлов на интерфейсе:\n$connect\n";
        		exec "$connect" or die "Ошибка соединения двух NETGRAPH-узлов!\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;
	
#/usr/sbin/ngctl name ${IFACE}:lower ${IFACE}_acct_tee	
        $name = "$ngctl name $interface\:lower $interface\_acct_tee ";
	
	$pid = fork;
        if (defined $pid) {
                if ($pid == 0){
			print "Присвоение имени созданному узлу:\n$name\n";
        		exec "$name" or die "Ошибка на этапе присвоения имени созданному узлу!\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;

#/usr/sbin/ngctl mkpeer ${IFACE}_acct_tee: ipacct right2left ${IFACE}_in	
        $mkpeer = "$ngctl mkpeer $interface\_acct_tee: ipacct right2left $interface\_in";
	
	$pid = fork;
        if (defined $pid) {
                if ($pid == 0){
			print "Создание и подключение нового NETGRAPH-узла к уже существующему:\n $mkpeer\n";
			exec "$mkpeer" or die "Ошибка создания нового узла NETGRAPH!\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;
	
#/usr/sbin/ngctl name ${IFACE}_acct_tee:right2left ${IFACE}_ip_acct	
        $name = "$ngctl name $interface\_acct_tee:right2left $interface\_ip_acct";
	
	$pid = fork;
        if (defined $pid) {
                if ($pid == 0){
			print "Присвоение имени созданному узлу:\n$name\n";
        		exec "$name" or die "Ошибка на этапе присвоения имени созданному узлу!\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;
	
#/usr/sbin/ngctl connect ${IFACE}_acct_tee: ${IFACE}_ip_acct: left2right ${IFACE}_out
	$connect = "$ngctl connect $interface\_acct_tee: $interface\_ip_acct: left2right $interface\_out";
	
	$pid = fork;
        if (defined $pid) {
                if ($pid == 0){
			print "Соединение двух NETGRAPH-узлов на интерфейсе:\n$connect\n";
        		exec "$connect" or die "Ошибка соединения двух NETGRAPH-узлов!\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;
	
#$IPACCTCTL ${IFACE}_ip_acct:$IFACE verbose $VERBOSE	
        $verbose = "$ipacctctl $interface\_ip_acct:$interface verbose 1";

	$pid = fork;
        if (defined $pid) {
                if ($pid == 0){
			print "Установка режима вывода информации:\n$verbose\n";
        		exec "$verbose" or die "Ошибка установки режима вывода информации\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;
	
#$IPACCTCTL ${IFACE}_ip_acct:$IFACE threshold $THRESHOLD	
        $set_threshold = "$ipacctctl $interface\_ip_acct:$interface threshold $threshold";

	$pid = fork;
        if (defined $pid) {
                if ($pid == 0){
			print "Установка THRESHOLD:\n$set_threshold\n";
        		exec "$set_threshold" or die "Ошибка установки параметра THRESHOLD\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;
    }

}

exit(0);

Обсуждение

, d.m.Y H:i

With thanks, Numerous facts. casino en ligne Very good data Many thanks! casino en ligne You actually said it really well. casino en ligne Really a good deal of very good knowledge. casino en ligne fiable With thanks! I appreciate it! casino en ligne This is nicely said. ! casino en ligne France You revealed this effectively. casino en ligne Wow all kinds of great information. casino en ligne francais Incredible all kinds of excellent material. casino en ligne Seriously tons of superb data. casino en ligne

, d.m.Y H:i

With thanks, Numerous facts. casino en ligne Very good data Many thanks! casino en ligne You actually said it really well. casino en ligne Really a good deal of very good knowledge.

casino en ligne fiable With thanks! I appreciate it! casino en ligne This is nicely said. ! casino en ligne France You revealed this effectively. casino en ligne Wow all kinds of great information. casino en ligne francais Incredible all kinds of excellent material.

casino en ligne Seriously tons of superb data. casino en ligne

Ваш комментарий. Вики-синтаксис разрешён:
 
/var/www/wiki.itcall.ru/data/attic/doc/os/freebsd/ng_ipacct/ng_ipacct.1302367999.txt.gz · Последнее изменение: d.m.Y H:i (внешнее изменение)