Учет трафика в Linux с помощью ipcad

Многие системные администраторы в своей работе сталкиваются с задачей подсчета расходуемого трафика в своей локальной сети. Я расскажу, как справиться со сбором статистики и покажу, что, на самом деле, это несложная задача.
   
    В данной статье рассмотрено решение задачи учета трафика, проходящего через шлюз локальной сети в интернет, с помощью ipcad. ipcad (Cisco IP accounting simulator) — это программа для учета трафика, которая может вести подсчет несколькими механизмами, например через интерфейсы BPF, libpcap и iptables ULOG. Материал предназначен для тех администраторов, в чьем ведении имеется малая или средняя локальная сеть. Все, что понадобится для работы — лишь сам ipcad, текстовый редактор для написания скриптов разбора статистики и огромное желание наконец решить задачу подсчета расходуемого трафика в локальной сети.
   
    Данная статья охватывает процессы установки, настройки и запуска ipcad, а также рассматривает некоторые примеры написания скриптов разбора статистики.
   
   
    Установка ipcad
   
   
    Для начала необходимо скачать последнюю версию ipcad. На момент написания статьи таковой была 3.6.6. В самом процессе установки нет ничего нетривиального:
    
$ tar -xvzf ipcad-3.6.6.tar.gz

$ cd ipcad-3.6.6

$. /configure

$ make

$ /bin/su -

# make install
    
    В RPM-основанных дистрибутивах устанавливать лучше с помощью checkinstall (дабы следовать правилам пакетной системы).
    
    
    Настройка ipcad
    
    
    Из многочисленных способов ведения статистики самым простым является учет трафика, прошедшего через физические интерфейсы шлюза (в данной статье — два ethernet-интерфейса). Для конкретизации описания настроек взята локальная сеть с одной подсетью 192.168.0.0/24.
    
    По умолчанию единственный конфигурационный файл ipcad находится в директории /usr/local/etc. Преобразованный под задачу учета трафика через два сетевых интерфейса eth0 и eth1 ipcad.conf выглядит следующим образом:
    
------------------------begin of ipcad.conf--------------------------

# /usr/local/etc/ipcad.conf

##################

# GLOBAL OPTIONS #

##################

# опция 'capture-ports' включает/отключает дополнительные поля

# в статистике, такие, как TCP- и UDP-порты, а также типы 

# ICMP-пакетов. Однако включение данной опции увеличивает 

# потребление памяти, снижает скорость подсчета трафика и, 

# в ряде случаев, искажает вывод через RSH, поэтому она 

# в данном примере отключена.



capture-ports disable;



# Размер буферов, используемых для передачи статистики ядром,

# по умолчанию равен 64 kb, чего вполне достаточно.

buffers = 64k



#####################

# INTERFACE OPTIONS #

#####################

# интерфейсы, на которых считается проходящий трафик. 

# Рассматривается случай шлюза с двумя сетевыми интерфейсами:

# внутренним  (локальная сеть) и внешним  (интернет). 



interface eth0;  # Считать трафик на Ethernet-интерфейсе…

interface eth1;  # …и еще на одном.



# Разделять статистику по каждому IP-адресу для подсети 192.168.0.0/24. 

#  «aggregate 192.168.0.0/24» указывает ipcad диапазон адресов сети.

#  «strip 32» означает, что в статистику необходимо заносить все 32 бита

# адреса, принадлежащего данному адресному диапазону.

aggregate 192.168.0.0/24 strip 32; 



######################

# RSH SERVER OPTIONS #

######################

# Настройки rsh-сервера, с помощью которого будет просматриваться 

# статистика.



rsh enable at 127.0.0.1;



# Правила ниже описывают политики доступа к статистике ipcad.

# root может полностью управлять  (делать backup, просматривать 

# и изменять таблицы подсчета). Все остальные могут лишь 

# просматривать статистику.

rsh root@127.0.0.1 admin; 

rsh root@127.0.0.1 backup; 

rsh root@127.0.0.1;  

rsh 127.0.0.1 view-only; 



# “Время жизни» и тайм-аут IP пакета. 

rsh ttl = 3;

rsh timeout = 30;



# опцией dumpfile задается путь к файлу, в который по умолчанию 

# будут складываться данные  статистики

dumpfile = /var/log/ipcad/ipcad-curr.dump;



#################

# OTHER OPTIONS #

#################



pidfile = /var/run/ipcad.pid;



# Опция 'memory_limit задает количество памяти для хранения 

# содержимого одного потока данных.

# Синтаксис следующий: memory_limit = <количество>[{k|m|e}] ;

# где 'k'—килобайты, 'm'—мегабайты, 'e'—количество строк таблицы 

# данных.

memory_limit = 10m;

