Пишем простую систему учета трафика.

У многих начинающих системных администраторов часто стоит вопрос, а как организовать систему учета трафика? С подобными вопросами вы столкнетесь на многих форумах в интернете.

В рамках данной статьи мы рассмотрим простую систему учета трафика, которая должна будет обладать следующими характеристиками:

  • Учет всего трафика, проходящего через маршрутизатор работающий под ОС Linux;
  • Возможность быстрого изменения конфигурации без внесения изменений в код;
  • Данные о трафике должны храниться в базе данных, в нашем случае мы в качестве сервера баз данных будем использовать MySQL.

В рассматриваемом примере будем считать, что все IP адреса в нашей сети реальные. Начнем с создания конфигурационного файла, назовем его billing.conf. Пусть он имеет следующий вид:

# Формируем список IP адресов машин или сетей, для которых мы будем считать
# трафик
# Рабочее место
WS1="192.168.0.1"
# Ceть нашего клиента
NET="192.168.1.0/24"
# Объединим объединим все сети и адреса в один список.
ALLNETS="$WS1 $NET"

В принципе, формировать списки для каждого адреса или сети нет необходимости, т.к. рассматриваемая система использует только список ALLNETS, однако они могут понадобиться в случае, если вам нужно будет обрабатывать статистику о каждом пользователе. Данный конфигурационный файл является единой для всей нашей системы, состоящей как минимум из трех программ:

  • Программы формирования правил учета для firewall, с использованием iptables;
  • Программы снятия статистики;
  • Программы отображения статистики;

Рассмотрим программу формирования правил учета для firewall, названную в нашем случае rc.firewall, которую нужно будет добавить в один из файлов, который будет выполняться при загрузке системы.

Для начала немного теории, в ядрах Linux серии 2.4.X используется firewall NetFilter, интерфейсом к которому является программа iptables. В NetFilter cущестуют несколько цепочек: INPUT - все входящие пакеты, адресованные маршрутизатору, OUTPUT - все исходящии из маршрутизатора пакеты, FORWARD - все пересланные маршрутизатором пакеты во внешнюю сеть.

#!/bin/bash
# Подключаем конфигурационный файл
. /etc/lbiling.conf
IPTABLES="/sbin/iptables" # Задаем путь к программе iptables
###################################
# Учет трафика
###################################
# Функция для создания правила учета
addrule(){
$IPTABLES -N ACCT_IN_$1 # Создаем правило для учета входяшего трафика
$IPTABLES -N ACCT_OUT_$1 # Создаем правило для учета изходяшего трафика
$IPTABLES -F ACCT_IN_$1 # Обнулим полученные цепочки
$IPTABLES -F ACCT_OUT_$1
$IPTABLES -A INPUT -j ACCT_IN_$1 # Включим учет по цепочкам
$IPTABLES -A FORWARD -j ACCT_IN_$1
$IPTABLES -A FORWARD -j ACCT_OUT_$1
$IPTABLES -A OUTPUT -j ACCT_OUT_$1
$IPTABLES -A ACCT_IN_$1 -s $2 # Считать входящим трафик у которого источник
# адрес $2
$IPTABLES -A ACCT_OUT_$1 -d $2 # Считать исходящим трафик у которого получатель
# адрес $2
}
# Создаем правила для учета трафика
for NET in $ALLNETS; do
# Для всех сетей в списке $ALLNET создать правила учета трафика
addrule $NET $NET
done

После выполнения нашей программы rc.firewall, набрав в консоли:

# iptables -L

Вы должны будете увидеть нечто подобное:

Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCT_IN_192.168.0.1 all -- anywhere anywhere
ACCT_IN_192.168.1.0/24 all -- anywhere anywhere

Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCT_IN_192.168.0.1 all -- anywhere anywhere
ACCT_OUT_192.168.0.1 all -- anywhere anywhere
ACCT_IN_192.168.1.0/24 all -- anywhere anywhere
ACCT_OUT_192.168.1.0/24 all -- anywhere anywhere

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCT_OUT_192.168.0.1 all -- anywhere anywhere
ACCT_OUT_192.168.1.0/24 all -- anywhere anywhere

Chain ACCT_IN_192.168.0.1 (2 references)
target prot opt source destination
all -- 192.168.0.1 anywhere

Chain ACCT_IN_192.168.1.0/24 (2 references)
target prot opt source destination
all -- 192.168.1.0/24 anywhere

Chain ACCT_OUT_192.168.0.1 (2 references)
target prot opt source destination
all -- anywhere 192.168.0.1

Chain ACCT_OUT_192.168.1.0/24 (2 references)
target prot opt source destination
all -- anywhere 192.168.1.0/24

Создадим базу данных в MySQL с названием trafficbd, для этого необходимо будет выполнить следующий SQL запрос (вопрос "как это сделать" не входит в рамки нашей статьи, обратитесь к документации MySQL):

CREATE DATABASE IF NOT EXISTS trafficbd;
use trafficbd;

#
# Структура таблицы `traffic`
#

