Инструмент ng_ipacct, разработанный Романом Палагиным, предназначен для сбора статистики о трафике и реализует Cisco ip accounting. Являясь нодой netgraph, он работает полностью в ядре системы, что существенно снижает требования к системным ресурсам. Снятие и обнуление статистики происходит с помощью утилиты ipacctctl.
Инструмент ng_ipacct, разработанный Романом Палагиным, предназначен для сбора статистики о трафике и реализует Cisco ip accounting. Являясь нодой netgraph, он работает полностью в ядре системы, что существенно снижает требования к системным ресурсам. Снятие и обнуление статистики происходит с помощью утилиты ipacctctl. Для возможности работы с ng_ipacct описанными ниже методами нужно скомпилировать ядро с опциями:
options NETGRAPH
options NETGRAPH_ETHER
options NETGRAPH_IFACE
options NETGRAPH_KSOCKET
options NETGRAPH_SOCKET
options NETGRAPH_TEE
/sbin/kldload ng_netflow
ngctl -f- <<-SEQ
mkpeer tee dummy right2left
name .:dummy divert_tee_in
mkpeer divert_tee_in: echo right echo
mkpeer divert_tee_in: ksocket left inet/raw/divert
name divert_tee_in:left divert_sock_in
msg divert_sock_in: bind inet/0.0.0.0:3021
disconnect dummy
mkpeer divert_tee_in: ipacct left2right rl0_in
name divert_tee_in:left2right ng_ipacct
SEQ
Попавший в приведенные правила файервола пакет либо будет принят, либо продолжит путешествие по правилам ipfw, в зависимости от значения sysctl переменной net.inet.ip.fw.one_pass (1 - пакет считается принятым, 0 - сравнение продолжается). При этом автор патча сообщает, что такой способ доставки трафика в netgraph более эффективен, чем трюки с tee.
Также отметим, что в случае работы сетевых интерфейсов в режиме моста, мост должен быть фильтрующим, чтобы пакеты попадали в файервол. Приведенные методы также должны работать и с модулем ng_netflow. Добавлю, что описанные решения были проверены на маршрутизаторах NanoWall. Надеюсь, эта статья окажется полезной.
PS. А еще добавлю, что с 2006 года в netgraph появились ноды ng_ipfw, связывающая пакетный фильтр ipfw и подсистему netgraph, а также ng_nat, позволяющая делать ядерный NAT. Возможно, позже напишу и об этом.
Инструмент ng_ipacct, разработанный Романом Палагиным, предназначен для сбора статистики о трафике и реализует Cisco ip accounting. Являясь нодой netgraph, он работает полностью в ядре системы, что существенно снижает требования к системным ресурсам. Снятие и обнуление статистики происходит с помощью утилиты ipacctctl. Для возможности работы с ng_ipacct описанными ниже методами нужно скомпилировать ядро с опциями:
options NETGRAPH
options NETGRAPH_ETHER
options NETGRAPH_IFACE
options NETGRAPH_KSOCKET
options NETGRAPH_SOCKET
options NETGRAPH_TEE
Классический метод использования ng_ipacct предполагает, соединение через ng_tee с нодой ng_ether, т.е. трафик считается на ethernet интерфейсе. Приведем пример соответствующего скрипта, который поставляется вместе с исходным кодом самой утилиты.
/sbin/kldload ng_ipacct > /dev/null 2>&1
/usr/sbin/ngctl mkpeer rl0: tee lower right
/usr/sbin/ngctl connect rl0: lower upper left
/usr/sbin/ngctl name rl0:lower rl0_acct_tee
/usr/sbin/ngctl mkpeer rl0_acct_tee: ipacct right2left rl0_in
/usr/sbin/ngctl name rl0_acct_tee:right2left rl0_ip_acct
/usr/sbin/ngctl connect rl0_acct_tee: rl0_ip_acct: left2right rl0_out
В первой строке загружается модуль ng_ipacct, остальные строки иллюстрирует рисунок.
/usr/sbin/ngctl mkpeer rl0: tee lower right
/usr/sbin/ngctl connect rl0: lower upper left
/usr/sbin/ngctl name rl0:lower rl0_acct_tee
/usr/sbin/ngctl mkpeer rl0_acct_tee: ipacct right2left rl0_in
/usr/sbin/ngctl name rl0_acct_tee:right2left rl0_ip_acct
/usr/sbin/ngctl connect rl0_acct_tee: rl0_ip_acct: left2right rl0_out
В первой строке загружается модуль ng_ipacct, остальные строки иллюстрирует рисунок.
Таким образом, входящий в ethernet интерфейс rl0 трафик с хука lower попадает на ноду rl0_acct_tee, где происходит его копирование на хук upper ноды rl0 и на хук rl0_in ноды rl0_ip_acct. В обратном направлении все происходит аналогично - с хука upper через tee ноду на
хук lower, при параллельном копировании в ng_ipacct. Как видно из примера, нода tee служит для дублирования потоков данных проходящих через нее в обоих направлениях.
При кажущейся простоте метода, сложности все же возникают при необходимости учета трафика на gif и tun интерфейсах, а так же на интерфейсах, работающих в режиме моста, в виду особенностей их реализации. Ниже приведены приемы, позволяющие обойти эти проблемы. Наиболее универсальный способ - это использование правила tee файервола ipfw.
хук lower, при параллельном копировании в ng_ipacct. Как видно из примера, нода tee служит для дублирования потоков данных проходящих через нее в обоих направлениях.
При кажущейся простоте метода, сложности все же возникают при необходимости учета трафика на gif и tun интерфейсах, а так же на интерфейсах, работающих в режиме моста, в виду особенностей их реализации. Ниже приведены приемы, позволяющие обойти эти проблемы. Наиболее универсальный способ - это использование правила tee файервола ipfw.
nodename=ipacct_${IFACE}
hookprefix=${IFACE}
/sbin/kldload ng_netflow
ngctl -f- <<-SEQ
mkpeer ipacct ctl ctl
name .:ctl ${nodename}
### хук для входящего трафика
mkpeer ${nodename}: ksocket ${hookprefix}_in inet/raw/divert
name ${nodename}:${hookprefix}_in ${nodename}_in
msg ${nodename}_in: bind inet/0.0.0.0:3021
### хук для исходящего трафика
mkpeer ${nodename}: ksocket ${hookprefix}_out inet/raw/divert
name ${nodename}:${hookprefix}_out ${nodename}_out
msg ${nodename}_out: bind inet/0.0.0.0:3022
rmhook .:ctl
SEQ
hookprefix=${IFACE}
/sbin/kldload ng_netflow
ngctl -f- <<-SEQ
mkpeer ipacct ctl ctl
name .:ctl ${nodename}
### хук для входящего трафика
mkpeer ${nodename}: ksocket ${hookprefix}_in inet/raw/divert
name ${nodename}:${hookprefix}_in ${nodename}_in
msg ${nodename}_in: bind inet/0.0.0.0:3021
### хук для исходящего трафика
mkpeer ${nodename}: ksocket ${hookprefix}_out inet/raw/divert
name ${nodename}:${hookprefix}_out ${nodename}_out
msg ${nodename}_out: bind inet/0.0.0.0:3022
rmhook .:ctl
SEQ
В приведенном примере две ноды типа ksocket отправляют в ng_ipacct данные, попадающие в соответствующие сокеты 0.0.0.0:3021 и 0.0.0.0:3022. В эти сокеты трафик направляется правилами файервола:
ipfw add 64021 tee 3021 ip from any to room101 via ${IFACE}
ipfw add 64022 tee 3022 ip from room101 to any via ${IFACE}
ipfw add 64022 tee 3022 ip from room101 to any via ${IFACE}
При этом следует учитывать, что все запрещающие правила, должны предшествовать правилам tee, т.к. прохождение сетевых пакетов по ipfw заканчивается на этих правилах, и пакеты считаются принятыми. Такую же схему можно реализовать используя правила divert и ноду ng_echo, которая отправляет пришедший поток данных обратно к источнику. Проиллюстрируем это на примере входящего трафика.
/sbin/kldload ng_netflow
ngctl -f- <<-SEQ
mkpeer tee dummy right2left
name .:dummy divert_tee_in
mkpeer divert_tee_in: echo right echo
mkpeer divert_tee_in: ksocket left inet/raw/divert
name divert_tee_in:left divert_sock_in
msg divert_sock_in: bind inet/0.0.0.0:3021
disconnect dummy
mkpeer divert_tee_in: ipacct left2right rl0_in
name divert_tee_in:left2right ng_ipacct
SEQ
В январе 2005 года Gleb Smirnoff опубликовал патч для ноды ng_ipfw, позволяющий копировать трафик из ipfw в netgraph, не прибегая к использованию сокета divert. Это реализуется директивой файервола ngtee. Приведем пример соединения нод.
/sbin/kldload ng_ipacct > /dev/null 2>&1
/sbin/kldload ng_ipfw > /dev/null 2>&1
ngctl -f- <<-SEQ
mkpeer ipfw: ipacct 333 rl0_in
name ipfw:333 rl0_ip_acct
connect ipfw: rl0_ip_acct: 444 rl0_out
SEQ
/sbin/kldload ng_ipacct > /dev/null 2>&1
/sbin/kldload ng_ipfw > /dev/null 2>&1
ngctl -f- <<-SEQ
mkpeer ipfw: ipacct 333 rl0_in
name ipfw:333 rl0_ip_acct
connect ipfw: rl0_ip_acct: 444 rl0_out
SEQ
Трафик перенаправляется в netgraph следующими правилами ipfw:
ipfw add 100 ngtee 333 ip from any to any in
ipfw add 200 ngtee 444 ip from any to any out
Также существует директива netgraph, которую можно использовать совместно с ng_echo, аналогично тому, как это делалось в приведенном выше примере с правилом divert. Проиллюстрируем случай входящего трафика.
ipfw add 100 ngtee 333 ip from any to any in
ipfw add 200 ngtee 444 ip from any to any out
Также существует директива netgraph, которую можно использовать совместно с ng_echo, аналогично тому, как это делалось в приведенном выше примере с правилом divert. Проиллюстрируем случай входящего трафика.
/sbin/kldload ng_ipacct > /dev/null 2>&1
/sbin/kldload ng_ipfw > /dev/null 2>&1
ngctl -f- <<-SEQ
mkpeer ipfw: tee 333 left
name ipfw:333 rl0_tee
mkpeer rl0_tee: ipacct left2right rl0_in
mkpeer rl0_tee: echo right qqq
SEQ
Данному примеру будет соответствовать правило ipfw:
ipfw add 100 netgraph 333 ip from any to any in
/sbin/kldload ng_ipfw > /dev/null 2>&1
ngctl -f- <<-SEQ
mkpeer ipfw: tee 333 left
name ipfw:333 rl0_tee
mkpeer rl0_tee: ipacct left2right rl0_in
mkpeer rl0_tee: echo right qqq
SEQ
Данному примеру будет соответствовать правило ipfw:
ipfw add 100 netgraph 333 ip from any to any in
Попавший в приведенные правила файервола пакет либо будет принят, либо продолжит путешествие по правилам ipfw, в зависимости от значения sysctl переменной net.inet.ip.fw.one_pass (1 - пакет считается принятым, 0 - сравнение продолжается). При этом автор патча сообщает, что такой способ доставки трафика в netgraph более эффективен, чем трюки с tee.
Также отметим, что в случае работы сетевых интерфейсов в режиме моста, мост должен быть фильтрующим, чтобы пакеты попадали в файервол. Приведенные методы также должны работать и с модулем ng_netflow. Добавлю, что описанные решения были проверены на маршрутизаторах NanoWall. Надеюсь, эта статья окажется полезной.
PS. А еще добавлю, что с 2006 года в netgraph появились ноды ng_ipfw, связывающая пакетный фильтр ipfw и подсистему netgraph, а также ng_nat, позволяющая делать ядерный NAT. Возможно, позже напишу и об этом.
вот тебе ссылочка http://www.blogdir.ru/, внеси свой блог в каталог, иначе твой рецепты будешь сам читать.
ОтветитьУдалить