последняя стабильная
    версия: 3.4.0rc1
    главная     скачать     документация     поддержка     форум     разработка

Документация

Releases

База знаний

Примеры конфигурации

 

Сбор данных через NETGRAPH


Начиная с версии NETAMS-CURRENT build 2340 (03 марта 2005 г.) работает метод сбора статистики и фильтрация трафика через модуль NETGRAPH.

Технология NETGRAPH доступна для операционной системы FreeBSD версий 4.хх и 5.хх. Входящий в поставку модуль совместим с веткой 5.хх. NETGRAPH представляет собой механизм объединения различных сетевых модулей ядра FreeBSD в произвольные структуры (образующие граф), для последовательной обработки пакетов данных. Таким образом, представляется возможным написать и использовать достаточно произвольную схему обработки данных в ядре ОС, пользуясь стандартным интерфейсом программирования. Более того, легко осуществить связь модуля ядра с user-level программой. Через NETGRAPH работают, например, ng_netflow, user-level ppp, различные механизмы инкапсуляции пакетов, и многое другое. Для более глубокого ознакомления можно порекомендовать следующие источники:
http://www.daemonnews.org/200003/netgraph.html и man 4 netgraph

Пользователей других операционных систем вынуждены огорчить: ничего подобного у вас нет. Тем же, кому повезло, могут читать дальше:

  1. Принципы работы
  2. Как настроить
  3. Как проверить
  4. Результаты испытаний
  5. Заключение

Принципы работы

Работа netams в случае использования модуля NETGRAPH (далее-модуль) заключается в установке модуля в ядро (и подключения его к интерфейсу, через который идет трафик), и настройке программы netams (далее-демона) для корректного соединения с модулем.

Модуль и демон могут работать в двух режимах (они должны быть одинаковы в настройках!): tee и divert.



В режиме tee модуль ядра получает пакеты с использованием "дубликатора" ng_tee, который отсылает на обработку "копию" проходящего через интерфейс пакета. Понятное дело, в таком случае фильтрация трафика невозможна. Проходящие через модуль пакеты подвергаются анализу заголовков, формируются записи в хэш-таблице, которые периодически "устаревают" и отправляются на обработку демону. Он получает пакеты с данными о трафике и обрабатывает их примерно так же, как происходит с потоками netflow (работают учет и мониторинг).

В режиме divert модуль ядра подключается непосредственно к ethernet-интерфейсу. Весь трафик проходит через обработку, однако НЕ IP трафик пропускается прозрачно без учета. Каждый пакет также проходит проверку на соответствие с уже имеющимся в системе потоком данных, и:
  • если соответствующего потока не найдено, т.е. рассматриваемый пакет-первый в потоке данных (начало соединения), то для данного потока создается очередь. пакет помещается в конец очереди. создается запрос вида FWREQUEST, содержащий заголовки пакета, и передается через контрольный сокет демону netams. заметим, что в этот момент оригинальный IP пакет никуда не передается, он "застревает" в модуле. потоку присваивается статус QUEUED.

  • если поток найден, то проверяется его статус:
    • QUEUED - рассматриваемый пакет добавляется в конец цепочки пакетов данного потока. при этом делаются проверки на ряд ограничений по количеству потоков/пакетов/байт/очередей, для предотвращения атаки DoS
    • PASS - пакет передается дальше
    • DROP - пакет уничтожается
Возникает вопрос, что же происходит с пакетами в очереди, и откуда берутся статусы PASS и DROP?

Статус DROP является единственно возможным для режима работы TEE.

Когда демон получает запрос FWREQUEST из модуля ядра, происходит разбор заголовков и полный анализ возможности блокировки пакета с использованием таблиц юнитов, политик, системных политик, словом всего обычного набора действий. По окончании проверки, формируется решение по данному потоку: PASS или DROP, и оно передается обратно в ядро через сообщение FWREPLY. За время такой обработки в ядре уже может накопиться несколько пакетов в очереди для данного потока. По получении ответа от демона, модуль ядра во-первых ставит соответствующий флаг для данного потока, а затем пытается или отправить все пакеты из очереди, или очистить очередь.

Если по каким-то причинам демон недоступен, то по истечении некоторого таймаута (сейчас это NG_NETAMS_DEFAULT_TIMEOUT равный 2 секундам) производится принудительная очистка очереди для потока и принятие "решения по умолчанию" (сейчас: пропускать). Таким образом предотвращается залипание потока и выедание памяти у ядра (что может быть очень опасным!)

