Итак, решился таки перейти на pf, используя его firewall, nat и portfwd функционал.Собрал из нескольких мануалов сборную солянку, так что поправляйте меня, если я неправильно что-то буду делать.
Для начала в ядре подрубаем следующее:
# pf
device pf
device pflog
device pfsync
options ALTQ
options ALTQ_CBQ # Class Bases Queuing (CBQ)
options ALTQ_RED # Random Early Detection (RED)
options ALTQ_RIO # RED In/Out
options ALTQ_HFSC # Hierarchical Packet Scheduler (HFSC)
options ALTQ_PRIQ # Priority Queuing (PRIQ)
options ALTQ_NOPCC # Required for SMP build
Отключаем ipfw:
#options IPDIVERT
#options IPFIREWALL_VERBOSE
#options IPFIREWALL_VERBOSE_LIMIT=10
В /etc/sysctl.conf:
net.inet.ip.fw.enable=0
net.inet6.ip6.fw.enable=0
В /etc/rc.conf:
ppp_nat="NO"
firewall_enable="NO"
gateway_enable="NO"
natd_enable="NO"# PF
pf_enable="YES"
pflog_enable="YES"
pf_rules="/etc/pf.conf"
pf_program="/sbin/pfctl"
pf_flags=""
Теперь непосредственно курочим в самом pf.conf:
ext_if="bge0" # интерфейс на выход
int_if="bge1" # интерфейс на вход
tun_if="tun0" # PPPD-интерфейс
lo0="127.0.0.1" # Loopback
vlan1="192.168.2.0/24" # на всякий случай описываем сеть VLAN 1 (1)
vlan2="192.168.1.0/24" # на всякий случай описываем сеть VLAN 10 (2)
wserver="192.168.1.100" # Наш сервер, нуждающийся в пробросе портов# Settings
set debug urgent # Выводим только серьёзные ошибки
set block-policy return # Возвращаем плохие пакеты
set state-policy floating # Развязка пакета от интерфейса
set limit { states 250000, frags 175000 } # А чего мелочиться?
set optimization normal # Обыкновенная оптимизация
set ruleset-optimization none # Не будем оптимизировать правила
set skip on lo0 # Пропускаем все попытки обработать loopback
scrub in all # Отсылаем только собранные пакеты
tcp_services="{ 22, 25, 37, 43, 53, 80, 443, 110, 119 }" # Открытые порты для всех
icmp_types="{ echoreq, unreach}" # какие типы icmp запросов можно использовать
# NAT
nat on $tun_if from !($tun_if) -> ($tun_if:0) # NAT'им всё, что за PPP, так?
# Фильтрация
antispoof quick for $ext_if # Антиспуфинг для внешнего интерфейса bge0
# Сами правила
pass out on $ext_if from $ext_if to any # разрешаем серверу доступ в интернет
pass in on $int_if from any to $ext_if # в одностороннем порядке разрешаем всё, что лезет из локальной сети
pass in on $vlan1 proto tcp from $ext_if to $vlan1 port tcp_services # взаимно разрешаем все хорошие порты на первом vlan
pass in on $ext_if proto tcp from any to $ext_if port ssh # разрешаем стучаться откуда-либо до SSH на маршрутизаторе
# Форвардим
rdr on $ext_if proto tcp from any to any port 80 -> $server port 80
rdr on $ext_if proto tcp from any to any port 20 -> $server port 20
rdr on $ext_if proto tcp from any to any port 21 -> $server port 21
rdr on $ext_if proto tcp from any to any port 135 -> $server port 22
rdr on $ext_if proto tcp from any to any port 3000:3500 -> $server
Меньше всего уверен насчёт правил и NAT'a.