Vadim Goncharov wrote:
22.06.11 @ 18:53 Oleg Cherevko wrote:
На данный момент ng_netflow, в силу его внутреннего устройства, до
этого идеала далеко. У него проблемы с broadcast- и
multicast-трафиком, с пакетами, отсеяными firewall'ом, с ipfw fwd, с
локальным трафиком и,
С fwd можно справляться, навешивая ноду непосредственно на ng_ether, а
не через файрвол, и включая соответствующие флаги в конфигурации узла,
чтобы не считало дважды тот же трафик.
Да, можно. Но это будет полноценным решением лишь в том случае, если в картине
отсутствует ipfw nat, а у меня он предполагается присутствующим. Если собирать
netflow на выходе через ng_ether, невозможно будет увидеть детализацию трафика
по внутренним ip (которые раньше по пути движения пакета переписывает NAT).
возможно, еще с чем-то, до чего я пока не добрался. Справедливости
ради следует сказать, что все вышеперечисленное обычно не является
определяющим в общем объеме трафика, так что ng_netflow для основного
трафика на машине без особых изысков в конфигурации -- вполне рабочий
инструмент. Но мне хочется перевести его из фазы "make it work" в фазу
"make it right", (ну а затем и в "make it fast", если понадобится).
Боюст, это опять потребует архитектурных изменений :)
Чтобы совсем все идеально правильно работало -- наверное, да. Но чтобы выправить
ряд текущих косяков с broadcast'ами, multicast'ами и ipfw fwd, как оказалось,
нужно не так уж много всего менять. Совсем скромный патч для ng_ipfw (чтобы он
сохранял oif в mbuf tag'е). Чуть менее скромный патч для составляющих ng_netflow
(чтобы доставать этот oif, а также next_hop от ipfw fwd из соответсвующих tag'ов
+ еще кой-чего) и voila!
Было так (default смотрит в сторону vlan3):
#flowctl netflow show
SrcIf SrcIPaddress DstIf DstIPaddress Pr SrcP DstP Pkts
vlan2 192.168.1.140 vlan3 224.0.0.5 89 0000 0000 2
(null) 192.168.1.141 vlan3 224.0.0.6 89 0000 0000 1
(null) 192.168.1.141 vlan3 224.0.0.5 89 0000 0000 7
vlan2 192.168.1.142 vlan3 224.0.0.5 89 0000 0000 7
vlan3 10.1.0.5 vlan3 10.1.15.255 17 445c 445c 1
vlan3 10.1.0.5 vlan3 255.255.255.255 17 445c 445c 1
(null) 127.0.0.1 lo0 127.0.0.1 1 0000 0000 6
lo0 127.0.0.1 lo0 127.0.0.1 1 0000 0000 6
vlan3 10.1.0.3 vlan3 10.1.15.255 17 0089 0089 3
Стало так:
#flowctl netflow show
SrcIf SrcIPaddress DstIf DstIPaddress Pr SrcP DstP Pkts
vlan2 192.168.1.140 (null) 224.0.0.5 89 0000 0000 2
(null) 192.168.1.141 vlan2 224.0.0.6 89 0000 0000 1
(null) 192.168.1.141 vlan2 224.0.0.5 89 0000 0000 7
vlan2 192.168.1.142 (null) 224.0.0.5 89 0000 0000 7
vlan3 10.1.0.5 (null) 10.1.15.255 17 445c 445c 1
vlan3 10.1.0.5 (null) 255.255.255.255 17 445c 445c 1
(null) 127.0.0.1 lo0 127.0.0.1 1 0000 0000 8
lo0 127.0.0.1 (null) 127.0.0.1 1 0000 0000 8
vlan3 10.1.0.3 (null) 10.1.15.255 17 0089 0089 2
В новом варианте четко видно, какие пакеты приняты, какие отправлены и через
какой именно интерфейс. (На приведенном примере можно разглядеть выправление
ситуации с broadcast'ами, multicast'ами и некоторое перемены с локальным
траффиком, но учет ipfw fwd, которого тут не видно, тоже работает -- уже на
соседней машине, которая в production).
Сначала в ng_netflow попадает out-пакет идущий на 127.0.0.1, у него
SrcIf=(null), как и положено out-пакетам, потом он уходит в lo0 и тут
же снова принимается из lo0, но SrcIf уже, понятное дело, lo0, а
поскольку SrcIf входит в определение того, что такое flow, то вот и
образуется
Нет, вот в этом месте неправильно.
Да, согласен, тут было не додумано. Значит, все-таки, не зря в рассылку написал.
второй flow для того же пакета, что формально правильно, но по сути
неправильно, ибо в результате такой трафик учитывается дважды. Теперь
вопрос, что можно с этим сделать? Ну, кроме как просто не отправлять в
ng_netflow out-пакеты, идущие на lo0? Может у кого есть какие идеи?
Там на самом деле происходит следующее: у узла в конфигурации включен
флаг NG_NETFLOW_CONF_ONCE (conf=7), и узел честно помечает прошедший
через него пакет mbuf-тегом "пакет уже побывал на netflow-узле с
id=..."; в норме это приведет к тому, что в следующий раз этот пакет
будет отсеян еще до разбора, с какого он интерфейса, и с какого flow.
Однако далее пакет с этим тегом отправляется в if_lo, а там основная
функция обработчик начинается вот так:
int
if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen)
{
int isr;
M_ASSERTPKTHDR(m);
m_tag_delete_nonpersistent(m);
То есть, почти все теги первым делом удаляются, пакет как бы становится
чистым, и потом "поступает на вход". И дальше, когда он снова попадает в
ng_netflow, тот уже не обнаруживает на нем своей метки, и вот только
тогда вступает в действие то правило, что интерфейс у flow другой.
Не знаю, насколько это архитектурная особенность :) т.е. насколько
повредит сделать тег постоянным. Можно попробовать (эффекты, если что,
вылезут в других частях системы), если хочется, то вот решение:
исправить в /usr/src/sys/netgraph/netflow/ng_netflow.с и заменить строчку
mtag = m_tag_alloc(MTAG_NETFLOW, MTAG_NETFLOW_CALLED,
на
mtag = m_tag_alloc(MTAG_NETFLOW, MTAG_NETFLOW_CALLED |
MTAG_PERSISTENT,
Ну и как обычно, send-pr с соответствующим полем fix, особенно если
ничего не сломается.
Спасибо за идею. Я поэкспериментирую.
--
Olwi