FreeBSD Kernel NAT
Купил я себе новый HDD: WD GreenPower, емкостью 1 TB. Цель покупки — файло/медиапомойка. Организация любой помойки, при условии анлимного канала и аккаунта на torrents.ru — дело пустяковое. Через некоторое время активного использования торента (больше 20 раздач со скоростью > 1 Mb) начал замечать такую картину:
# top | grep natd 42549 root 1 45 0 9408K 2856K select 0:01 7.78% natd
Мало того, что natd светит адреса внутренних хостов, так он еще нехило потребляет системные ресурсы. Решено было переходить на «ядерный» нат. Добавляем в конфиг ядра опции для поддержки ipfw и ipfw nat:
options IPFIREWALL options IPFIREWALL_FORWARD options IPFIREWALL_VERBOSE options IPFIREWALL_VERBOSE_LIMIT=1000 options IPFIREWALL_NAT options LIBALIAS options IPDIVERT options DUMMYNET
Далее:
# cd /usr/src # make buildkernel KERNCONF=NEW_MY_CONF .... # make installkernel KERNCONF=NEW_MY_CONF
Ребутимся и редактируем скрипт ipfw. Коментим те строки, где были правила divert и заменяем на правила ipfw nat:
# ${fwcmd} add divert natd all from any to any via ${inet_if}
# ${fwcmd} add divert natd all from any to any via lo0
${fwcmd} nat 1 config ip ${inet_ip} log same_ports unreg_only
${fwcmd} add nat 1 all from ${lan_net} to any
${fwcmd} add nat 1 all from any to ${inet_ip}
, где ${inet_if} — интерфейс смотрящий «наружу», ${lan_net} — внутренняя сеть (192.168.0.1/24), ${inet_ip} — внешняя пиха.
unreg_only говорит ipfw натить только частные сети
same_ports пытается оставлять те же номера портов
Дальше нам нужно остановить нат:
# /etc/rc.d/natd stop
Дальше комментируем все строки связанные с natd в /etc/rc.conf и перегружаем правила ipfw. Проверяем работу kernel nat и наслаждаемся всеми его преимуществами.
P.S. Для того, чтобы пробросить порт внутрь локальной сети, конфигурация ipfw nat должна выглядеть так:
${fwcmd} nat 1 config ip ${inet_ip} unreg_only same_ports log redirect_port tcp 192.168.0.17:80 80
${fwcmd} add nat 1 all from ${lan_net} to any
${fwcmd} add nat 1 all from any to ${inet_ip}
Это будет означать что мы прокидываем все входящие tcp пакеты адресованные 80 порту на внешнем IP на 80 порт машины с адресом 192.168.0.17
Рубрики: FreeBSD, Security · Теги: FreeBSD, ipfw, kernel nat, natd, redirect port, WD GreenPower

9 февраля 2010 в 0:45
· Ссылка
В правиле проброски портов заместо ${fwcmd} nat 1 config if ${inet_ip} надо ставить не адрес а интерфейс, раз уж такое дело… Поправьте если не прав.
Возник вопрос. Не подскажете, почему правила при проброске портов вписаные в стартап скрипт ipfw при старте не работают, однако, при введении непосредственно команды, например
ipfw nat 123 config if rl0 log same_ports unreg_only redirect_port tcp 192.168.0.2:17084 17084
правио моментально вступает в силу? Синтаксис проверял, все вроде абсолютно верно, все остальные правила срабатывают, однако проброска нет (
9 февраля 2010 в 12:43
· Ссылка
@ Satarum:
1) Спасибо за указание на очепятку. На самом деле строка конфига должна выглядеть так:
${fwcmd} nat 1 config ip ${inet_ip}
Сейчас же исправлю :)
2) По поводу страртового скрипта ipfw:
Путь к твоему скрипту должен быть статически прописан в rc.conf. У меня это выглядит так:
# cat /etc/rc.conf | grep firewall
firewall_enable=»YES»
firewall_script=»/usr/local/etc/firewall/rc.firewall»
С правилами при старте нет никаких проблемм. Также не забудь вписать в начало своего скрипта строку с указанием ipfw сбросить все правила:
ipfw -f flush
10 ноября 2010 в 22:52
· Ссылка
в rc.conf добавить вместо старых значений
firewall_nat_enable=»YES»
firewall_nat_interface=»rl0″