Учет по портам сервисов
Предположим, мы хотим также знать, какой именно трафик преобладает на связи через PPP. Например, надо выяснить, сколько данных проходит по протоколам FTP, smtp и World Wide Web.
Учет по портам сервисов
Предположим, мы хотим также знать, какой именно трафик преобладает на связи через 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
<
/p>
Это выглядит достаточно простым. К сожалению, имеется маленькая, но неизбежная проблема при попытке делать учет сервисным типом. Мы обсуждали в одной из предыдущих глав роль 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.