В режиме divert, как и в tee, проводится периодическое устаревание потоков и отправка их на учет "наверх", демону.

Рассмотренный механизм работает, по сути, аналогично Multilayer Switching, реализованному в Cisco Catalyst 6000 и подобных ящиках. Там "быстрый" Switch Engine направляет первый пакет потока "медленному" Route Processor, который определяет, куда маршрутизировать пакет, и проводит проверку правил доступа (access lists). Все последующие после ответа пакеты идут через SE напрямую, и только через некоторое время "наверх" передается статистика о прошедшем потоке. В нашем случае решения о маршрутизации принимать не нужно, в роли "быстрого" движка выступает ядро с его механизмом форвардинга пакетов, в роли "медленного" решателя - демон NeTAMS.


Как настроить

Для начала, вам надо скомпилировать netams, как обычно. Получившийся модуль src/ng_netams.ko необходимо переписать в /boot/kernel/
В дистрибутиве есть скрипт addon/netams-netgraph.sh, который устанавливает в ядро сам модуль ng_netams.ko, устанавливает его режим работы (TEE или DIVERT), вывод отладочной информации, производит подключения к другим нодам NETGRAPH (интерфейсу и ng_tee, если надо)

Запускается этот скрипт через
./netams-netgraph.sh start
останавливается через
./netams-netgraph.sh stop
Для настройки самого NeTAMS необходимо добавить соответствующий сервис в /usr/local/etc/netams.cfg:
service data-source 1
type netgraph
source netams: divert
При этом 'netams:' - это имя модуля NETGRAPH, совпадающее с тем, что написано в скрипте netams-netgraph.sh. Не забываем про двоеточие!
Модуль ядра должен быть запущен ДО демона. В противном случае демон не заработает, как следует. Однако, в процессе работы допускается останавливать и запускать демон NeTAMS, равно как и выгружать и загружать снова модуль ядра (при этом будет 20-секундная задержка в приеме статистики).

Как проверить

Если что-то будет идти совсем не так, упадет ядро :) или блокируется весь трафик!
Работу демона netams можно проверить через просмотр состояния сервиса data-source:

netamsctl show ds
 Data-source ID=1 type NETGRAPH source netams::9 loop 0 average 0 mcsec
    Perf: average skew delay 0 mcsec, PPS: 0, BPS: 0
    IP tree: 7 nodes [12] + 4 dlinks [1024] + 4 unodes [24] = 4276 bytes
    Flows: 0/0 act/inact entries (0 bytes), 3 flows sent
    HASH: size=65536, 0 flows hashed, 0 nodes used, max chain= 0
    FIFO: 0/2 used/ready messages, each 108, total 216 bytes
        ds_netgraph data messages: 3
        netams: mode=2, pkt_rx=201, pkt_tx=169
        flows: active(now)=3, queued(now)=0, blocked(total)=0, total=4
Работа модуля ядра видна через ngctl:

ngctl msg netams: info
Rec'd response "info" (1) from "[3bb]:":
Args:   { packets/in=254 packets/out=202 mode=2 debug=1 
	active_flows=3 total_flows=9 default_policy=2 }
При включенной отладке модуля (через ngctl msg netams: debug 1) на консоли и в dmesg видно много подобных строк:
info/1109893460: sent to daemon [961] with error=0
callout/1109893461+ active 1, checked 1, queued=0, flushed 0
callout/1109893462+ active 1, checked 1, queued=0, flushed 0
callout/1109893463+ active 1, checked 1, queued=0, flushed 0
callout/1109893464+ active 1, checked 1, queued=0, flushed 0
callout/1109893465+ active 1, checked 1, queued=0, flushed 0
callout/1109893466+ active 1, checked 1, queued=0, flushed 0
callout/1109893467+ active 1, checked 1, queued=0, flushed 0
callout/1109893468+ active 1, checked 1, queued=0, flushed 0
callout/1109893469+ active 1, checked 1, queued=0, flushed 0
netams: created flow record id=14, hash=00766, time=1109893469, proto=6
netams: created queue 0xc1a15250 for id=14, hash=00766
netams fwreply for entry id=14, flags=0, queue 1/102
netams: flush queue for entry id=14, hash=766, size=1, action=1
netams: created flow record id=15, hash=00254, time=1109893469, proto=6
netams: created queue 0xc1355240 for id=15, hash=00254
netams fwreply for entry id=15, flags=0, queue 1/102
netams: flush queue for entry id=15, hash=254, size=1, action=1