--------------------------end of ipcad.conf--------------------------
    
    Все остальные опции, задаваемые ipcad.conf, в нашем случае можно смело удалить (или, как минимум, закомментировать). Таким образом, они не будут задействованы вообще. 
    
    Примечание: директория /var/log/ipcad/ НЕ создается при установке ipcad, поэтому ее необходимо создать самостоятельно. Права на чтение, запись и просмотр содержимого директории с логами ipcad рекомендую дать лишь пользователю root. Всем остальным — запретить все, чтобы избежать даже просмотр простыми пользователями статистики расходуемого трафика в сети. 
    
    На этом процессы установки и настройки завершены, и можно переходить к запуску ipcad.
    
    
    Запуск ipcad
    
    
    Запускать ipcad имеет смысл таким образом, чтобы при загрузке он восстанавливал данные о статистике из dumpfile, уходил в фон, а при выключении сбрасывал все данные в тот же dumpfile. Команда для запуска выглядит следующим образом:
    
    /usr/local/bin/ipcad -rds
    
    где ключ 'r' импортирует данные из dumpfile, 'd' — «демонизирует» ipcad, 's' — сбрасывает статистику в dumpfile при выключении ipcad.
    
    Лучше всего разместить указанную команду в один из init-скриптов для запуска ipcad вместе с системой. В какой именно init-скрипт я не конкретизирую, т.к. это зависит от каждого дистрибутива. Например, в SuSE Linux для подобных целей служит скрипт /etc/init.d/boot.local, а в Red Hat — /etc/rc.d/rc.local.
    
    
    Просмотр статистики
    
    
    Для управления статистикой ipcad используется rsh, настройки которого [rsh] задаются в конфигурационном файле ipcad.conf (о чем говорится в пункте «Настройка ipcad»).
    Общий синтаксис команд для ipcad выглядит следующим образом:
    
    rsh host command
    
    где 'host' — это хост, на котором ведется статистика, а 'command' — это сама команда. В рассматриваемом случае значением 'host' является localhost.
    
    По команде: rsh localhost help — доступен полный список команд. А именно:
    
    show ip accounting # показать статистику
    clear ip accounting # сбросить статистику до контрольной точки. Если контрольная точка не задана, то статистика сбрасывается в ноль
    show ip accounting checkpoint # показать статистику сохраненную в контрольных точках
    clear ip accounting checkpoint # сбросить все контрольные точки
    
    show ip cache flow # показать кэш NetFlow
    
    show interface <iface> # показать счетчик интерфейса 
   
    dump [<path>] # сохранить текущую статистику в файл <path>. Если не указывать, то статистика сохранится в dumpfile, указанный в конфигурационном файле ipcad.conf
    restore [<path>] # восстановить статистику
    import [<path>] # импортировать (добавить) статистику
   
    stat # показать текущее состояние работы ipcad
    show version # показать версию и uptime ipcad'а
   
    shutdown # завершить работу ipcad
   
    Для просмотра статистики достаточно:
    rsh localhost show ip accounting
   
    Однако таким образом на экран выведется информация обо всем трафике, прошедшем через шлюз. Т.е. в одной таблице будет статистика по всему входящему и исходящему трафику из локальной сети.
   
    Получать нужные данные из вывода команды show ip accounting можно, например, с помощью самописных скриптов. Подобные скрипты пишутся «на коленке» за пять минут для каждой конкретной ситуации. Ниже приводится пример для показа статистики по одному указанному IP-адресу и подсчета суммарного трафика для этого IP:
    
------------------------Begin of traff.acc---------------------------

#!/bin/bash

# name of script: traff.acc

HOST=localhost

rsh $HOST dump

rsh $HOST show ip accounting | grep -E '192\.168\.0\.'$1'  ([^0-9]|$)'

echo

echo  «Summary traffic of 192.168.0.$1  (kbytes):»

rsh $HOST show ip accounting | grep -E '192\.168\.0\.'$1'  ([^0-9]|$)' | awk '{s+=$4} END {print  (s/1024)}'

--------------------------End of traff.acc---------------------------
    
    Используется просто:
    ./traff.acc ip
    
    где ip — это число от 1 до 254 (попросту, последний октет из IP-адреса).
    Результатом работы этого скрипта будет вывод на экран количества в мегабайтах входящего трафика для введенного IP-адреса.
    
    Приведенный простейший скрипт будет выводить всю суммарную статистику по указанному IP адресу собранную с момента первого запуска ipcad и до текущего момента времени. А это не всегда удобно, поскольку наглядней иметь данные за какой-то конкретный промежуток времени (день/неделя/месяц). 
    Мне достаточно вести статистику расходуемого трафика по месяцам. Схема такого учета выглядит следующим образом: в 23 ч. 59 мин. «последнего» числа каждого месяца делается dump статистики в файл, к названию которого целесообразно добавить значения года и текущего месяца. Уже через минуту, в 0 ч. 00 мин. 1-го числа следующего месяца, счетчик трафика сбрасывается командой clear ip accounting, статистика начинает вестись «с нуля». По достижении «последнего» дня месяца схема повторяется.
    
    Для реализации этого механизма создан файл /etc/cron.d/ipcad с заданиями для cron'а: 
    
