Ядерный NAT во FreeBSD


В последних версиях FreeBSD (по-моему с ветки 8.x) во FreeBSD появился так
называемый ядерный NAT (kernel nat) - механизм, замещающий стандартный демон NAT -
natd. Мои опыты и практическое использование показали, что ядерный NAT - намного
шустрее и отзывчивее natd, и при правильном использовании повышает
работоспособность даже самого тупого шлюза. Делается ядерный NAT не совсем быстро,
но оно того стоит.

Сначала пересобирается ядро. В файле /usr/src/sys/amd64/conf/MYKERNEL добавляются
опции для поддержки ядерного NAT.

cpu             I686_CPU
ident           OFFICE
options         GEOM_MIRROR
...
# Ядерный НАТ
options         IPFIREWALL
options         IPFIREWALL_NAT
options         IPFIREWALL_FORWARD
....

В файле /etc/rc.conf всё достаточно просто "как обычно":

hostname="office"
ifconfig_vr0="inet 192.168.1.1 netmask 255.255.255.0"
ifconfig_fxp0="inet 32.32.32.200 netmask 255.255.255.0"
defaultrouter="32.32.32.1"
gateway_enable="YES"

firewall_enable="YES"
firewall_type="simple"
firewall_simple_oif="fxp0"
firewall_simple_onet="32.32.32.0/24"
firewall_simple_iif="vr0"
firewall_simple_inet="192.168.1.0/24"
firewall_quiet="NO"
firewall_script="/etc/firewall.conf"

#Обычный NAT - не нужен
#natd_enable="YES"
#natd_interface="re0"
#natd_flags="-f /etc/redirect.conf"

Я специально привел кусок конфига, в котором наглядно видно, что natd -
для ядерного "ната" не нужен.

И осталось привести актуальный кусок из файла /etc/firewall.conf Этот файл - 
точная копия стандартного /etc/rc.firewall, который я просто поправил для своих
нужд, выкинув из него IPv6 и добавив всякие хак-проверки и баны. А в то место,
где раньше была секция natd - divert - я написал вставку своего ядерного NAT:

case ${firewall_type} in
[Oo][Pp][Ee][Nn])
    ${fwcmd} add 65000 pass all from any to any
    ;;

[Ss][Ii][Mm][Pp][Ll][Ee])

    # ...

    # KERNEL NAT
    ${fwcmd} nat 1 config if ${oif} log same_ports unreg_only
    ${fwcmd} add nat 1 ip from ${inet} to any
    ${fwcmd} add nat 1 ip from any to ${onet} via ${oif}

    ${fwcmd} add fwd 192.168.1.1,3128 tcp from ${inet} to any 80

    # ....

esac

Squid все также остался прозрачным - но уже с использованием NAT ядра.