Теперь, когда мы познакомились как с описанием принципов прохождения трафика через стек, так и с описание доступных опций конфигурирования механизма ipfw nat, можно приступать к составлению правил и рассмотрению их работы. Дальнейшее описание будет строиться по принципу "задача - решение", а так же по принципу постепенного усложнения конфигурации, с детальными описаниями того как работает предлагаемое решение. Есть мнение, что на примерах проще понять изучаемый материал, а кроме того эти примеры можно будет использовать в работе.
Включение ipfw nat и Dummynet
Либо пересборка ядра с дополнительными параметрами:
Либо включение без пересборки (но так меньше возможностей для конфигурации)
/etc/rc.conf
firewall_nat_enable="YES" dummynet_enable="YES"
Пример 1
Простейший случай: рутер с двумя сетевыми адаптерами подключенными в локальную сеть и в интернет. Адрес в локальной сети 192.168.1.1 (сетевой адаптер fxp0), адрес в интернете 1.2.3.4 (сетевой адаптер em0).
Задача: "раздавать интернет" для локальной сети, обеспечить проброс портов для внутренних адресов, разрешить прохождение трафика на отдельные порты самого рутера.
# правила разрешающие трафик через локальный интерфейс 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
# настройка ната # опции переноса строк "\" надо убрать # все должно быть в одну строчку nat 1 config log if em0 reset same_ports deny_in \ redirect_port tcp 1.2.3.4:68816881 \ redirect_port udp 1.2.3.4:44444444 \ redirect_port tcp 192.168.1.24:2525
# заварачиваем все что проходит через внешний интерфейс в нат 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.
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
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 используя два экземпляра ната.
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
Детальное описание прохождения трафика через фаервол в данной конфигурации:
Для рутера:
Трафик инициализированный непосредственно от рутера пройдет через цепочку правил ipfw прохода OUT до правила с номером 10130 где попадет в нат. После прохождения ната трафик выйдет из фаервола и будет передан в интернет.
Ответный трафик пройдет через цепочку правил прохода IN фаервола до правила 10130 где попав в нат будет демаскирован (в данном случае не сущесвенно) и выйдет