Результаты испытаний

Зачем все это нужно? Чтобы быстрее работало! Ниже приведены результаты небольших стендовых испытаний.

Все работы проводились с ОС FreeBSD 5.3-RELEASE, которая работала внутри виртуальной машины VmWare 4.5.2. Сама виртуальная машина работала на компьютере DUAL P4 Xeon 3.4GHz, 4Gb RAM под управлением Windows Server 2003. Виртуальная машина и хост-машина связаны через виртуальный адаптер vnmat (хотя в тестах трансляции адресов не было).

Скорость передачи данных измерялась при помощи iperf 1.7.0

На самой машине с Windows Server 2003 запущен сервер iperf, там же запускаем клиента:
C:\>iperf.exe -c 192.168.56.1 -t 10 -i 1
------------------------------------------------------------
Client connecting to 192.168.56.1, TCP port 5001
TCP window size: 8.00 KByte (default)
------------------------------------------------------------
[1948] local 192.168.56.1 port 3027 connected with 192.168.56.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[1948]  0.0- 1.0 sec  97.8 MBytes   821 Mbits/sec
[1948]  1.0- 2.0 sec  96.1 MBytes   807 Mbits/sec
[1948]  2.0- 3.0 sec  97.7 MBytes   820 Mbits/sec
[1948]  3.0- 4.0 sec  93.0 MBytes   780 Mbits/sec
[1948]  4.0- 5.0 sec  93.2 MBytes   782 Mbits/sec
[1948]  5.0- 6.0 sec  96.9 MBytes   813 Mbits/sec
[1948]  6.0- 7.0 sec  98.4 MBytes   825 Mbits/sec
[1948]  7.0- 8.0 sec  97.4 MBytes   817 Mbits/sec
[1948]  8.0- 9.0 sec  96.0 MBytes   806 Mbits/sec
[1948]  9.0-10.0 sec  98.2 MBytes   824 Mbits/sec
[1948]  0.0-10.0 sec   965 MBytes   808 Mbits/sec
Как видим, скорость передачи данных через локальный виртуальный интерфейс просто гигантская. Пробуем, как передаются данные между Windows и установленной FreeBSD, через VmWare, безо всяких побочных эффектов (NeTAMS и модуль ядра выключены):
freebsd-vm:~/netams#iperf -c 192.168.56.1 -t 10 -i 1
------------------------------------------------------------
Client connecting to 192.168.56.1, TCP port 5001
TCP window size: 32.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.56.17 port 51925 connected with 192.168.56.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 1.0 sec  27.6 MBytes   232 Mbits/sec
[  3]  1.0- 2.0 sec  28.4 MBytes   238 Mbits/sec
[  3]  2.0- 3.0 sec  28.1 MBytes   236 Mbits/sec
[  3]  3.0- 4.0 sec  28.3 MBytes   237 Mbits/sec
[  3]  4.0- 5.0 sec  28.4 MBytes   238 Mbits/sec
[  3]  5.0- 6.0 sec  28.3 MBytes   237 Mbits/sec
[  3]  6.0- 7.0 sec  28.0 MBytes   235 Mbits/sec
[  3]  7.0- 8.0 sec  28.1 MBytes   236 Mbits/sec
[  3]  8.0- 9.0 sec  28.7 MBytes   240 Mbits/sec
[  3]  9.0-10.0 sec  28.3 MBytes   237 Mbits/sec
[  3]  0.0-10.0 sec   282 MBytes   237 Mbits/sec
Естественно, медленнее. Теперь запустим NeTAMS и модуль ядра вместе, в режиме divert и убедимся, что это была не подстава:
freebsd-vm:~/netams#iperf -c 192.168.56.1 -t 10 -i 1
------------------------------------------------------------
Client connecting to 192.168.56.1, TCP port 5001
TCP window size: 32.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.56.17 port 56639 connected with 192.168.56.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 1.0 sec  20.9 MBytes   175 Mbits/sec
[  3]  1.0- 2.0 sec  23.4 MBytes   196 Mbits/sec
[  3]  2.0- 3.0 sec  23.5 MBytes   197 Mbits/sec
[  3]  3.0- 4.0 sec  23.5 MBytes   197 Mbits/sec
[  3]  4.0- 5.0 sec  23.6 MBytes   198 Mbits/sec
[  3]  5.0- 6.0 sec  23.6 MBytes   198 Mbits/sec
[  3]  6.0- 7.0 sec  23.4 MBytes   196 Mbits/sec
[  3]  7.0- 8.0 sec  23.8 MBytes   200 Mbits/sec
[  3]  8.0- 9.0 sec  23.6 MBytes   198 Mbits/sec
[  3]  9.0-10.0 sec  23.3 MBytes   196 Mbits/sec
[  3]  0.0-10.0 sec   233 MBytes   195 Mbits/sec

