Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> настройка —> ipfw nat

Подробное руководство по ipfw nat

Автор: terminus.


Версия статьи 1.3.6

Оглавление:

  • Опции конфигурации ipfw nat
  • Пример 1
  • Пример 2
  • Пример 3
  • Пример 4
  • Пример 5
  • Пример 6
  • Пример 7
  • Дополнительная информация


    По странному стечению обстоятельств в Сети встречается очень мало внятных руководств описывающих функции и сценарии применения механизма ipfw nat, несмотря на то, что его поддержка появилась уже давно - начиная с версии FreeBSD 7.0. Самое обидное, что удручающе выглядит секция man ipfw посвященная nat. А ведь именно ее начинает читать любой кто хотел бы попробовать в деле "ядерный нат", и, что закономерно - не всегда разбирается. В итоге люди переходят на natd, а некоторый горячие головы начинают использовать даже альтернативные фаерволы такие как pf/ipf. Целью заметки является детализированное (по мере сил) описание ipfw nat, а так же опыта использования этого инструмента в различных сетевых конфигурациях. В заметке будет много смысловых отсылок на замечательную  статью Вадима Гончарова (nuclight) где давалось подробное описание внутреннего устройства ipfw и сетевой подсистемы FreeBSD.

    Примеры приводимые в моей заметке отрабатывались на FreeBSD 7.2-STABLE.


    Прежде всего необходимо детально описать как именно происходит движение трафика в сетевом стеке FreeBSD. Без этого понимания целостной картины того "что же мы делаем", не сложится и все скатится просто к набору "хавтушек". На рисунках 1-а и 1-б показана гипотетическая система оборудованная двумя сетевыми адаптерами fxp0 и fxp1. Схема 1-а показывает физическое подключение, а схема 1-б уже логическое. Нас больше интересует схема логическая - на ней мы видим, что в каждом сетевом поключении для трафика существует два прохода - IN и OUT. Как легко можно догадаться в проход IN поступает трафик пришедший к нам из сети, а в проход OUT уходит то, что адресовано уйти в сеть к которой подлючен данный сетевой адаптер. Таким образом, возвращаясь к примеру системы с двумя сетевыми адаптерами, мы видим, что у нее существует четыре прохода для трафика. При добавлении к системе дополнительных сетевых адаптеров схема масштабируется.

    Но предыдущая схема не главная. На самом деле схема проходжения трафика через сетевой стек FreeBSD имеет только одну логическую сторону с проходами IN и OUT, независимо от количества сетевых адаптеров. Просто при движении трафика через стек, операционная система самостоятельно избирет какой именно из доступных IN и/или OUT проходов были и/или будут задействованы для передачи трафика. В соответствии с этим, к пакетам находящимся внутри сетевой подсистемы, добавляются метки указывающие на то, через какой IN проход конкретного сетевого адаптера к нам пришел трафик, и через какой OUT какого сетевого адаптера он уйдет из машины.


    Указанные два прохода IN и OUT важны тем, что при поступлении в них сетевого трафика, этот трафик попадает в фаервол где проходит через правила фильтрации ipfw. Таким образом, трафик проходящий через маршрутизатор проходит через правила ipfw два раза - на проходе IN сетевого адаптера через который он был получен, и на проходе OUT сетевого адаптера через который он будет передан (сейчас не рассматриваем случай включение фильтрации на уровне Ethernet - в таком случае трафик проходит через ipfw четыре раза). Точно так же трафик исходящий от самого маршрутизатора обязательно будет иметь свой OUT проход, а трафик адресованный непосредственно маршрутизатору войдет через свои IN проход.

    Ниже я привожу перепечатку части материала статьи Вадима Гончарова - того кусочка где объясняется движение трафика через Схему 2. Лучше самого автора я не напишу, а включить в статью это обьяснение очень-очень надо.



    ...Допустим, набор правил у нас такой:

    ipfw add 1        deny  tcp from any to any 135,445
    ipfw add 2 divert 8668  all from any to any via ext0
    ipfw add 3       count icmp from any to any
    ipfw add 4       allow  all from any to any
    # в 65535 по умолчанию deny

    Когда пакет проходит через машину, к нему системой прикрепляется дополнительная информация, помимо собственно его содержимого, видного в tcpdump. Например, на каком интерфейсе он был получен, через какой отправляется, и т.п. Их можно проверять соответствующими опциями в правилах ipfw, на рисунке показаны места, где будут срабатывать соответствующие указания in/out и recv/xmit для сетевух.

    Рассмотрим одну сторону роутера с рисунка выше более подробно, с точки зрения вызовов функций в ядре (чуть более подробная картинка из мана). На самом деле, с точки зрения функций, на рисунке выше нет двух сторон, она только одна, и различается параметром - обрабатываемой сетевухой.

    То есть, пакет на входе передается драйвером в ether_demux(), затем он попадает в ip_input(), в точку (2), где выполняются базовые проверки на корректность пакета, после чего пакет прилетает в ipfw - функция ipfw_chk(). Допустим, правила были простые, без задействования других подсистем. Тогда, вернувшись из ipfw, пакет продолжает движение по ip_input(), которая смотрит, предназначен ли пакет нашей машине ("to me" в терминах ipfw), либо кому-то другому. Если нам, то пакет уходит в точку (3), где решится, в какой сокет какой юзерлэндной программе его отправить.

    Если же пакет был предназначен не нам, пакет из ip_input() направится в точку (4), где ip_forward() проверит, установлен ли sysctl, разрешающий форвардинг, произведет декремент TTL и т.п. действия, после чего пакет придет в точку (6), функцию ip_output(). Туда же он попадет напрямую, когда какая-нибудь программа решит что-то отправить в сеть и передаст данные ядру.

    Функция ip_output() первым делом смотрит в таблицу маршрутизации, определяя, каков шлюз и на каком интерфейсе он находится. С этой информацией пакет вновь передается в ipfw, в котором опять пробегается по всем правилам. После выхода из ipfw_chk() в ip_output(), если ядро было скомпилировано с соответствующей опцией, проверяется, не был ли применен ipfw fwd - если да, то просмотр  таблицы маршрутизации выполняется заново с целью получить MAC-адрес нового шлюза. Затем пакет в точке (7) покидает ip_output() и передается дальше, на L2 и потом к драйверам интерфейсов.

    Это всё было для случая простых правил файрвола. Теперь, предположим, там появляется divert, рассмотрим на примере правил выше. Пакет из внутренней сети куда-то в Интернет на порт 80 войдет на внутреннем интерфейсе в точку (1), пройдет начальные проверки ip_input() в (2), будет передан в ipfw_chk() и начнет проходить по правилам. Под правило 1 он не подпадает, под 2 тоже, так как имя интерфеса сейчас int0, правило 3 опять-таки не срабатывает, но под правило 4 подходят все пакеты, и он выходит из ipfw_chk() дальше в ip_input(). Там выясняется, что предназначен он идти в Интернет, поэтому пакет попадает в точки (4) и затем (6), где ip_output() определяет адрес шлюза и то, что интерфейс будет ext0, с чем пакет и попадает опять в ipfw_chk() и снова идет по правилам. Правило 1 снова не подходит, но условие правила 2 срабатывает - "via ext0, проходим прямо сейчас через интерфейс ext0, в любом направлении".

    И вот здесь срабатывает divert - пакет из ipfw_chk() передается в точку (8), в подсистему divert, при этом к нему предварительно прикрепляется метаинформация с направлением (out), интерфейсом (ext0) и номером правила 2. Подсистема divert передает этот пакет в указанный в правиле порт (8668), на котором в нашем случае работает natd. Тот обрабатывает пакет, метаинформацию же - не трогает, и возвращает подсистеме divert вместе с измененным пакетом как есть (так поступают большинство divert-демонов, хотя любой их них, в принципе, может поменять эту информацию, и пакет будет передан в другое место).

    Подсистема divert выводит полученный из natd пакет из точки (9) в точку (6). Следует обратить внимание - пакет попадает в ip_output() ЕЩЕ РАЗ! Это необходимо, так как демон мог вернуть пакет с совершенно другими адресами или вообще создать новый пакет. Но в нашем случае пакет несет с собой диверт-тег, метаинформацию, самая важная часть которой - номер правила. При входе в ipfw_chk() пакет первым делом проверяется на наличие этого самого тега. Он найден, и в нем содержится номер правила - 2. Поэтому ipfw_chk() пропускает правила номер 1 и 2, и начинает с номера 2+1, то есть 3 (если бы пакет применялся к указанному номеру, а не следующему, то он снова попал бы в divert, то есть получился бы бесконечный цикл).

    На этом месте пакет продолжит движение с правила номер 3 и дальше, как обычно, уйдет в точке (7) в сеть. Таким образом, несмотря на то, что пакет попадал в ip_output() два раза, с точки зрения пользователя это выглядит так, как если бы он был там один раз и никуда из файрвола не убегал - просто на правиле 2 в нем волшебным образом поменялись адреса и порты.

    Аналогичным образом, ответный пакет, возвращающийся из Интернета на интерфейс ext0, пройдет через машину по пути (1) - (2) - начало ipfw_chk() - правило 1 - правило 2 - (8) - divert - natd - divert - (9) - (2) - проверка в ipfw_chk() - правило 3 - правило 4 - (4) - (6) - начало ipfw_chk() - правило 1 - правило 2 - правило 3 - правило 4 - (7) - отправка через интерфейс int0.

    Подобное выведение пакета из обработки ipfw в другую подсистему - не уникально для divert, это общая схема работы в стеке FreeBSD. Например, действия pipe и queue в dummynet, передача пакета в netgraph (а также появившийся в 7.0 ipfw nat) действуют по тому же принципу. Отличие, однако, в том, что в этих подсистемах пакет остается внутри ядра, никакому демону не передается. Поэтому, во-первых, подсистемы вместо номера правила сохраняют на него полный указатель, и пакет вернется непосредственно в следующее правило, даже если оно имеет тот же номер. Во-вторых, для таких подсистем действует настройка one_pass в соответствующем sysctl - если она включена, то при повторном входе пакета в ipfw после возврата из подсистемы dummynet (netgraph), ipfw_chk() сразу вернется без прохода по правилам, как если бы к пакету был применен allow. Это поведение позволяет упростить правила файрвола, когда известно, что если пакет попал в трубу, то он уже точно отправляется дальше, и не требуется после каждого pipe вставлять allow (чтобы пакет не попал в следующие правила и следующие pipe/queue). Если же конфигурация требует сначала ограничить трафик, а потом уже разбираться по замысловатым требованиям, что из него разрешить, а что запретить, то упрощению правил наоборот будет способствовать отключенный one_pass - поскольку с ним вместо allow, расположенных до pipe, пришлось бы делать skipto.

    Итак, как уже было сказано, пакет проходит по списку правил последовательно, в порядке возрастания номеров правил. Список правил можно рассматривать как таблицу с тремя столбцами: номер, действие (и его параметры, например log), и условия, при которых пакет соответствует правилу (например, от адреса 1.1.1.1 адресу 2.2.2.2). Таблица просматривается сверху вниз, пакет сравнивается с условиями. На первом совпавшем условии смотрим в столбец действий, выполняем действие, прекращаем просмотр...



    Теперь, зная, что именно и в какой последовательности происходит с пакетами на их пути через сетевой стек FreeBSD мы можем приступать к изучению правил ipfw nat.

    Механизм ipfw nat можно рассматривать как своеобразный фильтр-преобразователь трафика. В зависимости от того как настроен нат, и от того какие IP адреса отправителя и получателя есть в проходящем через него пакете, нат будет преобразовывать в пакете IP адрес отправителя, либо IP адрес получателя, или же просто отвергать пакет. Важно помнить то, что нат разделяет трафик на исходящий (тот который надо маскировать) и входящий (тот который надо демаскировать) в зависимости от того на каком проходе (OUT или IN) он был получен. Так, трафик попавший в нат из прохода OUT требуется маскировать (заменить IP адрес отправителя на IP адрес нат машины), а трафик пришедший из прохода IN демаскировать. Развернуть это поведение можно используя директиву revers - тогда все поведение поменяется и можно будет запускать нат не на внешнем сетевом интерфейсе (который смотрит в интернет), а на внутреннем (том который смотрит в локальную сеть). Детальное описание того как работает механизм нат приводить, наверное, излишне. На поведение механизма nat влияет настройка параметра one_pass - в зависимости от ее значения трафик прошедший через нат может либо вернуться в проход фаервола из которого он был направлен в нат, либо выйти из фаервола. Такая гибкость дает возможность делать с трафиком много интересных вещей. ipfw nat позволяет запускать множество своих экземпляров каждый из которых имеет свою нат-таблицу и настройки. Объеденить несколько экземпляров для использования ими общей нат-таблицы - нельзя.


    Возможности ipfw nat и опции конфигурации.

    ipfw nat основан на коде библиотеки libalias. На ней же построенны как natd так ng_nat. Функционал libalias перенесенный в ipfw nat практически полностью повторяет все то, что есть в natd за исключением некоторых специфических вещей. К сожалению man страница для ipfw nat дает очень скупое описание его возможностей, поэтому при изучении опций конфигурации можно пользоваться man страницей для natd.

    Параметры конфигурации и их перевод.

         ip ip_address
    
    	Параметр предписывает IP адрес используемый при маскировании и
    	демаскировании. Этот параметр (или же параметр "if") должны быть
    	указаны. Установка параметра "proxy_only" отменяет действие
    	параметров "ip" и "if". В этом параметре обычно указывается адрес
    	назначенный "внешнему" сетевому интерфейсу. Может быть указан только один
    	IP адрес.
    
    	Во всех уходящих во вне пакетах, исходный IP адрес отправителя будет
    	замещен на адрес указанный в этом параметре. Все приходящие из вне пакеты
    	будут проверяться на совпадение с параметрами для какого-либо из ранее
    	установленных соединений, и в случае нахождения совпадения, пакет будет
    	демаскирован. Если совпадения не будет найдено, проверяются и применяются
    	все директивы redirect_port, redirect_proto и redirect_addr.
    	Если пакет не подпадает не под один из установленных
    	критериев демаскировки и не установлен параметр "deny_in", то тогда
    	пакет будет принят для локальной машины. Если параметр
    	"deny_in" установлен, то тогда пакет будет удален.
    

         if nic
    
    	Параметр предписывает IP адрес используемый при маскировании и
    	демаскировании, на основе имеющихся настроек для сетевого
    	интерфейса с именем "nic".
    	В случае динамического изменения IP адреса на сетевом интерфейсе,
    	адрес маскировки и демаскировки будет так же динамически изменен.
    

         log
    
    	Параметр предписывает включение накопления внутренней статистики по
    	количеству и типу активных соединений.
    

         deny_in
    
            Параметр предписывает запрет пропускать через nat входящие пакеты для
    	которых нет совпадения во внутренней таблице активных соединений,
    	или же нет совпадения с другими правил демаскировки.
    
    	Если данный параметр не установлен то для входящих соединений
    	будет создаваться новая запись в таблице активных соединений
    	и пакет будет пропускаться.
    

         same_ports
    
    	Параметр предлагает механизму nat поведение при котором тот будет
    	стараться сохранять оригинальные номера портов в уходящих
    	(маскируемых) пакетах.
    
    	При установке данного параметра такие протоколы как RPC будут иметь больше
    	шансов на успешную работу. Если по какой-либо причине сохранить оригинальные
    	номера портов невозможно, то пакет будет молча приобразован без учета этого
    	предписания.
    

         unreg_only
    
    	Параметр предписывает проводить маскировку только для тех исходящих пакетов,
    	чей адрес отправителя находится в классах "незарегистрированных" IP адресов.
    	В соответсвии с RFC 1918 к такими классам относятся адреса из диапазонов
    	10.0.0.0/8, 172.16.0.0/12 и 192.168.0.0/16.
    

         reset
    
    	Параметр предписывает очищать внутреннюю таблицу активных соединений при
    	изменениях параметра "ip" указывающего адрес используемый при маскировании
    	и демаскировании.
    

        reverse
    
    	Параметр предписывает поменять внутренне представление для случаев обработки
    	входящего и исходящего трафика через проходы IN и OUT.
    
    	В случае установки этого параметра, трафик поступивший в механизм nat из
    	прохода IN будет считаться исходящим, т.е. требующим проведения маскировки,
    	а трафик поступивший из прохода OUT будет считаться входящим, т.е.
    	требующем демаскировки.
    
    	Такое поведение может быть необходимо в некоторых случаях построения схем
    	прозрачного проксирования, когда исходящий трафик необходимо перенаправлять
    	на локальную машину, а сам механизм nat запущен на внетреннем сетевом
    	интерфейсе (обычно nat запускают на внешнем сетевом интефейсе).
    

         proxy_only
    
    	Параметр предписывает применять только правила прозрачного проксирования.
    	Правила маскировки и демаскировки при этом применяться не будут.
    

        redirect_addr localIP publicIP
    
    	Параметр предписывает проводить перенаправление трафика поступающего на
    	внешний IP адрес (publicIP), на машину с IP адресом во внутренней
    	сети (localIP). Этот механизм так же известен под названием
    	"статический NAT". Обычно статический NAT применяется в случаях, когда
    	провайдер выделил вам небольшой диапазон IP адресов, но он так же может
    	применяться при случаях с одним адресом:
    
    		redirect_addr 10.0.0.8 0.0.0.0
    
    	Данная команда будет пересылать весь входящий трафик на машину с
    	адресом 10.0.0.8
    
    	В случае, когда несколько внутренних адресов назначены для пересылки с
    	одного внешнего адреса:
    
    		redirect_addr 192.168.0.2 public_addr
    		redirect_addr 192.168.0.3 public_addr
    		redirect_addr 192.168.0.4 public_addr
    
    	весь входящий трафик будет пересылаться на последний из назначенных
    	адресов (192.168.0.4), но трафик исходящий с первых двух адресов по
    	прежнему будет маскироваться под адрес указанный в public_addr.
    

        redirect_addr localIP[,localIP[,...]] publicIP
    
    	Данная форма записи для параметра redirect_addr (а так же для
    	redirect_port) используется для прозрачного распределения сетевой нагрузки
    	между набором из нескольких серверов. Данная функция известна под
    	названием LSNAT (RFC 2391).
    
    	Например данная конфигурация для redirect_port:
    
    		www1:http,www2:http,www3:http www:http
    
    	означает, что входящие HTTP соединения для хоста www будут прозрачно
    	перенаправленны на хосты www1, www2 или www3, при этом выбор хоста для
    	перенаправления соединения будет произходить по алгоритму round-robin
    	(по очереди), но без учета текущей нагрузки на хосты или сеть.
    
    	Пример:
    
    	redirect_addr 192.168.0.10,192.168.0.11,192.168.0.12 10.0.0.100
    

        redirect_port proto targetIP:targetPORT[-targetPORT]
    	[aliasIP:]aliasPORT[-aliasPORT]
    	[remoteIP[:remotePORT[-remotePORT]]]
    
    	Параметр предписывает проводить перенаправление входящих соединений
    	поступающих на указанный номер порта(ов), на другой хост и порт(ы).
    	Аргумент "proto" может устанавливаться либо как tcp, либо как udp.
    	Аргумент "targetIP" указывает IP адрес на который должна происходить
    	пересылка трафика, а аргумент "targetPORT" порт (или диапазон портов)
    	на который будет перенаправлен трафик.
    	Аргумент "aliasIP" указывает IP адрес на который будут поступать
    	входящие соединения, а аргумент "aliasPORT" указывает номер порта
    	(или диапазон портов) на которые будут поступать входящие соединения.
    	Аргумены "remoteIP" и "remotePORT" при необходимости могут быть
    	использованы для более точного указания того какие именно входящие
    	соединения необходимо обрабатывать указанным правилом, устанавливая
    	соотвествие с удаленным источником/назначением трафика.
    	Если аргумент "remotePORT" не указан, то подразумевается, что
    	имеются в виду номера всех портов.
    	
    	Аргументы targetIP, aliasIP и remoteIP могут указываться как в
    	виде IP адресов, так и в виде имен хостов. Аргументы targetPORT,
    	aliasPORT и remotePORT указывающие диапазоны портов, не обязательно
    	должны полностью совпадать по начальным и конечным значениям
    	диапазонов, но обязаны иметь одинаковый размер диапазонов.
    	Когда арументы targetPORT, aliasPORT или remotePORT указывают
    	на единственный порт (не диапазон), то их значения могут указываться
    	как имена соответвующих сервисов перечисленных в services(5).
    
    	Примеры:
    
    		redirect_port tcp inside1:telnet 6666
    
    	это означает, что входящие TCP пакеты направляемые на порт
    	6666 данной машины будут перенаправленны на порт 23 (telnet)
    	машины с именем inside1
    
    		redirect_port tcp inside2:2300-2399 3300-3399
    
    	это означает перенаправление входящих соединений поступающих на
    	диапазон портов 3300-3399 на машину с именем inside2, в диапазон
    	портов 2300-2399. В данном случае произойдет сопоставление
    	портов 1:1 - это значит, что порт 3300 будет перенаправляться
    	в 2300,	порт 3301 в 2301 и так далее.
    
    	Примеры:
    
    	redirect_port tcp 192.168.0.1:80 500
    
    	redirect_port tcp 192.168.0.1:80,192.168.0.10:22 500
    
    	redirect_port tcp 192.168.1.2:20-25 70-75
    
    	redirect_port tcp 192.168.0.1:80 1.2.3.4:500 5.6.7.8:1024
    

        redirect_proto proto localIP [publicIP [remoteIP]]
    
    	Параметр предписывает проводить перенаправление входящих соединений
    	протокола "proto" поступающих на внешний IP адрес "publicIP", на
    	машину с IP адресом "localIP" во внутренней сети. Аргумены "remoteIP"
    	при необходимости может быть использован для более точного указания того
    	какие именно входящие соединения необходимо обрабатывать указанным
    	правилом, устанавливая соотвествие с удаленным
    	источником/назначением трафика.
    
    	Если аргумент publicIP не указан, то по-умолчанию будет использоваться
    	адрес настроенный для маскировки/демаскировки.
    
    	Пример:
    
    		redirect_proto udp 192.168.1.43 1.2.3.4
    



    Примеры и сценарии применения механизма ipfw nat

    Теперь, когда мы познакомились как с описанием принципов прохождения трафика через стек, так и с описание доступных опций конфигурирования механизма ipfw nat, можно приступать к составлению правил и рассмотрению их работы. Дальнейшее описание будет строиться по принципу "задача - решение", а так же по принципу постепенного усложнения конфигурации с детальными описаниями того как работает предлагаемое решение. Есть мнение, что на примерах проще понять изучаемый материал, а кроме того эти примеры можно будет использовать в работе.

    Включение ipfw nat и Dummynet

    Либо пересборка ядра с дополнительными параметрами:
    options         IPFIREWALL
    options         IPFIREWALL_VERBOSE
    options         IPFIREWALL_VERBOSE_LIMIT=50
    options         IPFIREWALL_NAT
    options         LIBALIAS
    options         ROUTETABLES=2
    options         DUMMYNET
    options         HZ="1000"
    

    Либо включение без пересборки (но так меньше возможностей для конфигурации)

    /etc/rc.conf
    firewall_nat_enable="YES"
    dummynet_enable="YES"
    




    Пример 1

    Простейший случай: рутер с двумя сетевыми адаптерами подключенными в локальную сеть и в интернет. Адрес в локальной сети 192.168.1.1 (сетевой адаптер fxp0), адрес в интернете 1.2.3.4 (сетевой адаптер em0).

    Задача: "раздавать интернет" для локальной сети, обеспечить проброс портов для внутренних адресов, разрешить прохождение трафика на отдельные порты самого рутера.



    Конфигурация:

    /etc/rc.conf
    
    gateway_enable="YES"
    ifconfig_em0="inet 1.2.3.4 netmask 255.255.255.0 -rxcsum"
    ifconfig_fxp0="inet 192.168.1.1 netmask 255.255.255.0"
    defaultrouter="1.2.3.254"
    firewall_enable="YES"
    firewall_type="/etc/firewall"
    



    /etc/sysctl.conf
    
    net.inet.ip.fw.one_pass=1
    



    /etc/firewall
    # правила разрешающие трафик через локальный интерфейс lo0
    # будут добавляться автоматически сами при старте фаервола
    # 100 allow ip from any to any via lo0
    # 200 deny ip from any to 127.0.0.0/8
    # 300 deny ip from 127.0.0.0/8 to any
    
    # разрешаем все через интерфейс локальной сети
    add 1040 allow ip from any to any via fxp0
    
    # боимся непонятного
    add 1050 deny ip from any to 192.168.0.0/16 in recv em0
    add 1060 deny ip from 192.168.0.0/16 to any in recv em0
    add 1070 deny ip from any to 172.16.0.0/12 in recv em0
    add 1080 deny ip from 172.16.0.0/12 to any in recv em0
    add 1090 deny ip from any to 10.0.0.0/8 in recv em0
    add 10100 deny ip from 10.0.0.0/8 to any in recv em0
    add 10110 deny ip from any to 169.254.0.0/16 in recv em0
    add 10120 deny ip from 169.254.0.0/16 to any in recv em0
    
    # настройка ната.
    # опции переноса строк "\" надо убрать все должно быть в одну строчку
    # опции redirect_port приведены для примера - как делать "проброс портов"
    nat 1 config log if em0 reset same_ports deny_in \
    redirect_port tcp 1.2.3.4:6881 6881 \
    redirect_port udp 1.2.3.4:4444 4444 \
    redirect_port tcp 192.168.1.24:25 25
    
    # заварачиваем все что проходит через внешний интерфейс в нат
    add 10130 nat 1 ip from any to any via em0
    
    # боимся непонятного
    add 65534 deny all from any to any
    




    Детальное описание прохождения трафика через фаервол в данной конфигурации:

    Для рутера:

    Трафик инициализированный непосредственно от рутера из точки (5) рис.2 пройдет в точку (6). Попав ip_output() ему будет присвоен шлюз по-умолчанию и тег с сетевым интерфейсом em0 через который он должен выйти в интернет (via em0, а точнее xmit em0). Трафик войдет в фаервол и начнет проходить через цепочку правил. Трафик дойдет до правила 10130 и будет передан в точку (8) то есть на обработку в нат как выходящий трафик так как поступит он из прохода OUT. В подсистеме нат для трафика в таблице соединений будет создана запись соответствия пар IP_локальный:порт <-> IP_удаленный:порт. После этого в точке (9) трафик выйдет из подсистемы нат и будет передан обратно в точку (6), заново попав в ip_output(). Так как значение one_pass выставлено в 1 (то есть разрешено) то трафик выйдет из ipfw (как если бы для него было применено правило allow) и уйдет в интернет через em0.

    Трафик возвращающийся в виде ответа зайдет в точку (1) и попадет в проход IN имея при этом тег с сетевым интерфейсом em0 (via em0, а точнее recv em0) через который он был получен. Далее трафик зайдет в точку (2) и попадет в функцию ip_input() после чего войдет в фаервол и начнет проходить через цепочку правил. Трафик дойдет до правила 10130 и будет передан в точку (8) то есть на обработку в нат как входящий трафик так как поступит он из прохода IN. В подсистеме нат для трафика в таблице соединений будет найдена ранее созданая запись соответствия пар IP_локальный:порт <-> IP_удаленный:порт, после чего он будет демаскирован (в данном случае изменения фактически не будет так как адрес маскировки/демаскировки один и тот же - локальный 1.2.3.4). После этого в точке (9) трафик выйдет из подсистемы нат и будет передан обратно в точку (2) заново попав ip_input(). Так как значение one_pass выставлено в 1 (то есть разрешено) то трафик выйдет из ipfw (как если бы для него было применено правило allow) и поступит в локальный сокет на котором работает программа ранее  инициализировавшая соединение.

    Если из интернета приходит трафик не имеющий в таблице соединений записи соответсвия, то такой трафик при поступлении в нат будет отвергнут, так как в настройках выставлен параметр deny_in.

    Если из интернета приходит трафик адресованный для tcp 1.2.3.4:6881 то он дойдя до точки (8) и попав в нат, будет успешно демаскирован так как в таблице для него уже будет иметься статическая запись соответствия 1.2.3.4:6881 <-> IP_любой:любой_порт. После чего он так же как и в случае с любым трафиком возвращающимся из интернета, будет принят и поступит в локальный сокет на порту 6881.
    Ответный, уходящий с этого сокета трафик, пройдет через то же статическое правило и будет успешно обработан как это было в случае с любым трафиком уходящим в интернет.

    Для сети 192.168.1.0/24:

    Трафик инициализированный от хоста 192.168.1.56 из сети 192.168.1.0/24 войдет в рутер через ссетевой интерфейс fxp0 и пройдя через точку (1) получит тег с сетевым интерфейсом fxp0 (via fxp0, а точнее recv fxp0) через который он был получен. Далее трафик зайдет в точку (2) и попадет в функцию ip_input() после чего войдет в фаервол и начнет проходить через цепочку правил. Трафик дойдет до правила 1040 после чего выйдет из прохода IN фаервола, и попадет обратно в ip_input() где будет принято решение о том, что он предназначен не нам, а следовательно должен быть направлен в точку (4), в функцию ip_forward(). Попав в ip_forward() у IP трафика будет уменьшено значение TTL, а кроме того, после проверки разрешено ли проводить маршрутизацию (установка соответвующего значения sysctl выполненная из rc.conf через gateway_enable="YES") он будет передан в точку (6) в функцию ip_output(). Попав ip_output() ему будет присвоен шлюз по-умолчанию и тег с сетевым интерфейсом em0 через который он должен выйти в интернет (via em0, а точнее xmit em0). Трафик войдет в фаервол и начнет проходить через цепочку правил. Трафик дойдет до правила 10130 и будет передан в точку (8) то есть на обработку в нат как выходящий трафик так как поступит он из прохода OUT. В подсистеме нат для трафика в таблице соединений будет создана запись соответствия пар 192.168.1.56:порт <-> 1.2.3.4:порт <-> IP_удаленный:порт, а оригинальный адрес отправителя (192.168.1.56) в заголовке IP пакета будет заменен на IP адрес указанный для параметре "if" в настройках нат. После этого в точке (9) трафик выйдет из подсистемы нат и будет передан обратно в точку (6), заново попав в ip_output(). Так как значение one_pass выставлено в 1 (то есть разрешено) то трафик выйдет из ipfw (как если бы для него было применено правило allow) и уйдет в интернет через em0 имея IP адрес отправителя 1.2.3.4.

    Трафик возвращающийся в виде ответа зайдет в точку (1) и попадет в проход IN имея при этом тег с сетевым интерфейсом em0 (via em0, а точнее recv em0) через который он был получен. Далее трафик зайдет в точку (2) и попадет в функцию ip_input() после чего войдет в фаервол и начнет проходить через цепочку правил. Трафик дойдет до правила 10130 и будет передан в точку (8) то есть на обработку в нат как входящий трафик так как поступит он из прохода IN. В подсистеме нат для трафика в таблице соединений будет найдена ранее созданая запись соответствия пар 192.168.1.56:порт <-> 1.2.3.4:порт <-> IP_удаленный:порт, после чего он будет демаскирован - адрес получателя в заголовке IP пакета будет заменен с 1.2.3.4 на 192.168.1.56. После этого в точке (9) трафик выйдет из подсистемы нат и будет передан обратно в точку (2) заново попав ip_input() Так как значение one_pass выставлено в 1 (то есть разрешено) то трафик выйдет из прохода IN фаервола (как если бы для него было применено правило allow) и попадет обратно в ip_input() где будет принято решение о том, что он предназначен не нам, а следовательно должен быть направлен в точку (4), в функцию ip_forward(). Попав в ip_forward() у IP трафика бцдет уменьшено значение TTL, а кроме того, после проверки разрешено ли проводить маршрутизацию (установка соответвующего значения sysctl выполненная из rc.conf через gateway_enable="YES") он будет передан в точку (6) в функцию ip_output(). Попав ip_output() ему будет присвоен шлюз по-умолчанию и тег с сетевым интерфейсом fxp0 через который он должен выйти в локальную сеть (via fxp0, а точнее xmit fxp0). Трафик войдет в фаервол и начнет проходить через цепочку правил. Трафик дойдет до правила 1040. После этого трафик выйдет из ipfw и уйдет в локальную сеть через fxp0 имея IP адрес получателя 192.168.1.56.

    Если из интернета приходит трафик не имеющий в таблице соединений записи соответсвия, то такой трафик при поступлении в нат будет отвергнут, так как в настройках нат выставлен параметр deny_in.

    Если из интернета приходит трафик адресованный для tcp 1.2.3.4:25 то он дойдя до точки (8) и попав в нат, будет успешно демаскирован так как в таблице для него уже будет иметься статическая запись соответсвия 192.168.1.24:25 <-> 1.2.3.4:25 <-> IP_любой:любой_порт. После чего он так же как и в случае с любым трафиком возвращающимся из интернета, будет принят и пройдя по тому же маршруту через IN и OUT уйдет в локальную сеть на машину с IP 192.168.1.24.
    Ответный, уходящий с этого IP 192.168.1.24 трафик, пройдет через то же статическое правило и будет успешно обработан как это было в случае с любым трафиком уходящим в интернет.


    Далее, при рассмотрении других конфигураций, я больше не буду так детально описывать все случаи. Для понимания сути механизма данное описание уже достаточно и его можно применять к остальным конфигурациям. Детальные описания будут лишь там, где это необходимо.


    Пример 2

    Более сложный случай: рутер с двумя сетевыми адаптерами подключенными в локальную сеть и в интернет. Адрес в локальной сети 192.168.1.1 (сетевой адаптер fxp0), адреса в интернете 1.2.3.4 и 1.2.3.5 (сетевой адаптер em0).

    Задача: "раздавать интернет" для локальной сети, обеспечить проброс портов для внутренних адресов, разрешить прохождение трафика на отдельные порты самого рутера, а главное - используя шейпер Dummynet обеспечить честное распределение пропускной способности между клиентами локальной сети. Так же обеспечить проброс всего трафика для 1.2.3.5 на 192.168.1.36 используя redirect_addr.



    /etc/rc.conf
    
    gateway_enable="YES"
    ifconfig_em0="inet 1.2.3.4 netmask 255.255.255.0 -rxcsum"
    ifconfig_em0_alias0="inet 1.2.3.5 netmask 255.255.255.255"
    ifconfig_fxp0="inet 192.168.1.1 netmask 255.255.255.0"
    defaultrouter="1.2.3.254"
    firewall_enable="YES"
    firewall_type="/etc/firewall"
    



    /etc/sysctl.conf
    
    net.inet.ip.fw.one_pass=0
    



    /etc/firewall
    
    add 1040 allow ip from any to any via fxp0
    
    add 1050 deny ip from any to 192.168.0.0/16 in recv em0
    add 1060 deny ip from 192.168.0.0/16 to any in recv em0
    add 1070 deny ip from any to 172.16.0.0/12 in recv em0
    add 1080 deny ip from 172.16.0.0/12 to any in recv em0
    add 1090 deny ip from any to 10.0.0.0/8 in recv em0
    add 10100 deny ip from 10.0.0.0/8 to any in recv em0
    add 10110 deny ip from any to 169.254.0.0/16 in recv em0
    add 10120 deny ip from 169.254.0.0/16 to any in recv em0
    
    pipe 1 config bw 10Mbit/s queue 60 gred 0.002/10/30/0.1 
    queue 1 config pipe 1 queue 60 mask src-ip 0xffffffff gred 0.002/10/30/0.1
    
    pipe 2 config bw 10Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 2 config pipe 2 queue 60 mask dst-ip 0xffffffff gred 0.002/10/30/0.1
    
    nat 1 config log if em0 reset same_ports deny_in \
    redirect_port tcp 1.2.3.4:6881 6881 \
    redirect_port udp 1.2.3.4:4444 4444 \
    redirect_port tcp 192.168.1.24:25 25
    
    nat 2 config log same_ports redirect_addr 192.168.1.36 1.2.3.5
    
    add 10130 skipto 10190 ip from 192.168.1.36 to any out xmit em0
    add 10140 skipto 10210 ip from any to 1.2.3.5 in recv em0
    
    add 10150 queue 1 ip from any to any out xmit em0
    add 10160 nat 1 ip from any to any via em0
    add 10170 queue 2 ip from any to any in recv em0
    
    add 10180 allow all from any to any
    
    add 10190 queue 1 ip from any to any out xmit em0
    add 10200 nat 2 ip from 192.168.1.36 to any out xmit em0
    add 10210 nat 2 ip from any to 1.2.3.5 in recv em0
    add 10220 queue 2 ip from any to any in recv em0
    
    add 10230 allow all from any to any
    
    add 65534 deny all from any to any
    






    Детальное описание прохождения трафика через фаервол в данной конфигурации:

    Настройки параметров queue mask 0xffffffff указывают на то, что динамические очереди будут создаваться на основании разницы любого бита из IP адресов отправителя или получателя. Скорость исходящего и входящего трафика будет ограничеваться под 10 Mbit/s.

    Для рутера:

    Трафик инициализированный непосредственно от рутера пройдет через цепочку правил ipfw прохода OUT до правила с номером 10150. Трафик попадет в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость выходящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол (так как выключен параметр one_pass) и попадет в правило 10160. После прохождения ната трафик сново вернется в фаервол и дойдя до правила 10180 будет выведен из фаервола и уйдет во внешнюю сеть.

    Ответный трафик пройдет через проход IN фаервола до правила 10160 где попадет в нат и будет демаскирован (в данном случае не сущесвенно) и принят так как в нате уже есть активное соединение. Выйдя из ната трафик попадет в правило 10170 и будет передан в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость входящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол и попадет в правило 10180 где будет разрешен и выйдет из фаервола направившись в сокет программы инициализировавшей соединение.

    Если на рутер из интернета придет случайный трафик, то он пройдя через правило 10160 будет отвергнут так как нат запущен с опцией deny_in.

    Трафик идущий на порты 6881, 4444 и 25 будет заведен в нат на правиле 10160, потом в Dummynet на правиле 10170, а потом пропущен либо на сам рутер, либо на хост 192.168.1.24 соответственно.

    Для IP адресов 192.168.1.36 и 1.2.3.5

    Трафик приходящий из интернета на внешний IP адрес 1.2.3.5 должен быть проброшен на 192.168.1.36. Когда такой трафик пойдет через проход IN фаервола, он будет обработан на правиле 10140 которое перенесет обработку на 10210 - трафик будет передан во второй экземпляр ната где произойдет демаскировка (1.2.3.5 в IP  адресе получателя будет заменено на 192.168.1.36). После этого трафик вернется в фаервол и через правило 10220 попадет в Dummynet. Выйдя от туда он вернется в фаервол и дойдет до правила 10230 после чего будет выведен из прохода IN фаервола и уйдет в проход OUT где дойдя до правила 1040 будет принят, выйдет из фаервола, и будет отправлен на 192.168.1.36.

    Ответный трафик (а так же любой другой исходящий трафик) от 192.168.1.36 пройдет на проходе IN через 1040, потом на проходе OUT через 10130, 10190, 10200 и 10230 после чего уйдет во внешнюю сеть.

    Для сети 192.168.1.0/24:

    Трафик исходящий из сети 192.168.1.0/24 (например от хоста с IP 192.168.1.24), зайдет через сетевой адаптер fxp0 в проход IN фаервола и дойдет до правила 1040 после чего выйдет из IN и будет разрешен. Трафик зайдет в проход OUT где пройдет по правилам до 10150. Трафик попадет в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость выходящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол (так как выключен параметр one_pass) и попадет в правило 10160. После прохождения ната трафик сново вернется в фаервол и дойдя до правила 10180 будет выведен из фаервола и уйдет во внешнюю сеть.

    Ответный трафик пройдет через проход IN фаервола до правила 10160 где попадет в нат, будет демаскирован и принят так как в нате уже есть активное соединение. Выйдя из ната трафик попадет в правило 10170 и будет передан в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость входящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол и попадет в правило 10180 где будет разрешен и выйдет из прохода IN фаервола. Трафик попадет в проход OUT фаервола где дойдет до правила 1040, после чего выйдет из IN и будет передан в сеть 192.168.1.0/24 через адаптер fxp0.

    Если на рутер из интернета придет случайный трафик, то он пройдя через правило 10160 будет отвергнут так как нат запущен с опцией deny_in.


    Пример 3

    В локальной сети из примера 2 появилась машина 192.168.1.80 на которой работает web сервер. Кроме того появился еще один компьютер с FreeBSD у которого есть два сетевых интерфейса (em1 со стороны интернета, и fxp1 со стороны локальной сети). Адаптер fxp1 подключен в ту же сеть и имеет IP 192.168.1.254, а адаптер em1 подключен ко второму провайдеру и имеет IP 5.6.7.8.

    Задача: не меняя настройки фаервола у имеющегося рутера 192.168.1.1 и TCP/IP настройки машины 192.168.1.80, обеспечить доступ к веб серверу работающему на 192.168.1.80 через подключение 5.6.7.8 используя два экземпляра ната.




    /etc/rc.conf
    
    gateway_enable="YES"
    ifconfig_em1="inet 5.6.7.8 netmask 255.255.255.0 -rxcsum"
    ifconfig_fxp1="inet 192.168.1.254 netmask 255.255.255.0"
    defaultrouter="5.6.7.254"
    firewall_enable="YES"
    firewall_type="/etc/firewall"
    



    /etc/sysctl.conf
    
    net.inet.ip.fw.one_pass=1
    



    /etc/firewall
    nat 2 config log if fxp1 same_ports reset deny_in
    
    add 1040 nat 2 ip from any to any via fxp1
    
    add 1050 deny ip from any to 192.168.0.0/16 in recv em1
    add 1060 deny ip from 192.168.0.0/16 to any in recv em1
    add 1070 deny ip from any to 172.16.0.0/12 in recv em1
    add 1080 deny ip from 172.16.0.0/12 to any in recv em1
    add 1090 deny ip from any to 10.0.0.0/8 in recv em1
    add 10100 deny ip from 10.0.0.0/8 to any in recv em1
    add 10110 deny ip from any to 169.254.0.0/16 in recv em1
    add 10120 deny ip from 169.254.0.0/16 to any in recv em1
    
    nat 1 config log if em1 reset same_ports deny_in \
    redirect_port tcp 192.168.1.80:80 80
    
    add 10130 nat 1 ip from any to any via em1
    
    add 65534 deny all from any to any
    




    Детальное описание прохождения трафика через фаервол в данной конфигурации:

    Для рутера:

    Трафик инициализированный непосредственно от рутера пройдет через цепочку правил ipfw прохода OUT до правила с номером 10130 где попадет в нат. После прохождения ната трафик выйдет из фаервола и будет передан в интернет.

    Ответный трафик пройдет через цепочку правил прохода IN фаервола до правила 10130 где попав в нат будет демаскирован (в данном случае не существенно) и выйдет из фаервола попав в сокет программы инициировавшей соединение.

    Если на рутер из интернета придет случайный трафик, то он пройдя через правило 10130 будет отвергнут так как нат запущен с опцией deny_in.

    Для 192.168.1.80 и 5.6.7.8:

    Трафик приходящий из интернета на 5.6.7.8:80 пройдет через цепочку правил ipfw прохода IN до правила с номером 10130 где попадет в первый экземпляр ната и будет демаскирован на основании статического правила (внешний_IP <-> 5.6.7.8 будет заменено на внешний_IP <-> 192.168.1.80). После этого трафик попадет в проход OUT фаервола и дойдет до правила 1040 где попадет во второй экземпляр ната. Трафик будет маскирован (внешний_IP <-> 192.168.1.80 будет заменено на 192.168.1.254 <-> 192.168.1.80). После этого трафик выйдет из ната и будет передан на 192.168.1.80:80

    Цепочка преобразования адресов при проходе была следующей:

    отправитель:		получатель:
    внешний_IP		5.6.7.8
    внешний_IP		192.168.1.80
    192.168.1.254		192.168.1.80
    



    Ответный трафик уходящий от 192.168.1.80:80 будет передан на 192.168.1.254 где попав в фаервол пройдет до правила 1040. Попав во второй экземпояр ната трафик будет демаскирован (192.168.1.80 <-> 192.168.1.254 будет заменено на 192.168.1.80 <-> внешний_IP) и выйдя из прохода IN перейдет в проход OUT где пройдя через правила дойдет до 10130. Попав в первый экземпляр ната трафик будет повторно маскирован (192.168.1.80 <-> внешний_IP будет заменено на 5.6.7.8 <-> внешний_IP) после чего трафик уйдет в интернет.

    Цепочка преобразования адресов при проходе была следующей:

    отправитель:		получатель:
    192.168.1.80		192.168.1.254
    192.168.1.80		внешний_IP
    5.6.7.8			внешний_IP
    



    Если на рутер из интернета придет случайный трафик, то он пройдя через правило 10130 будет отвергнут так как нат запущен с опцией deny_in.

    Пример 4

    Есть два подключения к двум независимым провайдерам и две локальных сети. На рутере имеется четыре сетевых адаптера каждый из которых подключен к своему провайдеру или к своей локальной сети. Адаптеры em0 и em1 подключены к провайдерам ISP1 (IP 11.22.33.44) и ISP2 (IP 55.66.77.88). Адаптеры fxp0 и fxp1 подключены к локальным сетям LAN1 (IP 192.168.1.1) и LAN2 (IP 10.1.1.1). Ядро рутера собранно с поддержкой двух таблиц маршрутизации (options ROUTETABLES=2).

    Задача: обеспечить выход в интернет первой сети через первого провайдера, а второй сети через второго. Все это через нат и используя шейпер Dummynet обеспечить честное распределение пропускной способности между клиентами в локальных сетях.




    /etc/rc.conf
    
    gateway_enable="YES"
    ifconfig_em0="inet 11.22.33.44 netmask 255.255.255.0 -rxcsum"
    ifconfig_em1="inet 55.66.77.88 netmask 255.255.255.0 -rxcsum"
    ifconfig_fxp0="inet 192.168.1.1 netmask 255.255.255.0"
    ifconfig_fxp1="inet 10.1.1.1 netmask 255.255.255.0"
    
    defaultrouter="11.22.33.254"
    
    setfib1_enable="YES"
    setfib1_defaultroute="55.66.77.254"
    
    firewall_enable="YES"
    firewall_type="/etc/firewall"
    



    /etc/sysctl.conf
    
    net.inet.ip.fw.one_pass=0
    




    /etc/firewall
    add 1040 setfib 0 ip from any to any in recv fxp0
    add 1050 setfib 1 ip from any to any in recv fxp1
    
    add 1060 allow ip from any to any via fxp0
    add 1070 allow ip from any to any via fxp1
    
    add 1080 deny ip from any to 192.168.0.0/16 in recv em0
    add 1081 deny ip from any to 192.168.0.0/16 in recv em1
    add 1090 deny ip from 192.168.0.0/16 to any in recv em0
    add 1091 deny ip from 192.168.0.0/16 to any in recv em1
    add 10100 deny ip from any to 172.16.0.0/12 in recv em0
    add 10101 deny ip from any to 172.16.0.0/12 in recv em1
    add 10110 deny ip from 172.16.0.0/12 to any in recv em0
    add 10111 deny ip from 172.16.0.0/12 to any in recv em1
    add 10120 deny ip from any to 10.0.0.0/8 in recv em0
    add 10121 deny ip from any to 10.0.0.0/8 in recv em1
    add 10130 deny ip from 10.0.0.0/8 to any in recv em0
    add 10131 deny ip from 10.0.0.0/8 to any in recv em1
    add 10140 deny ip from any to 169.254.0.0/16 in recv em0
    add 10141 deny ip from any to 169.254.0.0/16 in recv em1
    add 10150 deny ip from 169.254.0.0/16 to any in recv em0
    add 10151 deny ip from 169.254.0.0/16 to any in recv em1
    
    pipe 1 config bw 10Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 1 config pipe 1 queue 60 mask src-ip 0xffffffff gred 0.002/10/30/0.1
    
    pipe 2 config bw 10Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 2 config pipe 2 queue 60 mask dst-ip 0xffffffff gred 0.002/10/30/0.1
    
    pipe 3 config bw 20Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 3 config pipe 3 queue 60 mask src-ip 0xffffffff gred 0.002/10/30/0.1
    
    pipe 4 config bw 35Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 4 config pipe 4 queue 60 mask dst-ip 0xffffffff gred 0.002/10/30/0.1
    
    nat 1 config log if em0 same_ports reset deny_in
    nat 2 config log if em1 same_ports reset deny_in
    
    add 10160 queue 1 ip from any to any out xmit em0
    add 10170 nat 1 ip from any to any via em0
    add 10180 queue 2 ip from any to any in recv em0
    
    add 10190 queue 3 ip from any to any out xmit em1
    add 10200 nat 2 ip from any to any via em1
    add 10210 queue 4 ip from any to any in recv em1
    
    add 10220 allow all from any to any
    
    add 65534 deny all from any to any
    




    /usr/local/etc/rc.d/setfib1
    
    #!/bin/sh
    # PROVIDE: SETFIB1
    # REQUIRE: NETWORKING
    # BEFORE: DAEMON
    #
    # Add the following lines to /etc/rc.conf to enable setfib -1 at startup
    # setfib1 (bool): Set to "NO" by default.
    #                Set it to "YES" to enable setfib1
    # setfib1_defaultroute (str): Set to "" by default
    #       Set it to ip address of default gateway for use in fib 1
    
    . /etc/rc.subr
    
    name="setfib1"
    rcvar=`set_rcvar`
    
    load_rc_config $name
    
    [ -z "$setfib1_enable" ] && setfib1_enable="NO"
    [ -z "$setfib1_defaultroute" ] && setfib1_defaultroute=""
    
    start_cmd="${name}_start"
    stop_cmd="${name}_stop"
    
    setfib1_start()
    {
    if [ ${setfib1_defaultroute} ]
    then
    setfib 1 route delete default
    setfib 1 route add default ${setfib1_defaultroute}
    else
    echo "Can not set default route for fib 1!"
    fi
    }
    
    setfib1_stop()
    {
    setfib 1 route delete default
    }
    run_rc_command "$1"
    
    

    Напомининие.
    Скрипт setfib1 необходимо сделать исполняемым. Для этого после его создания надо выполнить:
    
    chmod 755 /usr/local/etc/rc.d/setfib1
    




    Детальное описание прохождения трафика через фаервол в данной конфигурации:

    Для рутера:

    Трафик инициализированный непосредственно от рутера пройдет через цепочку правил ipfw прохода OUT до правила с номером 10160. Трафик попадет в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость выходящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол (так как выключен параметр one_pass) и попадет в правило 10170. После прохождения ната трафик сново вернется в фаервол и дойдя до правила 10220 будет выведен их фаервола и уйдет во внешнюю сеть через 11.22.33.254..

    Ответный трафик пройдет через проход IN фаервола до правила 10170 где попадет в нат и будет демаскирован (в данном случае не сущесвенно) и принят так как в нате уже есть активное соединение. Выйдя из ната трафик попадет в правило 10180 и будет передан в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость входящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол и попадет в правило 10220 где будет разрешен и выйдет из фаервола направившись в сокет программы инициализировавшей соединение.

    Если на рутер из интернета придет случайный трафик, то он пройдя через правило 10170 будет отвергнут так как нат запущен с опцией deny_in.

    Для 192.168.1.0/24:

    Трафик исходящий из сети 192.168.1.0/24 (например от хоста с IP 192.168.1.24), зайдет через сетевой адаптер fxp0 в проход IN фаервола и дойдет до правила 1040 где ему будет назначенна таблица маршрутизации 0 (таблица по-умолчанию). Далее трафик пройдет до правила 1060 после чего выйдет из IN и будет разрешен. Трафик зайдет в проход OUT где пройдет по правилам до 10160. Трафик попадет в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость выходящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол (так как выключен параметр one_pass) и попадет в правило 10170. После прохождения ната трафик сново вернется в фаервол и дойдя до правила 10220 будет выведен их фаервола и уйдет во внешнюю сеть через 11.22.33.254.

    Ответный трафик пройдет через проход IN фаервола до правила 10170 где попадет в нат, будет демаскирован и принят так как в нате уже есть активное соединение. Выйдя из ната трафик попадет в правило 10180 и будет передан в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость входящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол и попадет в правило 10220 где будет разрешен, и выйдет из прохода IN фаервола. Трафик попадет в проход OUT фаервола где дойдет до правила 1060, после чего выйдет из IN и будет передан в сеть 192.168.1.0/24 через адаптер fxp0.

    Если на рутер из интернета придет случайный трафик, то он пройдя через правило 10170 будет отвергнут так как нат запущен с опцией deny_in.

    Для 10.1.1.0/24:

    Трафик исходящий из сети 10.1.1.0/24 (например от хоста с IP 10.1.1.24), зайдет через сетевой адаптер fxp1 в проход IN фаервола и дойдет до правила 1050 где ему будет назначенна таблица маршрутизации 1 (вторая таблица имеющая default gateway 55.66.77.254). Теперь для трафика в качестве сетевого адаптера через который он должен быть передан наружу, будет установлено em1. Далее трафик пройдет до правила 1070 после чего выйдет из IN и будет разрешен. Трафик зайдет в проход OUT где пройдет по правилам до 10190. Трафик попадет в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость выходящего трафика будет ограничена в 20Mbit/s. После выхода из Dummynet трафик вернется в фаервол (так как выключен параметр one_pass) и попадет в правило 10200. После прохождения ната трафик сново вернется в фаервол и дойдя до правила 10220 будет выведен из фаервола и уйдет во внешнюю сеть через 55.66.77.254.

    Ответный трафик пройдет через проход IN фаервола до правила 10200 где попадет в нат, будет демаскирован и принят так как в нате уже есть активное соединение. Выйдя из ната трафик попадет в правило 10210 и будет передан в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость входящего трафика будет ограничена в 35Mbit/s. После выхода из Dummynet трафик вернется в фаервол и попадет в правило 10220 где будет разрешен, и выйдет из прохода IN фаервола. Трафик попадет в проход OUT фаервола где дойдет до правила 1070, после чего выйдет из IN и будет передан в сеть 10.1.1.0/24 через адаптер fxp1.

    Если на рутер из интернета придет случайный трафик, то он пройдя через правило 10200 будет отвергнут так как нат запущен с опцией deny_in.





    Пример 5

    Есть два подключения к двум независимым провайдерам и одна локальная сеть. На рутере имеется три сетевых адаптера два из которых подключены провайдерам, а третий к своей локальной сети. Адаптеры em0 и em1 подключены к провайдерам ISP1 (IP 11.22.33.44) и ISP2 (IP 55.66.77.88). Адаптер fxp0 подключен к локальной сети LAN1 (IP 192.168.1.1). Ядро рутера собранно с поддержкой двух таблиц маршрутизации (options ROUTETABLES=2).

    Задача: обеспечить выход в интернет локальной сети через обоих провайдеров используя балансировку трафика между подключениями. Все это через нат и используя шейпер Dummynet обеспечить честное распределение пропускной способности между клиентами в локальной сети.




    /etc/rc.conf
    
    gateway_enable="YES"
    ifconfig_em0="inet 11.22.33.44 netmask 255.255.255.0 -rxcsum"
    ifconfig_em1="inet 55.66.77.88 netmask 255.255.255.0 -rxcsum"
    ifconfig_fxp0="inet 192.168.1.1 netmask 255.255.255.0"
    
    defaultrouter="11.22.33.254"
    
    setfib1_enable="YES"
    setfib1_defaultroute="55.66.77.254"
    
    firewall_enable="YES"
    firewall_type="/etc/firewall"
    



    /etc/sysctl.conf
    
    net.inet.ip.fw.one_pass=0
    




    /etc/firewall
    add 1010 prob 0.5 skipto 1060 ip from any to any in recv fxp0
    
    add 1040 setfib 0 ip from any to any in recv fxp0 keep-state
    add 1050 allow ip from any to any via fxp0
    
    add 1060 setfib 1 ip from any to any in recv fxp0 keep-state
    add 1070 allow ip from any to any via fxp0
    
    add 1080 deny ip from any to 192.168.0.0/16 in recv em0
    add 1081 deny ip from any to 192.168.0.0/16 in recv em1
    add 1090 deny ip from 192.168.0.0/16 to any in recv em0
    add 1091 deny ip from 192.168.0.0/16 to any in recv em1
    add 10100 deny ip from any to 172.16.0.0/12 in recv em0
    add 10101 deny ip from any to 172.16.0.0/12 in recv em1
    add 10110 deny ip from 172.16.0.0/12 to any in recv em0
    add 10111 deny ip from 172.16.0.0/12 to any in recv em1
    add 10120 deny ip from any to 10.0.0.0/8 in recv em0
    add 10121 deny ip from any to 10.0.0.0/8 in recv em1
    add 10130 deny ip from 10.0.0.0/8 to any in recv em0
    add 10131 deny ip from 10.0.0.0/8 to any in recv em1
    add 10140 deny ip from any to 169.254.0.0/16 in recv em0
    add 10141 deny ip from any to 169.254.0.0/16 in recv em1
    add 10150 deny ip from 169.254.0.0/16 to any in recv em0
    add 10151 deny ip from 169.254.0.0/16 to any in recv em1
    
    pipe 1 config bw 10Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 1 config pipe 1 queue 60 mask src-ip 0xffffffff gred 0.002/10/30/0.1
    
    pipe 2 config bw 10Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 2 config pipe 2 queue 60 mask dst-ip 0xffffffff gred 0.002/10/30/0.1
    
    pipe 3 config bw 20Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 3 config pipe 3 queue 60 mask src-ip 0xffffffff gred 0.002/10/30/0.1
    
    pipe 4 config bw 35Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 4 config pipe 4 queue 60 mask dst-ip 0xffffffff gred 0.002/10/30/0.1
    
    nat 1 config log if em0 same_ports reset deny_in \
    redirect_port tcp 192.168.1.5:25 25
    nat 2 config log if em1 same_ports reset deny_in
    
    add 10160 queue 1 ip from any to any out xmit em0
    add 10170 nat 1 ip from any to any via em0
    add 10180 queue 2 ip from any to any in recv em0
    
    add 10190 queue 3 ip from any to any out xmit em1
    add 10200 nat 2 ip from any to any via em1
    add 10210 queue 4 ip from any to any in recv em1
    
    add 10220 allow all from any to any
    
    add 65534 deny all from any to any
    




    /usr/local/etc/rc.d/setfib1
    
    #!/bin/sh
    # PROVIDE: SETFIB1
    # REQUIRE: NETWORKING
    # BEFORE: DAEMON
    #
    # Add the following lines to /etc/rc.conf to enable setfib -1 at startup
    # setfib1 (bool): Set to "NO" by default.
    #                Set it to "YES" to enable setfib1
    # setfib1_defaultroute (str): Set to "" by default
    #       Set it to ip address of default gateway for use in fib 1
    
    . /etc/rc.subr
    
    name="setfib1"
    rcvar=`set_rcvar`
    
    load_rc_config $name
    
    [ -z "$setfib1_enable" ] && setfib1_enable="NO"
    [ -z "$setfib1_defaultroute" ] && setfib1_defaultroute=""
    
    start_cmd="${name}_start"
    stop_cmd="${name}_stop"
    
    setfib1_start()
    {
    if [ ${setfib1_defaultroute} ]
    then
    setfib 1 route delete default
    setfib 1 route add default ${setfib1_defaultroute}
    else
    echo "Can not set default route for fib 1!"
    fi
    }
    
    setfib1_stop()
    {
    setfib 1 route delete default
    }
    run_rc_command "$1"
    

    Напомининие.
    Скрипт setfib1 необходимо сделать исполняемым. Для этого после его создания надо выполнить:
    
    chmod 755 /usr/local/etc/rc.d/setfib1
    




    Детальное описание прохождения трафика через фаервол в данной конфигурации:

    Для рутера:

    Трафик инициализированный непосредственно от рутера пройдет через цепочку правил ipfw прохода OUT до правила с номером 10160. Трафик попадет в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость выходящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол (так как выключен параметр one_pass) и попадет в правило 10170. После прохождения ната трафик сново вернется в фаервол и дойдя до правила 10220 будет выведен их фаервола и уйдет во внешнюю сеть через 11.22.33.254..

    Ответный трафик пройдет через проход IN фаервола до правила 10170 где попадет в нат и будет демаскирован (в данном случае не сущесвенно) и принят так как в нате уже есть активное соединение. Выйдя из ната трафик попадет в правило 10180 и будет передан в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость входящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол и попадет в правило 10220 где будет разрешен и выйдет из фаервола направившись в сокет программы инициализировавшей соединение.

    Если на рутер из интернета придет случайный трафик, то он пройдя через правило 10170 будет отвергнут так как нат запущен с опцией deny_in.

    Для 192.168.1.0/24:

    Трафик исходящий из сети 192.168.1.0/24 (например от хоста с IP 192.168.1.24), зайдет через сетевой адаптер fxp0 в проход IN фаервола и дойдет до правила 1010 на котором с вероятностью 1/2 будет либо произведен переход на правило 1060, либо переход к следующему по списку правилу 1040. Правила 1040 и 1060 имеют директиву keep-state (это динамические правила). Допустим, что 192.168.1.24 инициировал две сессии - первую на адрес IP 3.3.3.3:80, а вторую на адрес IP 9.9.9.9:22.

    Допустим, что первая сессия на правиле 1010 не была обработана. В таком случае трафик адресованный на IP 3.3.3.3 пройдет до правила 1040 где ему будет назначена таблица маршрутизации по-умолчанию, а кроме того в таблицу динамических правил будет занесена информация о сессии 192.168.1.24:12345 <-> 3.3.3.3:80 и о действии родительского правила (setfib 0) которое надо применять к трафику в рамках сессии. Далее, дойдя до правила 1050 трафик будет принят, выйдет из прохода IN и будет разрешен.

    Допустим, что вторая сессия на правиле 1010 была обработана. В таком случае трафик адресованный на IP 9.9.9.9 пройдет до правила 1060 где ему будет назначена вторая таблица маршрутизации, а кроме того в таблицу динамических правил будет занесена информация о сессии 192.168.1.24:56789 <-> 9.9.9.9:22 и о действии родительского правила (setfib 1) которое надо применять к трафику в рамках сессии. Далее, дойдя до правила 1070 трафик будет принят, выйдет из прохода IN и будет разрешен.

    Трафик первой сессии зайдет в проход OUT где пройдет по правилам до 10160. Трафик попадет в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость выходящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол (так как выключен параметр one_pass) и попадет в правило 10170. После прохождения ната трафик сново вернется в фаервол и дойдя до правила 10220 будет выведен их фаервола и уйдет во внешнюю сеть через 11.22.33.254.

    Трафик второй сессии зайдет в проход OUT где пройдет по правилам до 10190. Трафик попадет в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость выходящего трафика будет ограничена в 20Mbit/s. После выхода из Dummynet трафик вернется в фаервол (так как выключен параметр one_pass) и попадет в правило 10200. После прохождения ната трафик сново вернется в фаервол и дойдя до правила 10220 будет выведен их фаервола и уйдет во внешнюю сеть через 55.66.77.254.

    Ответный трафик в рамках первой сессии пройдет через проход IN фаервола до правила 10170 где попадет в нат, будет демаскирован и принят так как в нате уже есть активное соединение. Выйдя из ната трафик попадет в правило 10180 и будет передан в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость входящего трафика будет ограничена в 10Mbit/s. После выхода из Dummynet трафик вернется в фаервол и попадет в правило 10220 где будет разрешен, и выйдет из прохода IN фаервола. Трафик попадет в проход OUT фаервола и дойдет до правила 1040 - там он будет обработан на неявном check-state где к нему будет применено действие родительского правила (setfib 0). Далее трафик перейдет на правило 1050 после чего выйдет из IN и будет передан в сеть 192.168.1.0/24 через адаптер fxp0.

    Если на рутер из интернета придет случайный трафик, то он пройдя через правило 10170 будет отвергнут так как нат запущен с опцией deny_in.

    Ответный трафик в рамках второй сессии пройдет через проход IN фаервола до правила 10200 где попадет в нат, будет демаскирован и принят так как в нате уже есть активное соединение. Выйдя из ната трафик попадет в правило 10210 и будет передан в Dummynet - зайдет в динамически созданную очередь и трубу в результате чего скорость входящего трафика будет ограничена в 35Mbit/s. После выхода из Dummynet трафик вернется в фаервол и попадет в правило 10220 где будет разрешен, и выйдет из прохода IN фаервола. Трафик попадет в проход OUT фаервола и дойдет до правила 1040 - там он будет обработан на неявном check-state где к нему будет применено действие родительского правила (setfib 1). Далее трафик перейдет на правило 1070 после чего выйдет из IN и будет передан в сеть 192.168.1.0/24 через адаптер fxp0.

    Если на рутер из интернета придет случайный трафик, то он пройдя через правило 10200 будет отвергнут так как нат запущен с опцией deny_in.

    Если при следующем обмене трафиком в рамках первой сессии (192.168.1.24:12345 <-> 3.3.3.3:80) исходящий от 192.168.1.24 трафик на правиле 1010 будет передан не на 1040, а на 1060 то сессия не поломается так как при попадании на 1060 к трафику сессии на неявном check-state будет применено действие его родительского правила (setfib 0).

    Если при следующем обмене трафиком в рамках второй сессии (192.168.1.24:56789 <-> 9.9.9.9:22) исходящий от 192.168.1.24 трафик на правиле 1010 будет передан не на 1060, а на 1040 то сессия не поломается так как при попадании на 1040 к трафику сессии на неявном check-state будет применено действие его родительского правила (setfib 1).

    Замечания:
    Пример абсолютно не учитавает распределение DNS/UDP трафика между провайдерами. Я предрологаю, что на самом нат-рутере запущен локальный DNS-кеш сервер (Unbound, BIND, etc...) - в таком случае клиенты запрашивают разрешение имен у него, а он сам выходит в интернет только по одному каналу... Иначе DNS запросы к серверам одного провайдера могут уходить через сеть другого провайдера и не разрешаться.

    Подобная "балансировка" трафика не учитывает такие факторы как выход из строя одного из провайдеров. Если есть необходимость обрабатывать еще и это, то надо делать систему мониторинга (пинговалку?) обоих провайдеров, и в случае выпадения одного из них, перестраевать правила фаервола на задействование только одного канала как в примере 1. Подобное поведение можно удобно реализовать используя функцию наборов правил (set) ipfw.

    Так как таблица динамических правил не хранит их у себя вечно ;) то при неактивности сессии в течение какого-то времени, и после ее возобновления позже, эта сессиия может получить другую fib и уйти к получателю с другого IP. Если возникнут проблемы такого плана с какими-нибудь конкретными IP адресами (например с однокамерника... то есть с одноклассниками), то для этих конкретных IP можно создать отдельную таблицу и повесить ее обработку на отдельное правило жестко назначающее таким IP одну единственную таблицу маршрутизации.

    В данном примере "пробрасывать порты" можно только с того внешнего IP адреса который имеет default route в таблице маршрутизации по-умолчанию (fib 0). В данном случае это сетевой адаптер em0 с IP 11.22.33.44 - в экземпляре его ната выставлен проброс соединений приходящих на 25 порт на внутреннюю машину 192.168.1.5. Чтобы иметь возможность делать это с обеих внешних IP адресов, надо добавить в пример еще и такие правила:
    
    add 1011 skipto 1040 ip from any to any out xmit fxp0 tagged 1
    add 1012 skipto 1060 ip from any to any out xmit fxp0 tagged 2
    add 10171 skipto 10180 tag 1 ip from any to any in recv em0
    add 10201 skipto 10210 tag 2 ip from any to any in recv em1
    

    Пример 6

    Конфигурация практически полностью повторяет Пример 1: рутер с двумя сетевыми адаптерами подключенными в локальную сеть и в интернет. Адрес в локальной сети 192.168.1.1 (сетевой адаптер fxp0), адрес в интернете 1.2.3.4 (сетевой адаптер em0).

    Задача: "раздавать интернет" для локальной сети, обеспечить проброс портов для внутренних адресов, разрешить прохождение трафика на отдельные порты самого рутера, а главное - ввести жесткий лимит на количество одновременных исходящих TCP соединений для всего трафика уходящего в интернет (максимум 20 одновременных соединений с каждого внутреннего IP адреса).




    Конфигурация:

    /etc/rc.conf
    
    gateway_enable="YES"
    ifconfig_em0="inet 1.2.3.4 netmask 255.255.255.0 -rxcsum"
    ifconfig_fxp0="inet 192.168.1.1 netmask 255.255.255.0"
    defaultrouter="1.2.3.254"
    firewall_enable="YES"
    firewall_type="/etc/firewall"
    



    /etc/sysctl.conf
    
    net.inet.ip.fw.one_pass=1
    



    /etc/firewall
    add 1040 allow ip from any to any via fxp0
    
    add 1050 deny ip from any to 192.168.0.0/16 in recv em0
    add 1060 deny ip from 192.168.0.0/16 to any in recv em0
    add 1070 deny ip from any to 172.16.0.0/12 in recv em0
    add 1080 deny ip from 172.16.0.0/12 to any in recv em0
    add 1090 deny ip from any to 10.0.0.0/8 in recv em0
    add 10100 deny ip from 10.0.0.0/8 to any in recv em0
    add 10110 deny ip from any to 169.254.0.0/16 in recv em0
    add 10120 deny ip from 169.254.0.0/16 to any in recv em0
    
    nat 1 config log if em0 reset same_ports deny_in \
    redirect_port tcp 1.2.3.4:6881 6881 \
    redirect_port udp 1.2.3.4:4444 4444 \
    redirect_port tcp 192.168.1.24:25 25
    
    add 10130 nat 1 tcp from any to any out xmit em0 limit src-addr 20
    add 10140 nat 1 ip from any to any out xmit em0
    
    add 10150 nat 1 ip from any to any in recv em0
    
    add 65534 deny all from any to any
    



    Детальное описание прохождения трафика через фаервол в данной конфигурации:

    Для рутера:
    Исходящий TCP трафик инициализированный непосредственно от рутера пройдет через цепочку правил ipfw прохода OUT до правила с номером 10130. В следствии наличия директивы limit, трафик попадет в функцию обработки динамических (keep-state) правил - на неявный обработчик check-state. Будет проверено: нет ли соответсвия с какой-либо ранее инициализированной сессией (это окончется неудачей так как в таблице динамических правил, конечно же, не будет никаких совпадений). После неудачной проверки на активную сессию обработка вернется на тело правила 10130 где будет установлено, что пакет подпадает под критерий отбора (tcp from any to any out xmit em0). После этого в таблицу динамических правил будет помещена первая запись соответствия локальный_IP:порт <-> удаленный_IP:порт (по правилам в таблице может быть максимум 20 записей с одинаковым значением "локальный_IP") имеющая таймер устанавливающий время ее жизни. После этого трафик выйдет из функции обработки динамических правил и будет передан на поле действия правила 10130 - трафик будет перенаправлен в нат. Выйдя из ната трафик будет передан в интернет так как значение параметра one_pass=1.

    Для каждого из последующих 19 TCP соединений инициализированных от рутера обработка будет такой же. Когда таблица динамических правил заполниться, то следующие TCP соединения будут молча отвергаться до тех пор пока в динамической таблице активных соединений не освободиться место.

    Любой IP (UDP, ICMP, etc) трафик инициализированный непосредственно от рутера пройдет через цепочку правил ipfw прохода OUT до 10140 где попадет в нат и выйдя из него будет отправлен в интернет. Лимиты на данный трафик не распространяются.


    Ответный TCP трафик пройдет через проход IN фаервола до правила 10130. Не смотря на то, что тело правила (tcp from any to any out xmit em0) не имеет совпадения с параметрами трафика, из-за присутвия директивы limit трафик попадет в функцию обработки динамических (keep-state) правил - на неявный обработчик check-state. Будет проверено: нет ли соответсвия с какой-либо из ранее инициализированных сессий, и такое совпадение будет обнаружено. В следствии этого таймер устанавливающий время жизни динамической записи будет сброшен. После этого трафик выйдет из функции обработки динамических правил и будет передан на поле действия правила 10130 - трафик будет перенаправлен в нат. Выйдя из ната трафик будет передан в сокет процесса создавшего соединение.

    Любой ответный IP (UDP, ICMP, etc) трафик пройдет через проход IN фаервола до правила 10150 где попадет в нат. Выйдя из ната трафик будет передан в локальную систему.

    Трафик приходящий на порты 6881, 4444 и 25 пройдет до правила 10150 и будет принят.

    Любой случайный трафик пришедший из интернета (как TCP так и IP) пройдет до правила 10150 и будет отброшен так как нат запущен с директивой deny_in


    Для 192.168.1.0/24:

    Исходящий TCP трафик инициализированный от хостов из сети 192.168.1.0/24 (например от 192.168.1.56) пройдет через цепочку правил ipfw прохода IN до правила 1040 после чего выйдет из фаервола и будет передан в проход OUT. Зайдя в OUT трафик дойдет до правила с номером 10130. В следствии наличия директивы limit, трафик попадет в функцию обработки динамических (keep-state) правил - на неявный обработчик check-state. Будет проверено: нет ли соответсвия с какой-либо ранее инициализированной сессией (это окончется неудачей так как в таблице динамических правил, конечно же, не будет никаких совпадений). После неудачной проверки на активную сессию обработка вернется на тело правила 10130 где будет установлено, что пакет подпадает под критерий отбора (tcp from any to any out xmit em0). После этого в таблицу динамических правил будет помещена первая запись соответствия 192.168.1.56:порт <-> удаленный_IP:порт (по правилам в таблице может быть максимум 20 записей с одинаковым значением 192.168.1.56) имеющая таймер устанавливающий время ее жизни. После этого трафик выйдет из функции обработки динамических правил и будет передан на поле действия правила 10130 - трафик будет перенаправлен в нат. Выйдя из ната трафик будет передан в интернет так как значение параметра one_pass=1.

    Для каждого из последующих 19 TCP соединений инициализированный от 192.168.1.56 обработка будет такой же. Когда таблица динамических правил заполниться, то следующие TCP соединения будут молча отвергаться до тех пор пока в динамической таблице активных соединений не освободиться место.

    Любой IP (UDP, ICMP, etc) трафик инициализированный непосредственно от 192.168.1.56 пройдет через цепочку правил ipfw прохода IN до 1040, а затем в проходе OUT до 10140 где попадет в нат и выйдя из него будет отправлен в интернет. Лимиты на данный трафик не распространяются.


    Ответный TCP трафик пройдет через проход IN фаервола до правила 10130. Не смотря на то, что тело правила (tcp from any to any out xmit em0) не имеет совпадения с параметрами трафика, из-за присутвия директивы limit трафик попадет в функцию обработки динамических (keep-state) правил - на неявный обработчик check-state. Будет проверено: нет ли соответсвия с какой-либо из ранее инициализированных сессий, но такое совпадение не будет обнаружено так как пришедший из интернета трафик еще не прошел деалиасинг в нате. В следствии этого таймер устанавливающий время жизни динамической записи не будет сброшен. Трафик пройдет до правила 10150 на котором будет перенаправлен в нат. Выйдя из ната трафик покинет проход IN (так как one_pass=1) и перейдет в проход OUT где на правиле 1040 будет разрешен и уйдет в сеть 192.168.1.0/24.

    Любой ответный IP (UDP, ICMP, etc) трафик пройдет через проход IN фаервола до правила 10150 где попадет в нат. Выйдя из ната трафик будет передан в проход OUT (так как one_pass=1), где на правиле 1040 будет разрешен и уйдет в сеть 192.168.1.0/24.

    Любой случайный трафик пришедший из интернета (как TCP так и IP) пройдет до правила 10150 и будет отброшен так как нат запущен с директивой deny_in

    Замечание:
    Схема не очень красивая из-за того, что ответный трафик не обноляет счетчики на динамических правилах. Позже перепишу пример чтобы заставить приходящий трафик делать это.


    Пример 7



    Подключение к провайдеру имеет выделенный диапазон IP адресов - для использования доступно пять адресов. На рутере установлено два сетевых адаптера. Адаптер em0 подключен к провайдеру и имеет IP адреса в диапазоне от 11.22.33.[1-5]. Адаптер fxp0 подключен к локальной сети (IP 192.168.1.1).

    Задача: обеспечить выход в интернет локальной сети задействуя все имеющиеся внешние адреса (использовать пул адресов). Все это через нат и используя шейпер Dummynet обеспечить честное распределение пропускной способности между клиентами в локальной сети.



    /etc/rc.conf
    
    gateway_enable="YES"
    
    ifconfig_em0="inet 11.22.33.1 netmask 255.255.255.0 -rxcsum"
    ifconfig_em0_alias0="inet 11.22.33.2 netmask 255.255.255.255"
    ifconfig_em0_alias1="inet 11.22.33.3 netmask 255.255.255.255"
    ifconfig_em0_alias2="inet 11.22.33.4 netmask 255.255.255.255"
    ifconfig_em0_alias3="inet 11.22.33.5 netmask 255.255.255.255"
    
    ifconfig_fxp0="inet 192.168.1.1 netmask 255.255.255.0"
    
    defaultrouter="11.22.33.6"
    
    firewall_enable="YES"
    firewall_type="/etc/firewall"
    



    /etc/sysctl.conf
    
    net.inet.ip.fw.one_pass=0
    




    /etc/firewall
    
    add 1011 prob 0.2 skipto 1061 ip from any to any in recv fxp0
    add 1012 prob 0.25 skipto 1063 ip from any to any in recv fxp0
    add 1013 prob 0.333 skipto 1065 ip from any to any in recv fxp0
    add 1014 prob 0.5 skipto 1067 ip from any to any in recv fxp0
    add 1015 prob 1 skipto 1069 ip from any to any in recv fxp0
    
    add 1061 skipto 1070 tag 1 ip from any to any via fxp0 keep-state
    add 1063 skipto 1070 tag 2 ip from any to any via fxp0 keep-state
    add 1065 skipto 1070 tag 3 ip from any to any via fxp0 keep-state
    add 1067 skipto 1070 tag 4 ip from any to any via fxp0 keep-state
    add 1069 skipto 1070 tag 5 ip from any to any via fxp0 keep-state
    
    add 1070 allow ip from any to any via fxp0
    
    add 1080 deny ip from any to 192.168.0.0/16 in recv em0
    add 1090 deny ip from 192.168.0.0/16 to any in recv em0
    add 2000 deny ip from any to 172.16.0.0/12 in recv em0
    add 2010 deny ip from 172.16.0.0/12 to any in recv em0
    add 2020 deny ip from any to 10.0.0.0/8 in recv em0
    add 2030 deny ip from 10.0.0.0/8 to any in recv em0
    add 2040 deny ip from any to 169.254.0.0/16 in recv em0
    add 2050 deny ip from 169.254.0.0/16 to any in recv em0
    
    
    pipe 1 config bw 20Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 1 config pipe 1 queue 60 mask src-ip 0xffffffff gred 0.002/10/30/0.1
    
    pipe 2 config bw 35Mbit/s queue 60 gred 0.002/10/30/0.1
    queue 2 config pipe 2 queue 60 mask dst-ip 0xffffffff gred 0.002/10/30/0.1
    
    
    nat 1 config log ip 11.22.33.1 same_ports reset deny_in \
    redirect_port tcp wsrv:80 80
    nat 2 config log ip 11.22.33.2 same_ports reset deny_in
    nat 3 config log ip 11.22.33.3 same_ports reset deny_in
    nat 4 config log ip 11.22.33.4 same_ports reset deny_in
    nat 5 config log ip 11.22.33.5 same_ports reset deny_in
    
    
    add 10000 queue 1 ip from any to any out xmit em0
    
    add 10190 skipto 10601 tag 1 ip from me to any out xmit em0
    
    add 10201 nat 2 ip from any to any out xmit em0 tagged 2
    add 10202 nat 2 ip from any to 11.22.33.2 in recv em0
    
    add 10301 nat 3 ip from any to any out xmit em0 tagged 3
    add 10302 nat 3 ip from any to 11.22.33.3 in recv em0
    
    add 10401 nat 4 ip from any to any out xmit em0 tagged 4
    add 10402 nat 4 ip from any to 11.22.33.4 in recv em0
    
    add 10501 nat 5 ip from any to any out xmit em0 tagged 5
    add 10502 nat 5 ip from any to 11.22.33.5 in recv em0
    
    add 10601 nat 1 ip from any to any out xmit em0 tagged 1
    add 10602 nat 1 ip from any to 11.22.33.1 in recv em0
    
    
    add 20000 queue 2 ip from any to any in recv em0
    
    
    add 20220 allow all from any to any
    
    
    add 65534 deny all from any to any
    




    Детальное описание прохождения трафика через фаервол в данной конфигурации:

    Для рутера:
    Трафик инициированный непосредственно от рутера пройдет через цепочку правил до правила номер 10000. На правиле с номером 10000 трафик будет передан в dummynet - скорость выходящего потока будет ограничена в 20Mbit/s. После выхода из шейпера, трафик пройдет по цепочке правил до 10190 где ему будет присвоен тег 1. После этого трафик перепрыгнет на 10601. На правиле 10601 произойдет совпадение с уточняющим параметром tagged 1, и трафик будет передан в нат. Выйдя из ната трафик продолжит движение по правилам, и дойдя до правила 20220 выйдет из фаервола и уйдет во внешнюю сеть через интерфейс em0.

    Ответный трафик принимаемый из внешней сети через интерфейс em0, пройдет по цепочке правил до правила 10602 на котором будет передан в нат. Выйдя из ната трафик продолжит движение по правилам до правила с номером
    20000 на котром он будет передан в dummynet - скорость входящего потока будет ограничена в 35Mbit/s. После выхода из шейпера, трафик пройдет по цепочке правил до правила 20220, после чего выйдет из фаервола и будет принят рутером.

    Если на рутер из внешней сети, на адрес 11.22.33.1 придет случайный трафик, то он будет отвергнут так как нат запущен с опцией deny_in.

    Если на рутер из внешней сети, на адрес 11.22.33.1 придет трафик адресованный для tcp порта 11.22.33.1:80, то он будет принят так как в настройках ната указанна опция форвардинга redirect_port. Адрес назначения будет заменен IP адресом машины с именем wsrv. Трафик пройдет до правила с номером 10602 где попадет в нат. Далее трафик зайдет в правило 20000 на котром он будет передан в dummynet - скорость входящего потока будет ограничена в 35Mbit/s. После выхода из шейпера, трафик пройдет по цепочке правил до правила 20220, после чего выйдет из прохода IN фаервола и перейдет в проход OUT. В проходе OUT трафик пройдет по правилам до 1061 где попадет на неявный check-state. Так как в таблице динамических правил нет соединения для пар адресов внешнего и внутреннего адреса из IP заголовка, и трафик подпадает под действие правила from any to any via fxp0 то, следовательно, запись в таблице динамических правил будет создана, к трафику будет применен параметр действия родительского правила (tag 1), а так же применено действие родительского правила (skipto 1070). Перейдя на правило 1070 трафик выйдет из фаервола и будет передан через интерфейс fxp0 во внутреннюю сеть.

    Ответный трафик от машины с именем wsrv пройдет через любое из правил 1011-1015 с параметром prob и попадет на любое из правил 1061-1069 с параметром keep-state, в результате чего на вызове неявного check-state будет установлено, что в таблице динамических правил уже есть запись с соответсвующими параметрами для ранее установленной сессии. Трафик будет переброшен на правило впервые породившее сессию - это было правило 1061. К трафику будет применен параметр действия родительского правила (tag 1), а так же применено действие родительского правила (skipto 1070). Попав на правило 1070 трафик будет принят и выйдет из прохода IN фаервола.

    Трафик зайдет в проход OUT где на правиле с номером 1061 сново попадет на неявный check-state. Так как в таблице есть данные о сессии, то трафик будет переброшен на правило впервые породившее сессию - это было правило 1061. К трафику будет применен параметр действия родительского правила (tag 1), а так же применено действие родительского правила (skipto 1070). Так как на проходе OUT правило 1070 совпадения не даст то трафик пройдет по фаерволу далее до правила с номером 10000 на котором он будет передан в dummynet - скорость выходящего потока будет ограничена в 20Mbit/s. После выхода из шейпера, трафик пройдет по цепочке правил до 10601. Так как трафик имеет присвоенный ему ранее тег равный 1, то он будет обработан на последнем экземпляре ната у которого установлен уточняющий параметр tagged 1. Выйдя из ната трафик продолжит движение по правилам, и дойдя до правила 20220 выйдет из фаервола и уйдет во внешнюю сеть через интерфейс em0.

    Для 192.168.1.0/24:
    Допостим, что хост 192.168.1.83 инициировал две сессии. Обе сессии будут приняты рутером и на проходе IN пройдут через секцию правил с номерами 1011-1015. Эти правила имеют параметр определяющий вероятность их срабатывания. Каждое из правил делит проходящий через него поток по вероятности обработки на части. В итоге рассматривая поток из 100 случайных пакетов получим, что каждый пакет так или иначе будет обработан на каком-либо из правил, а в итоге все 100 пакетов в среднем будут поделены на пять равновероятных групп по 20 пакетов в каждой.

    Допустим, что первая сессия была обработана на правиле 1012. При этом произойдет переход на правило 1063 на котором сработает неявный check-state - будет установлено, что в таблице динамических правил еще нет записи для параметров первой сессии, в результате чего при вызове keep-state такая запись будет создана, к трафику будет применен параметр действия (tag 2) и само действие правила (skipto 1070). После перехода на правило 1070 трафик будет разрешен и выйдет из прохода IN перейдя в проход OUT фаервола. На проходе OUT трафик дойдет до первого правила с keep-state где на неявном check-state будет обработан - так как в таблице динамических правил уже есть ранее созданная запись с параметрами сессии, то к трафику будет применен параметр действия (tag 2) и само действие родительского правила (skipto 1070). После перехода на правило 1070 трафик продолжет движение до правила 10000. На правиле с номером 10000 трафик будет передан в dummynet - скорость выходящего потока будет ограничена в 20Mbit/s. После выхода из шейпера, трафик пройдет по цепочке правил до 10201. Так как трафик имеет присвоенный ему ранее тег равный 2, то произойдет совпадение с уточняющим параметром tagged 2 и трафик будет передан в экземпляр ната с номером 2. Выйдя из ната трафик продолжит движение по правилам, и дойдя до правила 20220 выйдет из фаервола и уйдет во внешнюю сеть через интерфейс em0.

    Ответный трафик полученный из внешней сети через интерфейс em0 на проходе IN пройдет до праила 10202 на котором будет передан в нат. Выйдя из ната трафик продолжит движение по правилам до правила с номером 20000 на котром он будет передан в dummynet - скорость входящего потока будет ограничена в 35Mbit/s. После выхода из шейпера, трафик пройдет по цепочке правил до правила 20220, после чего выйдет из прохода IN и перейдет в проход OUT фаервола. В проходе OUT трафик дойдет до правила 1061 где на неявном check-state будет определено, что в таблице динамических правил есть совпадение с параметрами сессии в результате чего трафик перескочет на свое родительское правило 1063 где к нему будет применен параметр действия (tag 2) и само действие правила (skipto 1070). После перехода на правило 1070 трафик будет разрешен, выйдет из прохода OUT фаервола и будет передан во внутреннюю сеть на хост 192.168.1.83.

    Ответный трафик в рамках сессии проходя через check-state всегда будет попадать на родительское правило 1063 где к нему будет применен параметр действия (tag 2) и само действие правила (skipto 1070). Таким образом, до тех пор пока в таблице динамических правил есть информация о сессии, проходящий трафик конкретной сессии всегда будет помечаться своим тегом, а позже направляться в свой экземпляр ната.

    Аналогичное поведение будет для трафика второй сессии, но, если допустить, что на секции правил с номерами 1011-1015 эта сессия была обработана правилом 1015, то тогда вся цепочка преобразований будет давать присвоение трафику тега с номером 5 и последующую обработку его на пятом экземпляре ната.

    Если на рутер из внешней сети, на адреса 11.22.33.[1-5] придет случайный трафик, то он будет отвергнут так как все экземпляры натов запущены с опцией deny_in.



    Дополнительная информация.

    Модули протоколов:

    Для ipfw nat есть возможность запускать модули помогающие улучшать работу через нат различных протоколов прикладного уровня. На момент написания заметки в FreeBSD 7.2-STABLE были достуаны следующие модули:

    alias_cuseeme.ko
    alias_ftp.ko
    alias_irc.ko
    alias_nbt.ko
    alias_pptp.ko
    alias_skinny.ko
    alias_smedia.ko
    

    Так, например, после запуска модуля alias_ftp.ko (или вручную через kldload alias_ftp.ko или через /boot/loader.conf alias_ftp_load="YES") поведение ipfw nat изменяется к лучшему - он начнет пропускать через себя активные FTP сессии инициализированные от клиентов находящихся за ним. Модуль alias_ftp отслеживат FTP трафик проходящий через нат и динамически изменяет внутреннюю таблицу ната для установления соответствия номеров портов используемых в сессии. Аналогично и для прочих модулей.
    Файл /etc/libalias.conf не влияет на работу ipfw nat. Этот конфигурационный файл используется только "user space" программами такими как natd.


    Мониторинг:

    Время процессора потребляемое ipfw и Dummynet:
    top -SH -n 500 | grep swi1
    
    PID USERNAME   PRI NICE   SIZE    RES STATE    TIME   WCPU  COMMAND
    14  root       -44 -      0K      8K  WAIT     0:00   0.00% swi1: net
    
    
    top -SH -n 500 | grep dummynet
    
    PID USERNAME   PRI NICE   SIZE    RES STATE    TIME   WCPU  COMMAND
    44  root       -68 -      0K      8K  -        1:14   0.00% dummynet
    



    Размер памяти съедаемый ipfw nat:
    vmstat -m | grep libalias
    
    Type 		InUse MemUse HighUse Requests  Size(s)
    libalias	19    35K       -    580       128
    




    Тюнинг:

    Так как ipfw nat работает в ядре, то память для своей работы он потребляет из диапазона доступного для аллокации ядру. Объем памяти ядра устанавливается через переменную sysctl vm.kmem_size. На момент написания заметки для FreeBSD 7.2-STABLE i386 это значение по-умолчанию было:
    sysctl -a | grep vm.kmem_size
    vm.kmem_size: 335544320
    vm.kmem_size_min: 0
    vm.kmem_size_max: 335544320
    vm.kmem_size_scale: 3
    

    Что есть 335544320 байт = 320 Мб.

    Потолок для i386 - 2Гб. Чтобы выставить его, необходимо пересобрать ядро с опцией options KVA_PAGES=512.

    Для архитектуры AMD64 этот параметр может быть выставлен вплоть до 6 Гб и для этого нет необходимости в пересборке ядра - достаточно установить соответсвующие sysctl значения через /boot/loader.conf.


    Описание известных проблем:

    Чем лучше какая-либо штука, тем она сложнее, а в сложных вещах бывают и свои проблемы :) Механизм ipfw nat тоже не идеален. Далее я просто перечислю некоторые его косячки и возможные решения.

    - При больших нагрузках (когда через нат создается очень много соединений) внутренняя таблица ната может разростись до очень больших размеров и исчерпать всю доступную память ядра. Такая проблема встречалась в первых релизах версии FreeBSD 7, и насколько мне известно ее решением занимались путем оптимизации механизма создания/удаления записей в таблице - патчили его чтобы он более агрессивно следил за используемой памятью. Насколько проблема актуальна сейчас я проверить не могу так как не обладаю каналом с трафиком в сотни мегабайт/сек и тысячами юзеров.
    В качестве меры профилактики можно удалять экземпляр старого ната, а потом создавать новый. Удаление делается через:
    ipfw nat delete 1
    



    - Нет возможности получить дамп внутренне таблицы ната. При включении параметра конфигурации log накапливается довольно скудная статистика которую можно просмотреть с помощью команды:
    # ipfw nat 1 show
    nat 1: icmp=0, udp=6, tcp=3, pptp=0, proto=0, frag_id=0 frag_ptr=0 / tot=9
    



    - Библиотека libalias, на которой основан ipfw nat, плохо дружит с функциями аппаратного ускорения расчета контрольных сумм и управления потоками, которые доступны на некотроых сетевых адаптерах. Рекомендуется выключать tcp segmentation offloading (TSO), а так же rxcsum на том сетевом адаптере где работает нат (ifconfig em0 -rxcsum -tso).


    - Тайной осталось то, каким образом применять директиву proxy_only. В natd кроме нее есть так же и деректива proxy_rule с помощью которой можно настраевать правила. Здесь же ее почему-то нет (недопилили?) и как завести правила проксирования - непонятно. В natd правила проксирования позволяют организовать что-то вроде ipfw fwd - пакеты адресованные на определенный порт можно модифицировать заменив в них IP адрес и порт назначения на произвольные. Без этого правила мы можем менять в пакете только адрес отправителя на тот что указан в директиве IP, или только адрес получателя на один конкретный при использовании redirect_port или redirect_addr. Функциональность proxy_rule позволила бы менять адрес получателя без привязки к конкретному IP указанному в настройках экземпляра ната. Такое нельзя сделать через связку revers+redirect_port. Например для пересылки всего исходящего http трафика на сервер srv1 порт 81, можно было бы применить правило: proxy_only proxy_rule port 80 server srv1:81


    - На момент написания заметки в FreeBSD 7.2-STABLE не работали правила redirect_proto.


    - В FreeBSD 7.1 и более ранних версиях размер redirect_port имел какое-то внутреннее ограничение приводящее к ошибкам "logical string limit" при составлении длиных правил. В FreeBSD 7.2-STABLE этой проблемы больше нет.


    - ipfw nat любит перезагрузки при изменениях в конфигурации. Я не могу привести конкретных примеров, но иногда случается, что после больших изменений в конфигурации экземпляра ната, новые настроки могут вступить в действие только после перезагрузки модуля ipfw, или же после перезагрузки машины. Бездоказательное утверждение из опыта и на уровне "ощущений".


    - Параметры sysctl которые влияют на динамические (keep-state) правила.

    срок жизни инамических правил для UDP и TCP:
    net.inet.ip.fw.dyn_udp_lifetime
    net.inet.ip.fw.dyn_ack_lifetime

    максимальное количество динамических правил:
    net.inet.ip.fw.dyn_max

    размер хеш-таблицы для поиска в списке динамических правил:
    net.inet.ip.fw.dyn_buckets

    автоматическая отсылка TCP keep-alive сообщений для динамических правил:
    net.inet.ip.fw.dyn_keepalive


    - В версии FreeBSD 8.1-RELEASE не работает параметр sysctl one_pass - трафик после прохода через нат  возвращается обратно в фаервол. Чтобы избавиться от этой неприятности надо делать правило "allow all from any to any" после правила ната. Эту проблему должны будут исправить в релизе 8.2.



    размещено: 2009-08-30,
    последнее обновление: 2011-01-28,
    автор: terminus


    vitiko007, 2009-08-08 в 22:15:53

    Супер... !!! Автор молодца :)

    www2, 2009-08-10 в 8:05:08

    Отличная работа!

    beerman, 2009-08-10 в 8:39:06

    зачем так мучицца, если во фришке есть ipfilter  с ipnat??? И работает без бубнов и доки по нему вполне вменяемые

    MadMike, 2009-08-10 в 9:36:16

    Классная статья! Автору спасибо!

    terminus, 2009-08-10 в 11:55:42

    >зачем так мучицца, если во фришке есть ipfilter  с ipnat???

    Это все конечно есть, но я предпочитаю отечественного производителя =)

    Харон, 2009-08-10 в 12:50:48

    может для кого pf и сильно альтернативный, а я перешёл на него сразу после внедрения с большим удовольствием. Однако ipfw тоже имеет право быть :)

    Прохожий, 2009-08-10 в 14:23:04

    Очепятк хорошо бы поправить...
    ...так как в настройках выстален параметр deny_in.

    AFly, 2009-08-10 в 18:23:14

    В первом примере нет правила 10140, о котором есть упоминание в тексте.

    terminus, 2009-08-10 в 18:38:26

    >В первом примере нет правила 10140

    Упс - опечался я где-то?
    Уточните пожалуйста в какой части текста первого примера про 10140.

    vales, 2009-08-10 в 18:51:06

    А где бы pf такую же красивую доку найти, где весь путь пакетов расписан и где что срабатывает и куда идет?

    vales, 2009-08-10 в 18:52:04

    ..про pf то бишь..

    GR, 2009-08-10 в 19:20:29

    Мужики - не будте неблагодарными <beeep!>
    Статья называется \"Подробное руководство по ipfw nat\" - зметьте не \"чего можно заюзать вместо\" или \"IPFILTER - город контрастов\" ...
    Автору респект, глядя на себя в зеркало - мне было бы ломы после походов по граблям, занудно и монотонно разжевывать для других. А он - сделал. Одна такая вещь стоит 99% всех ваших комментов.
    Так что Viva Terminus! Молодца!

    PS: А ошибки - вычистит.

    vales, 2009-08-10 в 19:44:46

    Да не, автору большущий респект! Но вопрос прямо по статье: я правильно понял, что общая схема остается прежней, независимо от того, какой фильтр применяется? Т.е. в случае с pf на месте ipfw_chk() будет что-то вроде pf_chk(), а прочие вещи типа ip_input(), ip_output() и ip_forward() остаются прежними, поскольку это часть ядра? Только наверное pf сам делает подмену адресов/портов для NAT и ему не нужно отклонение на ветку (8)-(9), все делается в точке (7) для выхода и в точке (2) для входа. Я прав?

    terminus, 2009-08-10 в 21:44:23

    >я правильно понял, что общая схема остается прежней, независимо от того, какой фильтр применяется?


    Не могу сказать. Я использовал объяснение nuclight про стек FreeBSD и ipfw как опорный материал. Сам я внутрях FreeBSD не копался и как все эту будет выглядеть в случае pf/ipf незнаю...

    AFly, 2009-08-11 в 10:32:14

    >Уточните пожалуйста в какой части
    Извини, все в статье нормально. Это я смотрю в книгу и вижу … не то что написано :-)

    terminus, 2009-08-12 в 18:18:26

    >я правильно понял, что общая схема остается прежней, независимо от того, какой фильтр применяется?

    вот кстати интересное выступление nuclight\'a - там кажется есть ответ на ваш вопрос.

    http://smotri.com/video/view/?id=v9864889761#none

    vales, 2009-08-13 в 19:10:12

    Посмотрел. Большое спасибо за ссылку! Действительно кое-что проясняет и дает повод подумать.

    vlad, 2009-08-21 в 12:22:58

    # боимся непонятного
    Уважаемый автор, можно можно использовать эту строку конфига у себя? :)
    P.S. спасибо за труд.

    terminus, 2009-08-21 в 14:36:24

    Это комментарий - его использовать не нужно (его использование ни на что не повлияет) ;)

    Vit, 2009-08-21 в 15:35:35

    Спасибо большое автору, хорошая статья. Молодцом, как говорил Хенкок :).

    prince, 2009-08-23 в 19:49:22

    Присоединяюсь к общей волне благодарностей!
    Есть вопрос по примеру 2, а именно:

    Какой адрес подразумевается при настройке nat 2?
    Если я правильно понимаю, машина 192.168.1.36 может ходить в инет от имени 1.2.3.4 или 1.2.3.5, а входящие соединения принимаются только через 1.2.3.5, тем самым создавая некую путаницу

    Логично ли будет отдать 192.168.1.36 отдельный коридор 192.168.1.36 <--> 1.2.3.5?

    nat 2 config if em0_alias0 log same_ports redirect_addr 192.168.1.36 1.2.3.5

    terminus, 2009-08-23 в 22:00:21

    Вот спасибо - вы нашли ошибку! Я забыл указать настройки IP для второго экземпляра :) Сейчас исправлю.

    terminus, 2009-08-23 в 22:06:11

    Хотя нет!
    На самом деле там все правильно, просто при настройке redirect_addr нельзя использовать if или ip. Такая настройка для второго экземпляра корректная - ip для своей работы он берет из последнего атрибута redirect_addr 192.168.1.36 1.2.3.5

    Я не знаю почему именно так, но этот пример был проверенн в работе.

    terminus, 2009-08-23 в 22:07:59

    И про 192.168.1.36 <--> 1.2.3.5

    192.168.1.36 будет ходить в мир ТОЛЬКО из-под 1.2.3.5.

    Jungo, 2009-08-28 в 19:16:53

    Спасибо за статью! У самого работает такой nat около года в личных целях. Когда настраивал было очень много проблем с прохождением пакетов, причем наблюдались такие вещи что при нате порты на сервере оказывались открытыми! причем все. это при том что тип default to deny. Видимо как то они подпадали под нат и не находя получателя терялись. Сути всей не знаю.

    Теперь почитаю) может что нового найду.

    Дмитрий, 2009-08-30 в 17:35:46

    Спасибо за статью!
    К примеру 4 я бы ещё добавил пример, в котором 2 провайдера и одна локалка

    Александр, 2009-08-30 в 17:56:57

    Статья сама что нужна. Ошибки ошибками, кто работает и учится с этим работать, разберутся с ними. Но интересный был бы случай, когда два провайдера и одна локалка, но один провайдер дает интернет через впн, к тому же предоставляя ресурсы в своей локалке. В остальном, большая благодарность!

    DemonSKED, 2009-08-31 в 1:10:18

    Спасибо огромное. А то ковырял нат - еле настроил. Криво вышло, но теперь есть этот шедевр на русском!

    terminus, 2009-08-31 в 10:36:09

    >К примеру 4 я бы ещё добавил пример, в котором 2 провайдера и одна локалка

    >Но интересный был бы случай, когда два провайдера и одна локалка

    Я пока не знаю как красиво сделать такое на 7.Х. Есть, конечно, вариант жестко разделить диапазон адресов локальной сети на две части, и каждую часть заводить через своего провайдера, но это кривое решение.
    Вот в 8.0 обещали ввести Equal cost multipath routing - надо будет потом посмотреть как эта штука сделана. Главная задача обеспечить прозрачную балансировку и отказоустойчивость при выпадении одного из провайдеров.

    alik, 2009-09-02 в 8:19:57

    Сразу видно, статья основана на практике!
    Да и с примерами вы хорошо постарались. Отлично.

    DoMeN, 2009-09-02 в 23:21:04

    Статья отличная натолкнула на пару мыслей. Спасибо.
    >Вот в 8.0 обещали ввести Equal cost multipath routing - надо будет потом посмотреть как эта штука сделана. Главная задача обеспечить прозрачную балансировку и отказоустойчивость при выпадении одного из провайдеров.
    Да это актуально.

    ktulhu, 2009-09-05 в 16:09:23

    автор молодец. осталось написать похожую статью для pf. и конечно же обновлять эту по мере добавления информации

    terminus, 2009-09-05 в 22:54:32

    Люди, для кого актуальна ситуация с "одной локалкой и двумя провайдерами" - потестируйте пожалуйста вот этот пример:
    http://forum.lissyara.su/viewtopic.php?f=8&t=18967&p=189375#p189375

    terminus, 2009-09-07 в 22:49:16

    В общем я прогнал пример с "двумя провайдерами" в голове и ошибок не нашел. Объяснить движение трафика через схему тоже получилось без особых затруднений...

    Короче пока предупреждение - я пятый пример не тестировал, но вероятность 0.8 того, что он заработает так как там написано :)

    Мягков Василий, 2009-09-16 в 19:05:30

    Злостный оффтоп, прошу прощения за это, вопрос автору: в чем схемы рисовались, редактор имеется ввиду?

    terminus, 2009-09-16 в 21:51:48

    В Visio 2007 + клипарт встроенный.

    kpp, 2009-09-17 в 14:55:37

    небольшая придирка, но всеже ухо(глаза) режет ;)
    "Пример 5
    ...
    Задача: обеспечить выход в интернет локальной сети через обеих провайдеров
    ..."

    нужно

    "обоих провайдеров"

    Статья - супер, имею фрю7.2 сегодня же перейду с natd на ядренный нат. У меня будет похоже на пример5, но не 2 а 3 провайдера ;)

    terminus, 2009-09-17 в 15:51:53

    мидифицировать 5й пример для 3х провайдеров сможете?

    о результатах потом на форуме (в теме для обсуждения) напишите пожалуйста.

    kpp, 2009-09-17 в 16:11:06

    Конечно модифицируем полностью и отпишусь ;)

    Kolesya, 2009-09-18 в 23:23:17

    Придется связку ipfw+natd у себя перенастроить на ядерный нат :)

    +100 "за разжеваное описалово"

    staskur, 2009-09-30 в 16:17:02

    Автор.

    куда денег закинуть за статью ?
    нереально помог.

    terminus, 2009-10-01 в 10:22:14

    Деньги в FreeBSD Foundation закиньте =)

    reekoff, 2009-10-01 в 13:59:55

    Что-то не понятно по 3-му примеру для второго экземпляра нат:
    Трафик приходящий из интернета на 5.6.7.8:80 пройдет через цепочку правил ipfw прохода IN до правила с номером 10130 где попадет в первый экземпляр ната и будет демаскирован на основании статического правила (внешний_IP <-> 5.6.7.8 будет заменено на внешний_IP <-> 192.168.1.80).
    Разве после посещения нат на этом правиле трафик не готов уже пойти на 192.168.1.80?
    nat 1 config log if em1 reset same_ports deny_in redirect_port tcp 192.168.1.80:80 80, по-моему, об этом и говорит (тобишь, 5.6.7.8 будет демаскирован в 192.168.1.80). Зачем нужен второй нат, поясните пожалуйста.
    В общем, непонятны правила преобразования адресов в обоих натах.


    terminus, 2009-10-01 в 14:55:12

    Второй нат там нежен для того чтобы вычеркнуть из пакета еще и оригинальный "внешний_IP" IP адрес - чтобы на 192.168.1.80 пакет пришел как бы от 192.168.1.254, тогда и ответ уйдет на него же.

    В описании задачи скзано, что дуступ к веб серверу надо обчеспечить только через второго провайдера не меняя настройки TCP/IP.

    Если не пропускать трафик через второй нат, то ответ на "внешний_IP" уйдет через 192.168.1.1 (через подключение к первому провайдеру).

    ---
    >непонятны правила преобразования адресов в обоих натах

    первый нат производит "демаскировку" заменяя в пакете адрес получателя. второй нат производит "маскировку" заменяя адрес отправителя.

    reekoff, 2009-10-01 в 15:28:31

    Извиняюсь,
    а (внешний_IP <-> 5.6.7.8 будет заменено на внешний_IP <-> 192.168.1.80) что здесь внешний_IP? Это который [remote IP] для redirect_port по ману?

    terminus, 2009-10-01 в 15:34:35

    ну да, я наверно не очень удачно выбрал названия... внешний_IP - это адрес удаленного клиента в интернете.

    потом переделаю там названия.

    reekoff, 2009-10-01 в 15:40:41

    тогда, может быть в конфиге первого ната нужно редирект так задать:
    redirect_port tcp 192.168.1.80:80 remote_IP:remote_port
    ?

    reekoff, 2009-10-01 в 15:45:51

    Сорри, туплю я )))

    FilosofBeer, 2009-10-22 в 12:11:31

    Странно, а в статье http://www.lissyara.su/?id=1127 IPFW - штатный файрволл FreeBSD всё по другому описано !?
    И где правда ???

    lissyara, 2009-10-22 в 15:14:22

    Посередине.
    Это не винда, где одну задачу можно решить ограниченным набором галочек, и только одним способом.
    Тут каждый волен сделать по своему, и каждый способ будет рабочим.

    FilosofBeer, 2009-10-22 в 19:34:33

    А ещё в примере 6 не описано как сделать ограничения для инета по конкретным ИП из всей локалки и ограничения скорости.

    terminus, 2009-10-22 в 20:31:06

    Примеры в статье по большому счету приведены для того чтобы показать на них концепции, а не как 100% варианты для использования... Более-менее "готовыми" являются 2, 4 и 5. Остальные - до кучи.

    Если вы на основе статьи nuclight'а и 6-го примера поймете по какому принципу действет связка nat + limit (keep-state) то осмысленно перенести ограничение количества сессий на второй или пятый примеры проблем не составит.

    Я ведь не могу заранее предусмотреть все возможные варианты использования ipfw nat, правильно? ;)

    chilllivilli, 2009-10-23 в 14:21:47

    не работает ядерный нат в клетке....http://forum.lissyara.su/viewtopic.php?f=8&t=21055&p=202097#p202097

    godlike, 2009-12-05 в 1:42:51

    Отлично.
    До всего этого доходил сам с граблями начиная с 7.0 и до сейчас (8.0).
    Преклоняюсь перед вами!
    Вы сделали по истине титанический труд.

    terminus, 2009-12-05 в 13:54:06

    Титанический труд сделал nuclight, описав в своей статье внутреннюю структуру стека, ipfw, и его взаимодействие с тем же натом, да keep-state правилами. Я только применил полученные от него знания - расписал касающееся ната по возможности подробнее. :)

    havarz, 2009-12-11 в 9:03:10

    Еще бы также подробненько про Layer2. И было бы вообще круто.

    terminus, 2009-12-11 в 22:33:48

    А что про Layer2 неясно? Да и как же прицепить его к теме про ipfw nat? =)

    havarz, 2009-12-12 в 9:11:15

    Понятно, что не про nat, просто хотелось бы также подробно и про Layer2. Четыре прохода, по манам не догоняю.
    А за статью большой респект. Перевожу свой сервер с natd на ядерный nat.

    terminus, 2009-12-12 в 19:43:59

    На форуме было какое-то обсуждение про Layer2:
    http://forum.lissyara.su/viewtopic.php?f=8&t=21660

    Если будут какие-то вопросы - спрашивайте там.

    chpoqxie, 2009-12-14 в 16:49:52

    включил нат (не по приведенной статье, по ману). и пошли кернел-трапы косяками сразу же при конфигуреньи ната.

    огромное спасибо за упоминание rxcsum. про tso написано в мане ipfw, его я отключил. не помогло. а вот отключение rxcsum вылечило падения.

    8.0-release-p1 amd64.

    terminus, 2009-12-14 в 21:16:41

    Интересно блин... А сетевуха у вас какая? em?

    chpoqxie, 2009-12-15 в 20:08:30

    ага, em две встроенные, забыл написать :)

    InventoR, 2010-01-08 в 15:32:25

    http://www.online66.ru/?id=156
    Не приятно однако

    terminus, 2010-01-09 в 14:02:12

    >Не приятно однако

    ipfw nat завоевывает мир! =)

    Пофиг. Статьи на сайте у Лисяры считай, что под BSD - то есть "юзай на здоровье". Тем более, что там ссылки стоят на оригинал.

    f0s, 2010-01-27 в 15:43:38

    InventoR, а собственно что неприятного? автор и там и там один и тот же.

    dm, 2010-05-18 в 10:33:34

    firewall_type="/etc/firewall"
    наверное firewall_script="/etc/firewall" ?

    terminus, 2010-05-19 в 11:53:37

    Можно и так, и так.

    Разница в том, что при использовании type сначала выполняются системные скрипты которые добавляют разрешения для localhost и др. что система считает нужным по-умолчанию, кроме того там не надо писать ipfw. Но и нельзя использовать переменные...

    При использовании script все правила надо составлять самому и можно юзать переменные.

    Я использую type по привычке так как считаю такой способ более предпочтительным. Например при апгрейде системы что-нить может поменяться в настройках ipfw и это будет учтено в системных скриптах которые сейчас добавляют разрешения для трафика localhost. При использовании type мои настройки не повлияют на систему, а при использовании script придется разбираться что же изменилось... Так как я сижу на STABLE/CURRENT для меня это чуть-чуть актуально.

    А вообще type/script - это дело вкуса.

    ASM, 2010-05-24 в 14:57:11

    Заметил такую штуку, что если в опциях ната есть проброс порта внутрь, а в то время, когда сервер поднимается, машина, на которую проброшен порт, выключена, то нат вроде бы и поднимается, но не работает. Пока не смог найти объяснение сему.

    SSh, 2010-06-03 в 23:07:09

    Статья - супер !!! Автору большое человеческое спасибо !!!

    alex_471, 2010-07-08 в 10:45:48

    Статья мощная, прямо как научная работа - автору респект, но переходить с natd на ipfw nat опять перехотелось. Поясню: os - 7.3, железо Intel3420+Core5i, 4GB RAM, 1 провайдер - 100 Мб. нагрузка на сервак неслабая - более 200 пользователей почты и пр. Natd работает как танк. Выключать -rxsum на Intel-ском гигабитном адаптере не собираюсь. Получаеться ipfw nat - мне не нужен. Попробуйте меня переубедить.

    www2, 2010-07-08 в 16:02:46

    >работает как танк.
    >Попробуйте меня переубедить.

    Сдалось кому-то переубеждать танкистов...

    terminus, 2010-07-08 в 17:50:32

    >Выключать -rxsum на Intel-ском гигабитном адаптере не собираюсь.

    Сетевуха какая? em или igb? На em из-за драйвера все еще есть проблемы, а про igb ничего не знаю. Попробуйте - расскажите потом.

    Dog, 2010-07-08 в 17:56:30

    Как вариант - попробовать врубить ядреный NAT на тестовой машине с аналогичной (или похожей) конфигурацией и посмотреть, что хуже скажется на производительности: отключений опции rxsum при работе kernel NAT или перелопачивание трафика с уровня ядра на пользовательский и обратно при использовании NATD.

    staskur, 2010-07-30 в 9:18:03

    " - ipfw nat любит перезагрузки при изменениях в конфигурации. "

    это мягко сказано...

    abibas, 2010-08-26 в 22:54:39

    чувак, а про pf не надо гнать, единственый его минус это то, что он не пропускает pptp сквозь нат.

    сергей, 2010-10-02 в 16:27:29

    большое спасибо за статью

    Макс, 2010-10-07 в 13:36:57

    ipfw nat конечно хорошо, но как на нем реализовать вот такое, чтобы заменить им natd?

              instance default
              interface sis0
              port 1000

              instance sis2
              interface sis2
              port 2000

              globalport 3000

    А?

    terminus, 2010-10-07 в 14:21:14

    Нету такого - запустить два экземпляря ядерного ната с общей таблицей нельзя. Если нужна балансировка между подключениями, то воркаунд с keep-state показан в пятом примере.

    Batonius, 2010-12-22 в 17:49:05

    Кажется, ошибка в пятом примере:
    add 1040 setfib 0 ip from any to any via fxp0 keep-state
    add 1050 allow ip from any to any via fxp0

    add 1060 setfib 1 ip from any to any via fxp0 keep-state
    add 1070 allow ip from any to any via fxp0


    Тогда как в форуме:
    add 1040 setfib 0 ip from any to any in recv fxp0 keep-state
    add 1050 allow ip from any to any via fxp0

    add 1060 setfib 1 ip from any to any in recv fxp0 keep-state
    add 1070 allow ip from any to any via fxp0


    А я долго бился, не мог понять, почему не работает. :( С исправлением на in recv всё заработало.
    Большое спасибо за статью! :)

    Batonius, 2010-12-22 в 17:54:50

    Забыл упомянуть. У меня FreeBSD-8.1.

    terminus, 2010-12-22 в 21:22:05

    Интересно. По логике результат должен быть один и тот же... Ладно, исправлю на in recv. Спасибо.

    ASM, 2010-12-22 в 21:37:35

    Но ведь via разрешает оба направления, а in recv - только входящие к ОС соединения.

    terminus, 2010-12-22 в 21:47:59

    Да там на том участке без разници должно быть. Единственное, я счас прикинул - если Batonius пытался делать проброс портов, то в этом случае могли быть грабли - там этот via имел бы значение, да...

    Проброс не работал или с клиентскими сессиями проблемы были?

    Batonius, 2010-12-23 в 17:33:31

    >Проброс не работал или с клиентскими сессиями проблемы были?
    Проблемы были с клиентскими сессиями, до проброса я тогда еще не дошел.
    Сегодня попробовал все еще раз на свежую голову и  сдается мне, что я слегка облажался. :) Очевидно, нужно было всего лишь перезагрузиться. И после все заработало. И с via и с in recv.

    Beginner, 2011-01-28 в 14:07:36

    Уважаемые форумчане. Уже 2 суток мучаюсь с IPFW + NATd, и у меня складывается впечатление что NATd не умеет делать divert во внутреннюю сеть если она не RFC совместима т.е. не 10, 192, 172. Срочно нужна альтернатива которая работает с не RFC подсетями. Может ли быть такой альтернативой IPFW NAT? Или есть другие варианты?

    стас , 2011-01-28 в 14:29:23

    у меня в двух местах исторически юзается сеть вида 1.2.3.ххх  ...  ipfw+NATD  там живет нормально..

    ыть, 2011-06-10 в 14:05:32

    Уважаемый, terminus, всё очень доходчиво и основательно "разжевано", приложено немало труда..

    Единственно режет\корёжит глаз\слух - "рутер".. %((
    Интересно, как вы произнесете фразу "пропишите маршрут такой-то туда-то, туда-то.." ??
    http://translate.google.ru/translate_t?hl=&ie=UTF-8&text=route&sl=en&tl=ru
    Даж и не знаю, как свои сетки роутить теперь %(
    Поверте, очень сильно корёжит..

    По-сути - мегастатья, респект!

    www2, 2011-06-10 в 15:32:17

    2 ыть

    Правильно произносится именно "рутер" (сюрприз! сюрприз!), а американцы вообще говорят "раутер". На google translat можно услышать именно американский вариант произношения.

    ыть, 2011-06-10 в 17:46:06

    ну в вашем варианте "сетки раутить" еще можно..

    статья написана русскими буквами с расчетом на то, что читать ее будут те, кто "made in USSR", т.е., общеупотребимое\понятное в повседневном лексиконе..

    ну не поймут фразу про сетки в такой транскрипции..
    зачем же с упорством маньяка следовать "правилам"..
    вы же не произносите "грустный"?
    та-же аналогия, если по-русски, пишите так, как произносите, либо по правилам, английскими буквами..

    Ну, наизнанку выворачивает, чесслово! %)

    www2, 2011-06-11 в 12:28:38

    >Ну, наизнанку выворачивает, чесслово! %)

    У вас какие-то проблемы с желудком. Вы поосторожнее с этим. А то сначала гастрит, потом язва...

    terminus, 2011-06-13 в 13:15:57

    Не знаю, всю жизнь все везде говорили просто рутер.

    sergko, 2011-06-24 в 15:14:49

    ipfw nat любит перезагрузки при изменениях в конфигурации. Я не могу привести конкретных примеров, но иногда случается, что после больших изменений в конфигурации экземпляра ната, новые настроки могут вступить в действие только после перезагрузки модуля ipfw, или же после перезагрузки машины. Бездоказательное утверждение из опыта и на уровне "ощущений".

    Обсалютно верно! Пол дня сидел настраивал НАТ, перезагружал ipfw и тоже самое было! Пока сервак не перезагружу или не уберу из правил НАТ

    Vasiliy P. Melnikm, 2011-08-05 в 0:17:54

    В первом примере ошибка, хотя возможно все и работает.

    gateway_enable="YES"
    ifconfig_em0="inet 1.2.3.4 netmask 255.255.255.0 -rxcsum"
    ifconfig_fxp0="inet 192.168.1.1 netmask 255.255.255.0"
    defaultrouter="1.2.3.254"
    firewall_enable="YES"
    firewall_type="/etc/firewall"

    А вместо этого надо
    firewall_script="/etc/rc.firewall"
    # Which script to run to set up the firewall

    terminus, 2011-08-07 в 20:12:05

    Все нормально там.

    Если используется firewall_type то при этом команды перечисленные в нем  обрабатываются напрямую ipfw, а если firewall_script то там уже просто любые shell команды/конструкции можно использовать.

    На любителя - никто не запрещает использовать то, что больше нравиться.

    Феликс, 2011-08-28 в 13:27:15

    Вот это сила, вот это жесть, да я в сетке не видел не чего подобного да так что бы было все в одном месте дэк еще и разжеванно, статья очень сильная! БООООЛЬЬЬШОЕ СПАСИБО АфФтору, отжоГ прямо в Ад.

    очень и очент интересно позновательно, до многово что бы додуматься у некоторых ушли бы месяцы а тут 1ч чтения и понятная картина, спасибо еще раз, обязательно использую правила, когда буду уходить в мелкомяхкого вин(д)овоза!

    Thanks!!!
    такой вопрос, пример:
    add 1050 deny ip from any to 192.168.0.0/16 in recv em0
    add 1060 deny ip from 192.168.0.0/16 to any in recv em0
    add 1070 deny ip from any to 172.16.0.0/12 in recv em0

    откуда они берутся ? или Мы их сами указываем как индефикатор правила для дольшейшего использования, или как вообще, я баран в этом так что чур не дратся!

    Феликс, 2011-08-28 в 13:31:39

    Соррии я имеюю ввиду цыфры 1050.1060.1070

    terminus, 2011-08-29 в 16:43:36

    Это "индефикатор правила для дольшейшего использования". порядковый номер правила - то, что показывает ipfw show.

    man ipfw

    Феликс, 2011-08-30 в 10:21:39

    Thanks!!!Thanks!!!Thanks!!!

    Klop, 2011-09-01 в 10:51:58

    Вот интересно: кто-нибудь разобрался, какова схема прохождения пакета в случае использования не natd в user space, а именно ipfw kernel nat?
    Пока не дошло. Вывод tcpdump уже снится...(((

    terminus, 2011-09-01 в 10:57:59

    точно такая же, читайте nuclihgt'а:
    ---
    Подобное выведение пакета из обработки ipfw в другую подсистему — не уникально
    для divert, это общая схема работы в стеке FreeBSD. Например, действия pipe и
    queue в dummynet, передача пакета в netgraph (а также появившийся в 7.0
    ipfw nat) действуют по тому же принципу. Отличие, однако, в том, что в этих
    подсистемах пакет остается внутри ядра, никакому демону не передается.
    ---

    gonzo111, 2011-10-15 в 17:40:23

    Нагуглил как сделать доступным пинг сервера из интернета

    "Перед НАТом добавляем такое правило:
    ipfw add 1350 allow icmp from any to 195.98.163.142 icmptypes 8 in via rl0
    Если разрешить, например, еще и эхо-ответ (icmptypes 0), то пинг из локальной сети уже не будет работать, поскольку ответ от удаленного ресурса будет сразу обрабатываться сервером напрямую, не попадая в НАТ. "
    http://forum.muff.kiev.ua/index.php?PHPSESSID=ac794d2b4f9d27cfa296b89f5c4ac9e1&topic=25.15
    спасибо ребята

    Стас, 2011-11-17 в 21:14:18

    Заместо setfib лучше юзать ipfw fwd. Не надо будет мучаться с двумя таблицами маршрутизации. Опять же это снимает ограничения с кол-ва каналов, которые натятся. Т.е. вы можете спокойно занатить хоть 15 каналов и правилами ipfw fwd указать для каждого свой дефолт, не применяя для этого дополнительных таблиц маршрутизации. Ну и конечно при этом не надо забывать one_pass=0. А для того, чтобы заработал ipfw fwd надо добавить в опции ядра options IPFIREWALL_FORWARD

    terminus, 2011-11-17 в 21:17:14

    fwd накладнее по ресурсам чем setfib

    Стас, 2011-11-17 в 21:28:46

    Но для каналов больше 2, придётся создавать на этапе компиляции ядра соответственное кол-во таблиц маршрутизации. Так что, если каналов много, то fwd более выгоден.

    terminus, 2011-11-17 в 21:50:40

    когда при компиляции было задано 2 fib то для использования 3,4,5...16 fib-ов можно использовать sysctl (то есть каждый раз перекомпиливать не надо):

    ===
    www.freebsd.org/releases/7.1R/errata.html

    This number can be modified on boot time. To do so, add the following to /boot/loader.conf and reboot the system:
    net.fibs=6
    ===

    adsh, 2011-12-12 в 1:10:51

    В чём смысл указания:

    queue, gred

    для пайпов, если они уже указаны для очередей?

    Насколько я понимаю, ссли есть вложенные очереди с такими параметрами, что указано для пайпа не имеет никакого значения.

    SkiNNi, 2011-12-19 в 13:25:19

    Естли сделать так. redirect_proto ip 192.168.1.11 то весь трафик пойдёт на 192.168.1.11, как и нету шлюза? И шлюз не получит ни какого пакета на уровень приложений?

    Стас, 2011-12-19 в 16:41:16

    Да, весь входящий tcp трафик пойдёт на хост 192.168.1.11 минуя уровень приложений

    adre, 2012-04-20 в 20:51:02

    Вот сижу и думаю. Зачем выставляется в данной системе HZ=1000 чем HZ=100 не устраивает?

    potf, 2012-04-24 в 12:25:50

    Прекрасная работа! Спасибо и Респект Автору!

    Мфынф, 2013-10-20 в 16:44:16

    ТУПАЯ ХИРНЯ

    bit suid, 2015-01-18 в 18:52:37

    FreeBSD 8.4 x64
    настраивал NAT  по примеру 1
    так нифига и не получилос НАТ не заработал
    КОНФИГ НЕ ПРАВИЛЬНЫЙ ДЛЯ НОВИЧКОВ СОВСЕМ НЕ ПОНЯТНЫЙ

    add 1040 allow ip from any to any via em1
    Это праило не отрабатывает КУДА СМОТРЕЛ АВТОР КОГДА ПИСАЛ СТАТЬЮ

    нужно исправить
    ipfw add 1040 allow ip from any to any via em1
    вот так работает

    terminus, 2015-01-19 в 15:01:38

    >КУДА СМОТРЕЛ АВТОР КОГДА ПИСАЛ СТАТЬЮ

    Автор предпологает, что у вас в /etc/rc.conf прописано:
    firewall_type="/etc/firewall"

    Если у вас прописано так:
    firewall_script="/etc/firewall"
    то работать не будет.

    _type и _script это разные вещи...

    Anton, 2015-04-21 в 14:52:21

    Возможно, баг или я не врубаюсь. В пятом примере редирект 25-го порта. Если пришёл входящий пакет, на проходе IN он зацепит 10170, 10180 и 10220. На проходе OUT он выйдет через 1050 и направится к 192.168.1.5. Но при этом никакие динамические правила не созданы и ответный пакет с вероятностью 50% может уйти через em1.
    Я думаю, что в правиле 1040 нужно исправить in recv fxp0 на via fxp0, тогда входящий пакет зацепит 1040 на проходе OUT для создания необходимого динамического правила.

    Rader, 2015-08-24 в 6:41:27

    Как составить конфигурация ipfw, чтобы все запросы DNS из локальной сети перенаправлялись только в мой DNS сервер?

    ama, 2015-10-13 в 18:39:48

    Просьба исправить рутор на роутер или маршрутизатор, читать ведь, неприятно!

    Pavel, 2016-07-19 в 17:30:43

    Подскажите пожалуйста, почему в статье используется параметр type, а не script? Для NAT это более предпочтительно или просто статья старая?

    Pizdyk, 2016-07-20 в 7:30:52

    Type типфаервола, а скрипт, это какие правила сам пилишь.

    Fahri Hasan, 2017-08-25 в 22:53:33

    Оптимизированные правила ipfw:

    net.inet.ip.fw.one_pass=1

    https://github.com/mysticall/imslu/blob/master/conf/freebsd/usr/local/etc/imslu/rc.firewall

    tauri, 2017-09-21 в 10:37:22

    а вот такой вопрос. Как "net.inet.ip.fw.dyn_keepalive" пакеты на выходе занатить? D



  •  

      Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
      Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

    © lissyara 2006-10-24 08:47 MSK

    Время генерации страницы 0.1133 секунд
    Из них PHP: 74%; SQL: 26%; Число SQL-запросов: 86 шт.
    Исходный размер: 364195; Сжатая: 55768