Добавить в избранное | Сделать стартовой страницей

Большая Linux библиотека для пользователей OS Linux и ПО для нее
Есть что сказать? Нужен совет? Посети наш форум.


При поддержке
Продвижение сайта
Продвижение сайта
Раскрутка сайта
Создание сайта
Оптимизация сайта
Интернет реклама
Аудит сайта
Администрирование сервера
настройка сервера
установка сервера
аренда сервера
Администрирование сервера
администрирование сервера
настройка сервера
аренда сервера
Rambler's Top100


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

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

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

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

  • Учет всего трафика, проходящего через маршрутизатор работающий под ОС 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;
}

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


Обсудить данную тему на нашем форуме "Все о Linux"