------------------------Begin of /etc/cron.d/ipcad-------------------
* * * * * root rsh localhost dump >/dev/null
59 23 * * * root date «+\%Y\%m» > /var/log/ipcad/ipcad.date
0 0 1 * * root (rsh localhost dump /var/log/ipcad/ipcad-$ (cat /var/log/ipcad/ipcad.date).dump && rsh localhost clear ip accounting) >/dev/null 2>&1
--------------------------End of /etc/cron.d/ipcad-------------------

    
    Первая задача из приведенного файла выполняет dump статистики каждую минуту. Делается это для защиты от непредусмотренных выключений и зависаний шлюза, на котором ведется учет проходящего трафика. 
    Вторая строчка — это такой маленький «хак», который автор статьи вынужден был сделать, в связи с трудностью указания в расписании «последнего дня месяца» при настройке заданий cron'а. Суть в том, что каждый день в файл /var/log/ipcad/ipcad.date сохраняется текущий месяц и год (в формате YYYYMM). Эта же процедура, ведь, произойдет и в последний день месяца. Уже через минуту третье задание сделает dump статистики в файл, к названию которого прикрепится содержимое файла ipcad.date (т.е. год и _уже_ прошедший месяц в формате YYYYMM) и сбросит счетчик расходуемого трафика. В этот же день файл ipcad.date перезапишется новыми значениями текущих месяца и года. Не совсем красиво, но зато работает.
    
    Теперь, когда есть данные о трафике по каждому месяцу, расположенные в разных dump-файлах, можно изменить скрипт, добавив к нему возможность просмотра общей и частной по каждому IP-адресу статистики израсходованного трафика за какой-то определенный месяц:
    
------------------------Begin of traff.acc.2-------------------------

#!/bin/bash

HOST=localhost

USERS=/etc/hosts

case $1 in

 M|m) echo  «Summary LAN traffic of month $2  (Mbytes):»

      rsh $HOST dump

      awk '{s+=$4} END {print  (s/1048576)}' < /var/log/ipcad/ipcad-$2.dump

      exit 0;;

 U|u) grep -E '192\.168\.0\.'$3'  ([^0-9]|$)' $USERS | awk '{print  ($2)}'

      USER=`grep -E '192\.168\.0\.'$3'  ([^0-9]|$)' $USERS | awk '{print  ($2)}'`

      rsh $HOST dump

      cat /var/log/ipcad/ipcad-$2.dump | grep -E '192\.168\.0\.'$3'  ([^0-9]|$)'

      echo

      echo  «Summary traffic of $USER in $2 month  (kbytes):»

      cat /var/log/ipcad/ipcad-$2.dump | grep -E '192\.168\.0\.'$3'  ([^0-9]|$)' | awk '{s+=$4} END {print  (s/1024)}'

      exit 0;;

 *)   echo  «Usage: „

      echo „1) if only month stat:“

      echo „  . /traff.acc.2 m  

      echo  «        — number of month“

      echo  «2) if user's stat for month:“

      echo  « . /traff.acc.2 u   

      echo „     — stat for that month“

      echo  «     — last octet of user's IP address“

      echo  «note: for current month in flag  just type 'curr'“

      exit 0;;

esac

--------------------------End of traff.acc.2-------------------------
   
    В приведенном скрипте traff.acc.2 в переменной $USERS определяется файл, в котором есть соответствия имен пользователей и их IP-адресов (в данном примере — это /etc/hosts на шлюзе). Эта переменная необязательна и вводится в скрипт исключительно для наглядности просматриваемой статистики.
   
    Использовать приведенный скрипт можно двумя способами:
    1) ./traff.acc.2 m <month>
    где семафор 'm' обозначает то, что на экран необходимо вывести общую статистику за указанный месяц.
   
    2) ./traff.acc.2 u <month> <IP>
    где семафор 'u' обозначает то, что на экран необходимо вывести статистику указанного пользователя за определенный месяц.
   
    Флаг <month> — это шестизначный номер месяца в формате YYYYMM — такой формат хранения ежемесячных dump-файлов выбран в файле задач для cron'a (для вывода статистики за текущий месяц следует указать вместо номера месяца слово 'curr'); флаг <IP> — это значение последнего октета IP-адреса пользователя, чью статистику надо просмотреть.
   
    В заключение статьи хочу отметить, что вместо shell-скрипта можно написать скрипт на Perl и, добавив элементы навигации, прикрутить страницу с этим скриптом к httpd-серверу. Тогда статистика будет доступна для просмотра через браузер.