Користувальницькькі налаштування

Налаштування сайту


ipfwnat

Розбіжності

Тут показані розбіжності між вибраною ревізією та поточною версією сторінки.

Посилання на цей список змін

Порівняння попередніх версій Попередня ревізія
Наступна ревізія По сторонах наступні версії
ipfwnat [2011/08/20 16:26]
ipfwnat [2022/09/24 14:39]
127.0.0.1 зовнішнє редагування
Рядок 1: Рядок 1:
 +====== Внимание ======
 +Данная реализация является устаревшей, и эта документация может быть использована только для общего развития.
 +{{:alertold.png? |}}
 +
 +
 +====== Краткий обзор ядерного NAT-а в FreeBSD ======
 +Распространенных вариантов NAT-а под FreeBSD есть довольно много. Это и natd, ipnat, pfnat, ng_nat либо как вариант «купи ASA 5550 и не выделывайся».\\
 +{{:ipfwnat.png?200|}} \\
 +
 +К сожалению, в последнее время мне попадалось очень мало хороших и главное доступных статей о ipfw nat который появился, если мне не изменяет память еще в 7.0.
 +Засим рассматривать под лупой сегодня будем мы именно его.\\
 +
 +Истинным адептам pf под кат рекомендуется не заглядывать, чтобы не травмировать себя излишними знаниями.\\
 +
 +===== Для начала объясню, почему именно ipfw nat =====
 +
 +  - Во-первых, потому, что я сторонник простых и очевидных решений, поддерживаемость которых возможна практически с первого взгляда без длительных медитаций и размышлений на тему «а как это работает? Оо». К сожалению, я не могу отнести к таковым нетривиальные гибриды вида ipfw+pfnat.
 +  - Во-вторых документации по ng_nat и pfnat (nat on intif from somenet to any -> extif – Ы?) уже достаточно много.
 +  - В-третьих я использую ipfw, и люблю его – за простоту, наглядность, предсказуемость, dummynet а гибриды вида ipfw+pf+altq… в общем смотрим «Во-первых».
 +
 +===== Матчасть. =====
 +ассматривать ipfw nat мы будем на примере сферической конеобразной сети в вакууме изображенной чуть выше. Собственно по схемке все довольно понятно – оговоримся сразу что НАТить мы будем сеть 172.16.0.0/21, на em1 висит адрес, ну скажем 8.8.8.8 а внутренние ресурсы сети к которым нам не нужно осуществлять трансляцию адресов – такие как например,<del>архивы порно</del> корпоративные почтовые сервера и прочие нужные штуки будут жить с адресами скажем 8.8.8.9, 8.8.8.10\\
 +Функционал ipfw nat практически полностью дублирует функционал libalias, которую также используют natd, ng_nat.\\
 +Если очень грубо самоцель NAT-сервера сводится к подмене src-ip в пакетах, пришедших на внутренний интерфейс (в нашем случае em0) на адрес исходящего интерфейса (в нашем примере em1) и внесении в свою таблицу соответствий данных для обратного преобразования по приходу нужных пакетов в ответ. Далее все отрихтованые соответствующим образом пакеты улетают либо по дефолтрауту ну либо куда вам нужно (если, допустим, наворотили PBR). \\
 +
 +//Итого в базовом варианте нам нужно следующее//
 +
 +Перебрать ядро с поддержкой ipfw, ipfw nat, libalias ну и дальше по вкусу
 +
 +  # cd /sys/i386/conf/
 +  # cp GENERIC NAT
 +  # vim NAT
 +  
 +После чего вставляем нечто похожее на это:
 +
 +  ident NAT
 +  options IPFIREWALL
 +  options IPFIREWALL_DEFAULT_TO_ACCEPT
 +  options IPFIREWALL_FORWARD
 +  options IPFIREWALL_VERBOSE
 +  options IPFIREWALL_VERBOSE_LIMIT=50
 +  options IPFIREWALL_NAT
 +  options LIBALIAS
 +  options ROUTETABLES=2
 +  options DUMMYNET
 +  options HZ="1000"
 +
 +Собираем и устанавливаем новое ядро предусмотрительно забекапив старое
 +
 +  # cp -R /boot/kernel /boot/good
 +  # config NAT
 +  # cd ../compile/NAT
 +  # make depend
 +  # make
 +  # make instal
 +  
 +В /etc/rc.conf добавляем 
 +
 +  firewall_enable="YES"
 +  firewall_nat_enable="YES"
 +  dummynet_enable="YES"
 +  firewall_type="/etc/firewall"
 +
 +Что как бы должно намекать на то, что инициализацию ipfw мы будем проводить при помощи /etc/firewall который хочется чтобы в простейшем случае выглядел, например, так:
 +
 +  # наша сеть которую нужно выпустить в интернет
 +  table 2 add 172.16.0.0/21
 +  # внутренние ресурсы которые нету смысла выпускать сквозь nat
 +  table 9 add 8.8.8.8
 +  table 9 add 8.8.8.9
 +  table 9 add 8.8.8.10
 +  #следующие три строчки собственно и есть nat =)
 +  nat 1 config log if em1 reset same_ports
 +  add 1200 nat 1 ip from table\(2\) to not table\(9\) via em1
 +  add 1300 nat 1 ip from any to 8.8.8.8 via em1
 +  
 +Для успокоения совести можно сделать еще в /etc/sysctl.conf что-то типа
 +
 +  net.inet.ip.fw.one_pass=1
 +  net.inet.ip.fastforwarding=1
 +  net.inet.tcp.nolocaltimewait=1
 +  net.inet.ip.portrange.randomized=0 
 +  
 +После перезагрузки все должно бы заработать. Проверяется работоспособность этого всего очень просто методом 
 +
 +  # ipfw nat 1 show
 +  nat 1: icmp=6, udp=55443, tcp=86794, sctp=0, pptp=0, proto=0, frag_id=10722 frag_ptr=0 / tot=152965
 +  
 +Вот такую вот скудную статистику в сравнении с pfctl –sa, при помощи параметра log собирает ipfw nat. 
 +
 +===== Кратко пробежимся по опциям скудные знания о которых мы можем почерпнуть из man =====
 +
 +**if** — интерфейс на котором будет производиться трансляция адресов\\
 +**log** — включает логирование «исчерпывающей» статистики по внутренним соединениям которую мы уже видели (ipfw nat1 show)\\
 +**reset** — намекает на то что при изменении интерфейса следует очищать внутреннюю табличку\\
 +**deny_in** — запрещает пропускать пакеты извне для которых не найдено соответствий во внутренней табличке.\\
 +**same_ports** — по возможности оставлять оригинальные порты в исходящих пакетах (рекомендуется включить)\\
 +**unreg_only** — проводить маскировку только пакетов пришедших из [[http://www.faqs.org/rfcs/rfc1918.html|«нереальных» сетей]].\\
 +**redirect_addr intip extip** — предписывает заворачивать трафик приходящий на extip к машине с intip. Сходным образом работают опции redirect_port и redirect_proto полезные для «вынесения» за NAT некоторых машин с нужными сервисами.\\
 +
 +Собственно экземпляров nat мы можем наплодить сколько угодно и на каких угодно интерфейсах/ip (ipfw nat 2 config log if em2 reset same_ports, например) и заворачивать в них трафик как нам вздумается.
 +Память которую ipfw nat использует в своей работе является памятью доступной для ядра и смотрится при помощи
 +  # sysctl -a | grep kmem
 +  vm.kmem_size_scale: 3
 +  vm.kmem_size_max: 335544320
 +  vm.kmem_size_min: 0
 +  vm.kmem_size: 335544320
 +  
 +Крутиться оная при помощи опции ядра KVA_PAGES (максимум 512 что соответствует 2Гб для i386).
 +
 +Как-то субъективно, при хорошенькой нагрузке на канале (у меня вылазит при >350-400Mbit/s) может требоваться периодический рестарт экземпляра nat-а, в целях высвобождения памяти, которую съедают таблички оного. Думаю, собака порылась в медленных механизмах отстреливания просроченных сессий. Рестарт можно делать элементарным скриптиком вида:
 +
 +  #!/bin/sh
 +  /sbin/ipfw nat 1 delete && /sbin/ipfw nat 1 config log if em1 reset same_ports
 +
 +Также как водиться все наступают на грабли с тем, что сам по себе libalias категорически не дружит с аппаратными считалками контрольных сумм а также с tcp segmentation offload, засим конфигурить карточки изначально рекомендую похожим образом:
 +
 +
 +  # cat /etc/rc.conf | grep ifconfig
 +  ifconfig_em1="inet 8.8.8.8 netmask 255.255.255.0 -rxcsum -txcsum -tso"
 +
 +Вот собственно и все. Работает все прозрачно, не имеет изначально болезней с сервисами типа pptp, ftp (pfnat) и не страдает удручающей медлительностью за счет переключений в юзерспейс (natd). Единственное чего действительно может не хватать – это нормального способа nat-ить из под пула адресов. Единственное что в этом случае приходит в голову это наплодить множество экземпляров на алиасах, но выглядит, это не так красиво как скажем у pfnat.\\
 +
 +//Как-то сумбурно получилось но надеюсь наглядно.//
 +
 +