CREATE TABLE traffic (
id int(11) NOT NULL auto_increment,
date datetime NOT NULL default '0000-00-00 00:00:00',
ip varchar(20) NOT NULL default '',
inb int(11) NOT NULL default '0',
outb int(11) NOT NULL default '0',
KEY id (id)
) TYPE=MyISAM;

Итак, подведем итоги, мы создали базу данных, написали правила учета трафика, теперь нам надо паписать программу, которая бы снимала полученную статистику, заносила её в базуданных и после этого обнуляла бы счетчики. Ниже приведен пример такой программы, её можно прописать в CRON и вызывать с некоторым периодом.

#!/usr/bin/perl
# Функция занимающаяся сбором и внесением данных в БД.
sub account{
$name=$_[0]; # Имя правила
$IP_IN=0; # Инициализация счетчиков
$IP_OUT=0;
# Командная строка MySQL для внесения данных в таблицу.
$mysqlcommand="/usr/bin/mysql -hlocalhost trafficbd -e";
# Снимем данные со счетчика входящего трафика и обнулим
$ipstuff=`/sbin/iptables -L -Z ACCT_IN_$name -v -x`;
# Выделим из вывода предыдущей команды значение счетчика
@IPTBMASS=split(/ /,$ipstuff);
chomp $IPTBMASS[2];
$string=$IPTBMASS[2];
$string=~ s/s{1,}/ /g;
@INFOMASS=split(/ /,$string);
$IP_IN=$INFOMASS[2];
# Снимем данные со счетчика исходящего трафика и обнулим
$ipstuff=`/sbin/iptables -L -Z ACCT_OUT_$name -v -x`;
# Выделим из вывода предыдущей команды значение счетчика
@IPTBMASS=split(/ /,$ipstuff);
$string=$IPTBMASS[2];
$string=~ s/s{1,}/ /g;
@INFOMASS2=split(/ /,$string);
$IP_OUT=$INFOMASS2[2];
# Получим текущее время
($min, $hours, $day, $mounth,$year) = (localtime)[1,2,3,4,5];
$time=$hours.":".$min.":00";
$mounth=$mounth+1;
$year=$year+1900;
$date=$year."-".$mounth."-".$day;
# Формируем SQL запрос
$sql="insert into traffic values('','".$date." ".$time."','".$name."','".$IP_IN."','".$IP_OUT."');";
# Выполняем его
`$mysqlcommand "$sql"`;
} # На этом функция account заканчивается:)
# Основная программа

$config=`./lconfreader.sh`; # Прочитаем конфигурационный файл.

# Ниже приводится текст скрипта lconfreader.sh:
# #!/bin/bash
# . ./lbiling.conf # Включить конфигурационный файл
# echo $ALLNETS # Вывести в stdout список всех сетей, покоторым ведется учет.
#

chomp $config;

@NETMASS=split(/ /,$config);

foreach $nets(@NETMASS)
{
# Для каждого элемента списка, выполнить функцию account
account $nets;
}

Вот собственно и вся биллинговая система :)

Автор: Вадим Фёдоров

Комментарии

Sly (добавлено 11 июля 2010 г. в 18:48)
TraffPro - система учёта трафика (биллинг) + система учёта телефонных звонков Мини АТС
Цитировать
Sly (добавлено 27 января 2008 г. в 02:39)
Office-Control извиняюсь ссылку забыл smile
office-control.org
Цитировать
Sly (добавлено 27 января 2008 г. в 02:37)
Что бы не писать самому! Бесплатная!
Система "Office-Control" предназначена для управления трафиком и защиты сетей офисов. Разрабатывается с учетом потребности в проектах, исключающих утомительную настройку сервера, и позволяет свести к минимуму время на развёртывание и обслуживание системы. Включает в себя несколько компонент, из которых можно построить необходимый комплекс для любых нужд офиса.

Комплекс позволяет:

* контролировать доступ к серверу как из сети интернет

* управлять доступом из внутренней сети во внешнюю, и из внешней во внутреннюю

* контролировать потребление трафика пользователями внутренней сети
* ограничивать доступа пользователей к ресурсам внешней сети по портам

Демо версии системы
Цитировать
Андрей (добавлено 2 декабря 2007 г. в 16:10)
Система эта не работает!!!
Так как iptables выдает на stdout 3 строки...
Так что, вот это:

$ipstuff=`/sbin/iptables -L -Z ACCT_IN_$name -v -x`;
# Выделим из вывода предыдущей команды значение счетчика
@IPTBMASS=split(/ /,$ipstuff);
chomp $IPTBMASS[2];
$string=$IPTBMASS[2];
$string=~ s/s{1,}/ /g;
@INFOMASS=split(/ /,$string);
$IP_IN=$INFOMASS[2];

НЕ РАБОТАЕТ!!! smile
Цитировать

Добавить комментарий




:smile1: :smile2: :smile3: :smile4: :smile5: :smile6: :smile7: :smile8: :smile9: :smile10: :smile11: :smile12: :smile13: :smile14: :smile15: :smile16: :smile17: :smile18:


Сайт для умных людей, логические игры, задачи
xNova - Браузерная космическая игра
Новости современных технологий
Яндекс цитирования Rambler's Top100 Рейтинг@Mail.ru
Реклама: дизель-генератор 75 квт