Наверно я неясно излагаю мысли, тогда распишу на примерах.
Допустим нам нужно реализовать нат, который будет по возможности не менять порты(чтобы у нас работал например SIP трафик), и пропускать клиентам ftp, PPTP трафик. в ipfw это выглядит вот так.
- Код: Выделить всё
nat 1 config if ext0 same_ports
add nat 1 ip from any to any via ext0
При этом клиенты, сидящие за ipfw NAT без проблем подключаются к ftp в интернете, и к VPN серверам через PPTP.
Смотрим точно такой же пример NAT на pf:
- Код: Выделить всё
nat on ext0 inet from int0:network to !(self) -> (ext0) static-port
Казалось бы чего еще нужно от жизни? А вот к ftp клиенты не могут подключиться, делаем следующее:
Добавляем правила в pf:
- Код: Выделить всё
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr pass on int0 inet proto tcp from <localnet> to !(self) port ftp -> 127.0.0.1 port 8021
anchor "ftp-proxy/*"
Запускаем демона ftp-proxy на 127.0.0.1 и порту 8021
В итоге клиенты и с pf nat и с ipfw nat подключаются к ftp серверам, но вот беда, клиенты за pf nat не могут подключиться к VPT PPTP серверу.
Проблема решается не очень адекватно:
- Код: Выделить всё
rdr on ext0 proto {tcp,udp} from any to ext0 port {1723} -> $IP_VPN_СЕРВЕРА
rdr on ext0 proto gre from any to ext0 -> $IP_VPN_СЕРВЕРА
Т.е. мне нужно бегать к каждому клиенту и узнавать к какому vpn серверу он собирается подключаться и добавлять эти правила для каждого VPN сервера, к которому хотят подключаться клиенты...
В итоге на ipfw эти вещи просто работают без лишних телодвижений, а вот в pf NAT какой-то "ущербный", для каждого протокола ему нужен отдельный демон, который бы изменял пакеты, если это требуется. (пример ftp, gre)