freebsd-vm:~/netams#ngctl msg netams: info
Rec'd response "info" (1) from "[3c5]:":
Args:   { packets/in=85515 packets/out=169244 mode=2 
	debug=1 active_flows=4 total_flows=4 default_policy=2 }
Налицо падение производительности на 100*(237-195)/237=17.7% или в 1.2 раза. Теперь заменим фильтрование через модуль ядра на стандартное, через ipfw divert и data-source ip-traffic:
freebsd-vm:~/netams#iperf -c 192.168.56.1 -t 10 -i 1
------------------------------------------------------------
Client connecting to 192.168.56.1, TCP port 5001
TCP window size: 32.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.56.17 port 55410 connected with 192.168.56.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 1.0 sec  2.96 MBytes  24.8 Mbits/sec
[  3]  1.0- 2.0 sec  3.59 MBytes  30.1 Mbits/sec
[  3]  2.0- 3.0 sec  3.73 MBytes  31.3 Mbits/sec
[  3]  3.0- 4.0 sec  3.62 MBytes  30.3 Mbits/sec
[  3]  4.0- 5.0 sec  3.70 MBytes  31.0 Mbits/sec
[  3]  5.0- 6.0 sec  3.69 MBytes  30.9 Mbits/sec
[  3]  6.0- 7.0 sec  3.65 MBytes  30.6 Mbits/sec
[  3]  7.0- 8.0 sec  3.71 MBytes  31.1 Mbits/sec
[  3]  8.0- 9.0 sec  3.71 MBytes  31.1 Mbits/sec
[  3]  9.0-10.0 sec  3.73 MBytes  31.3 Mbits/sec
[  3]  0.0-10.0 sec  36.1 MBytes  30.2 Mbits/sec

freebsd-vm:~/netams#ipfw show 10 11
00010   26136   39197956 divert 199 tcp from any to any dst-port 5001
00011   13069     679600 divert 199 tcp from any 5001 to any
В данном случае мы видим потерю производительности на 100*(237-30.2)/237=87.2% или в 8 раз. Выгода налицо!

Заключение

Велосипед мы не изобрели, это понятно. Результаты ожидаемы. Использование модуля ядра более опасно, чем обычного data-source ip-traffic, а уже тем более сбора по libpcap или netflow. В случае ошибок или переполнения буферов зависает ядро вместе со всеми процессами, или блокируются все сокеты. Было проведено тестирование на предмет поддержки "нехороших ситуаций" вроде ping -f или nmap -sS -PS 80 -iR 100. Однако стабильность работы не гарантируется, тестируйте модуль со всей осторожностью!

Кто-нибудь особенно умный может спросить: "А собственно зачем вы это делали? Фильтровать можно и в ядре, через тот же ipfw deny, pfctl и прочее. Все будет быстро и надежно."
Возможно. Однако вам придется как-то синхронизировать таблицу юнитов и политик учета с правилами firewall, фактически городить зоопарк скриптов и дублировать одно и то же дважды. Зачем? Использование NeTAMS позволяет хранить всю информацию о правилах в одном месте, без проблем применяя всякие хитрости вроде break flag, prefix table и срабатывание по времени суток. Совершенно прозрачно работают сервисы квот, системные политики, биллинг, и так далее.

Возможные направления улучшения и развития:
  • Создать аналогичный продукт для Linux, видимо на базе ULOG
  • Сделать поддержку RAW IP пакетов, PPP и так далее
  • Проверить работоспособность в случае нескольких модулей ядра, работающих одновременно

Рейтинг@Mail.ru