Пример как работает у меня (правда на N+)
more /etc/rc.firewall
#!/bin/sh -
f='/sbin/ipfw'
ifOut='vlan13'
#ifOut='re0 ng0 ng1'
ifVia=''
ifRecv=''
tmp_or=''
tmp_in=' in via'
tmp_out=' out via'
ifIVia=''
ifOVia=''
for i in $ifOut
do
ifVia="${ifVia}${tmp_or}via $i"
ifRecv="${ifRecv}${tmp_or}recv $i"
ifIVia="${ifIVia}${tmp_or}${tmp_in} $i"
ifOVia="${ifOVia}${tmp_or}${tmp_out} $i"
tmp_or=' or '
done
${f} -f flush
${f} table all flush
######## del all nat
for n_t in `${f} nat show config |awk '{print $3}'`; do
${f} nat $n_t delete
# echo "Delete old nat:" $n_t
done
######## какие сети надо натить в какой реальный ИП
${f} table 3 add 10.100.60.0/24 1
${f} table 3 add 10.100.61.0/24 2
${f} table 3 add 10.100.62.0/24 3
${f} table 3 add 10.100.63.0/24 4
${f} table 3 add 10.100.64.0/24 5
${f} table 3 add 10.100.65.0/24 6
${f} table 3 add 10.100.66.0/24 7
${f} table 3 add 10.100.67.0/24 8
####### Реальные ИП в которые нат <- NAT
# IP POOL at table 4 add xxx.xxx.xxx без последней точки
START_PREFIX="/sbin/ipfw table 4 add 1.2.3"
STA_RT=0
NUMBER=103 ## тут начало диапазона реальных -1
while [ $NUMBER -lt 111 ]; do ## тут конец диапазона
NUMBER=$(($NUMBER+1))
STA_RT=$(($STA_RT+1))
$START_PREFIX.$NUMBER $STA_RT
/sbin/ipfw nat $STA_RT config ip 1.2.3.$NUMBER log reset same_ports
done
${f} add 515 nat tablearg ip from table\(3\) to any { $ifOVia }
${f} add 2005 nat tablearg ip from any to table\(4\) { $ifIVia }
# dns, и прочие сайты что проходят при отключеном нете
${f} table 100 add 8.8.8.8
${f} table 100 add 50.16.196.80
${f} table 100 add 107.21.122.223
# mysql slave server
${f} table 101 add 50.17.182.68
${f} add 50 allow tcp from any to me 22
${f} add 51 allow tcp from me 22 to any
${f} add 110 allow ip from any to any via lo0
${f} add 120 skipto 1000 ip from me to any
${f} add 130 deny icmp from any to any in icmptype 5,9,13,14,15,16,17
${f} add 160 skipto 2000 ip from any to me
${f} add 200 skipto 500 ip from any to any { $ifVia }
${f} add 300 skipto 4500 ip from any to any in
${f} add 400 skipto 450 ip from any to any { $ifRecv }
${f} add 420 divert 1 ip from any to any
${f} add 450 divert 2 ip from any to any
${f} add 490 allow ip from any to any
${f} add 500 skipto 32500 ip from any to any in
${f} add 510 divert 1 ip from any to any
${f} add 540 allow ip from any to any
${f} add 1000 allow udp from any 53,7723 to any
${f} add 1010 allow tcp from any to any setup keep-state
${f} add 1020 allow udp from any to any keep-state
${f} add 1100 allow ip from any to any
${f} add 2000 check-state
${f} add 2010 allow icmp from any to any
${f} add 2020 allow tcp from any to any 22,80,443,5006
${f} add 2030 allow tcp from "table(101)" to any 3306
${f} add 2045 call 500 ip from any to any { $ifIVia }
${f} add 2050 deny ip from any to any { $ifVia }
${f} add 2060 allow udp from any to any 53,7723
${f} add 2100 deny ip from any to any
${f} add 4500 allow ip from any to "table(100)"
${f} add 32490 deny ip from any to any
${f} add 32500 allow ip from "table(100)" to any
net.inet.ip.fw.one_pass=0
ну и плюс правленый скрипт который пишет в окна фаервола
месяц полет нормальный порядка NNNN пациентов в час пик