Поскольку IP accounting очень тесно связан с IP firewall, для их настройки
используется одна программа. В зависимости от реализации это
ipfwadm, ipchains или
<BCLASS="COMMAND">iptables. Синтаксис команды очень похож на используемый
при задании правил firewall.
Появился новый параметр direction. Он принимает значения
in
, out
или
both
. Все значения считаются с точки зрения
linux-машины, так что in
задает входящий трафик,
out
задает исходящий трафик, а
both
оба типа сразу.
Команды очень похожи на свои аналоги для правил firewall за исключением
того, что стратегии здесь не применяются. Мы можем добавлять, вставлять,
удалять и просматривать список правил учета. В случае
ipchains и iptables, все имеющие силу правила
считаются правилами для учета, и любая команда, которая не определяет опцию
-j, выполняет только учет.
Параметры спецификации правила для учета IP такие же, как и для IP
firewall.
Давайте на примере покажем, как мы использовали бы учет IP.
Допустим, у нас есть Linux-роутер, который обслуживает два департамента
Virtual Brewery. Он имеет два устройства Ethernet, eth0
и eth1
, по одному на департамент, и одно
устройство PPP, ppp0
, для связи через
быстродействующую последовательную связь с университетским городком Groucho
Marx University.
Для составления счетов мы хотим знать общее количество трафика,
сгенерированного каждым из отделов по последовательной связи, и для целей
управления мы хотим знать общий трафик между двумя отделами.
Следующая таблица показывает используемые нами адреса и интерфейсы:
Для ответа на вопрос, сколько данных каждый отдел передает по PPP, мы
могли бы использовать правило, которое напоминает:
# ipfwadm -A both -a -W ppp0 -S 172.16.3.0/24 -b
# ipfwadm -A both -a -W ppp0 -S 172.16.4.0/24 -b
|
или:
# ipchains -A input -i ppp0 -d 172.16.3.0/24
# ipchains -A output -i ppp0 -s 172.16.3.0/24
# ipchains -A input -i ppp0 -d 172.16.4.0/24
# ipchains -A output -i ppp0 -s 172.16.4.0/24
|
или с
iptables:
# iptables -A FORWARD -i ppp0 -d 172.16.3.0/24
# iptables -A FORWARD -o ppp0 -s 172.16.3.0/24
# iptables -A FORWARD -i ppp0 -d 172.16.4.0/24
# iptables -A FORWARD -o ppp0 -s 172.16.4.0/24
|
Первая половина каждого набора правил задает подсчет всех данных,
передаваемых по интерфейсу ppp0 с исходным адресом или адресом назначения
172.16.3.0/24
. Здесь полезна опция
-b в ipfwadm и
iptables. Вторая половина каждого набора правил задает
то же самое, но для второй сети Ethernet.
Для ответа на вопрос, сколько трафика проходит между департаментами, нужно
правило, которое выглядит следующим образом:
# ipfwadm -A both -a -S 172.16.3.0/24 -D 172.16.4.0/24 -b
|
или:
# ipchains -A forward -s 172.16.3.0/24 -d 172.16.4.0/24 -b
|
или:
# iptables -A FORWARD -s 172.16.3.0/24 -d 172.16.4.0/24
# iptables -A FORWARD -s 172.16.4.0/24 -d 172.16.3.0/24
|
Эти правила будут считать все пакеты с исходящими адресами сети одного
департамента и адресом назначения в сети другого.
Предположим, мы хотим также знать, какой именно трафик преобладает на
связи через PPP. Например, надо выяснить, сколько данных проходит по
протоколам FTP, smtp и World Wide Web.
Для сбора этой информации пригоден такой скрипт с правилами:
#!/bin/sh
# Collect FTP, smtp and www volume statistics for data carried on our
# PPP link using ipfwadm
#
ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 ftp ftp-data
ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 smtp
ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 www
|
или:
#!/bin/sh
# Collect ftp, smtp and www volume statistics for data carried on our
# PPP link using ipchains
#
ipchains -A input -i ppp0 -p tcp -s 0/0 ftp-data:ftp
ipchains -A output -i ppp0 -p tcp -d 0/0 ftp-data:ftp
ipchains -A input -i ppp0 -p tcp -s 0/0 smtp
ipchains -A output -i ppp0 -p tcp -d 0/0 smtp
ipchains -A input -i ppp0 -p tcp -s 0/0 www
ipchains -A output -i ppp0 -p tcp -d 0/0 www
|
или:
#!/bin/sh
# Collect ftp, smtp and www volume statistics for data carried on our
# PPP link using iptables.
#
iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport ftp-data:ftp
iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport ftp-data:ftp
iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport smtp
iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport smtp
iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport www
iptables -A FORWARD -o ppp0 -m tcp -p tcp --dport www
|
Здесь есть пара интересных свойств. Во-первых, мы определили протокол.
Когда мы определяем порты в наших правилах, мы должны также определить
протокол потому, что TCP и UDP имеют отдельные наборы портов. Так как все эти
услуги основаны на TCP, мы определяем именно этот протокол. Во-вторых, мы
определили два сервиса, ftp
и
ftp-data
в одной команде. ipfwadm позволяет
определять одиночные порты, диапазоны портов или произвольные списки портов.
Команда ipchains позволяет определять любой одиночный
порт или диапазон портов. Запись "ftp-data:ftp
"
означает "порты с ftp-data (20) по ftp (21)", так можно кодировать порты в
ipchains и iptables. Когда вы
имеете список портов в правиле учета, это означает, что любые данные для
любого из портов в списке будут добавлены к общему количеству для этой
записи. Поскольку FTP использует два порта, команды и данные, мы добавили
их вместе к общему трафику FTP. Наконец, мы определили исходный адрес как
0/0
, что соответствует всем адресам и требуется
ipfwadm и ipchains для
определения портов.
Теперь нас интересует соотношение полезного трафика по FTP, SMTP и World
Wide Web к трафику по другим протоколам. Для этого зададим такие правила:
# ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 ftp ftp-data smtp www
# ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 1:19 22:24 26:79 81:32767
|
Если вы уже исследовали ваш файл /etc/services
,
вы увидите, что второе правило покрывает все порты за исключением
(ftp
, ftp-data
,
smtp
и www
).
Как сделать это с командами ipchains или
iptables, ведь они позволяют только один параметр в
спецификации порта? Мы можем эксплуатировать определяемые пользователем
цепочки в учете так же легко, как в правилах firewall. Рассмотрим следующий
подход:
# ipchains -N a-essent
# ipchains -N a-noness
# ipchains -A a-essent -j ACCEPT
# ipchains -A a-noness -j ACCEPT
# ipchains -A forward -i ppp0 -p tcp -s 0/0 ftp-data:ftp -j a-essent
# ipchains -A forward -i ppp0 -p tcp -s 0/0 smtp -j a-essent
# ipchains -A forward -i ppp0 -p tcp -s 0/0 www -j a-essent
# ipchains -A forward -j a-noness
|
Здесь мы создаем две определяемых пользователем цепочки:
a-essent
, где мы фиксируем данные для полезного
трафика и
a-noness
, где мы собираем данные для всего
остального. Затем добавим правила к цепочке forward, которые соответствуют
полезным сервисам и задают переход в цепочку
a-essent
, которая только считает трафик. Последнее правило в нашей цепочке
forward задает переход к цепочке
a-noness
, где тоже
есть только одно правило, считающее трафик. Правило, которое переходит к
цепочке
a-noness
, не будет достигнуто любым пакетом
из полезных сервисов, поскольку они будут приняты в их собственной цепочке.
Наши счетчики для полезных и остальных услуг будут доступны только в правилах
внутри тех цепочек. Это только один подход, который вы могли бы избрать.
Реализация того же самого подхода для
iptables:
# iptables -N a-essent
# iptables -N a-noness
# iptables -A a-essent -j ACCEPT
# iptables -A a-noness -j ACCEPT
# iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport ftp-data:ftp -j a-essent
# iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport smtp -j a-essent
# iptables -A FORWARD -i ppp0 -m tcp -p tcp --sport www -j a-essent
# iptables -A FORWARD -j a-noness
|
Это выглядит достаточно простым. К сожалению, имеется маленькая, но
неизбежная проблема при попытке делать учет сервисным типом. Мы обсуждали в
одной из предыдущих глав роль MTU в работе с сетями TCP/IP. MTU определяет
самый большой пакет, который будет передан на сетевое устройство. Когда пакет
получен маршрутизатором, и этот пакет больше, чем MTU интерфейса, который
должен его передать, маршрутизатор выполняет
фрагментацию
(fragmentation). Маршрутизатор разбивает большой пакет на маленькие части
не больше, чем MTU интерфейса, и затем передает эти части. Маршрутизатор
формирует новые заголовки для получившихся пакетов, по которым получатель
сможет восстановить исходный пакет. К сожалению, в течение фрагментации
значение порта будет потеряно для всего, кроме первого фрагмента. Это
означает, что учет IP не может правильно считать фрагментированные пакеты, а
только первые фрагменты или нефрагментированные пакеты. Имеется маленькая
хитрость
ipfwadm, которая позволяет считать пакеты,
даже не зная порт второго и последующих фрагментов. Первая версия
программного обеспечения Linux accounting назначала фрагментам поддельный
номер порта 0xFFFF, который мы могли перехватывать для учета. Мы фиксируем
вторые и последующие фрагменты, используя правило:
# ipfwadm -A both -a -W ppp0 -P tcp -S 0/0 0xFFFF
|
Реализация IP chains имеет немного более сложное решение, но результат тот
же самый. При использовании команды
ipchains надо
использовать правило:
# ipchains -A forward -i ppp0 -p tcp -f
|
Для
iptables подойдет правило:
# iptables -A FORWARD -i ppp0 -m tcp -p tcp -f
|
Это правило не будет сообщать нам, каков первоначальный порт для этих
данных, но по крайней мере мы способны видеть, сколько из наших данных
являются фрагментами.
В ядрах 2.2 вы можете выбирать при настройке ядра опцию, которая решает
эту проблему, если ваша Linux-машина действует как одиночная точка доступа к
сети. Если вы включили при построении ядра опцию IP:
always defragment
, все пакеты будут повторно собраны маршрутизатором
Linux перед маршрутизацией и передачей. Эта операция выполняется перед
firewall, и учетный блок видит пакеты. Таким образом, фрагментов просто не
будет. В ядрах 2.4 откомпилируйте и загрузите netfilter
с модулем forward-fragment
.
Протокол ICMP не использует сервисные номера портов, так что сбор
статистики по нему труднее. ICMP использует ряд различных типов пакетов.
Многие из их безобидны и нормальны, в то время, как другие появляются только
при специальных обстоятельствах. Иногда пытаются обвалить систему, посылая
огромное число пакетов ICMP. Эта атака называется ping
flooding. Против такой атаки хорош IP firewall, а IP accounting позволит
узнать, кто это сделал.
ICMP не использует порты в отличие от TCP и UDP. Вместо них используются
типы сообщений ICMP. Мы можем создать правила, чтобы учитывать каждый тип
сообщений ICMP. Для этого нужно определить тип сообщения ICMP вместо номера
порта в команде ipfwadm. Типы сообщений перечислены в
разделе "Типы
пакетов ICMP" главы 9.
Для сбора данных о передаче пакетов ICMP по всем типам сообщений
используйте правило:
# ipfwadm -A both -a -P icmp -S 0/0 8
# ipfwadm -A both -a -P icmp -S 0/0 0
# ipfwadm -A both -a -P icmp -S 0/0 0xff
|
или в
ipchains:
# ipchains -A forward -p icmp -s 0/0 8
# ipchains -A forward -p icmp -s 0/0 0
# ipchains -A forward -p icmp -s 0/0 -f
|
или в
iptables:
# iptables -A FORWARD -m icmp -p icmp --sports echo-request
# iptables -A FORWARD -m icmp -p icmp --sports echo-reply
# iptables -A FORWARD -m icmp -p icmp -f
|
Первое правило собирает информацию относительно пакетов ICMP Echo Request
(ping requests), второе правило собирает информацию относительно пакетов
ICMP Echo Reply (ping replies). Третье правило собирает информацию
относительно фрагментированных пакетов ICMP. Этот прием подобен описанному
для фрагментированных пакетов TCP и UDP.
Если Вы определяете источник и/или адресата в ваших правилах, Вы можете
следить, откуда приходят пакеты, изнутри сети или снаружи.