четвер, 4 листопада 2010 р.

ipfw vs pf: удобство синтаксиса

Многие взлюбили pf за наличие кучи приятных плюшек в конфиге. Вот только иногда люди забывают (или даже не знают), что большинство этих плюшек реализуются не собственно фаерволлом, а утилитой pfctl, которая транслирует конфиг при загрузке. А это: переменные, возможность вместо адреса или сети указывать "адрес (или сеть) с такого то интерфейса", возможность практически в любом месте правила вместо одного элемента указать список (в фигурных скобках).
"Ну и что?" скажут некоторые. А то, что, во первых, без четкого понимания что это всего лишь syntax sugar, реализуемый pfctl, часто можно оказаться обманутым и получить не то, что ожидалось. Напримерь кусок "from em0:network" это на самом деле не "от адресов с сетей, которые установлены на em0", а "от адресов с сетей, который былы установлены на em0 в момент загрузки правил". А правило "block in from not { 192.168.0.0/16, 10.0.0.0/8 }" на самом деле оттранслируется в два: "block in from not 192.168.0.0/16" и "block in from not 10.0.0.0/8" и в результате заблокирует весь трафик, а не трафик от сетей, кроме перечисленных.
"Ну и пусть! Все-равно же удобно! А в ipfw такого нет". Или есть?
Ну, во первых некоторые вещи в ipfw просто не нужны, потому что изначально есть правильные элементы: есть "me" вместо костыля "table <me> { self; }", есть "allow ip from { x or not y or z } to any" (причем и то, и то это элементы фаерволла, а не препроцессора), есть возможность задавать через запятую список сетей или вообще "1.2.3.0/24{128,35-55,89}"
Ну а во вторых все-равно хочется переменных и т.п., пусть и это будет транслироваться на этапе загрузки? Ну так вот же: -p . И вот так оно включается
firewall_enable="YES"
firewall_type="/etc/ipfw.conf.m4"
firewall_flags="-p /usr/bin/m4"
firewall_nat_enable="YES"
А вот так используется:
define(`ext_if',`vlan3')
define(`nat_ip',`100.100.100.20')
define(`rfc1918',`10.0.0.0/8, 172.16/12, 192.168/16')
define(`mailserviceip',`100.100.100.29')
define(`mailerip',`10.1.2.102')

nat 1 config ip nat_ip same_ports log
add nat 1 all from 10.0.0.0/8 to any out xmit ext_if
add deny all from rfc1918 to any out xmit ext_if

add nat 1 all from any to nat_ip in recv ext_if

add fwd mailerip,imaps tcp from any to mailserviceip imaps in

3 коментарі:

Yurij сказав...
Автор видалив цей коментар.
Yurij сказав...

К тому же, если я не ошибаюсь, то pf однопоточный, а ipfw многопоточный, тобишь производительность первого меньше на многопроцессорных машинах, нежели второго. Есть ли хотя-бы доля правды в моём предложении?

levsha сказав...

Строго говоря ни у ipfw, ни у pf нету своего потока выполнения: они исполняются в том потоке, где возникла задача обработки пакета ферволлом. Но да, так как pf закрыт биглоком, а в ipfw блокировка более гранулирована, можно утверждать что pf работает в одном потоке, а ipfw в нескольких.
Но вообще именно в этой заметке я намеренно ограничился только вопросом синтаксиса, не замахиваясь на сравнение глобально, по всем возможным пунктам