Документация по ОС FreeBSD Четверг, 05.12.2024, 04:39
Приветствую Вас Гость | RSS
Меню сайта

Категории каталога
Apache [58]
DNS [25]
FTP [27]
Mail [74]
Samba [24]
Squid [46]
SSH [23]
VPN [35]
РРР [20]
Net [173]

Главная » Статьи » Сеть » Net

Описание работы с ng_nat [2011]
Возник интерес к подсистеме netgraph. Решил начать изучать ее с наиболее актуальной и нужной лично мне возможности - с ната реализованного в ноде ng_nat. За время использования ipfw nat выяснилось, что у него есть некоторые недостатки, а ответственные за него люди из проекта FreeBSD что-то не спешат исправлять найденные проблемы. Поэтому захотелось освоить параллельно еще и ng_nat чтобы применять его при случае там, где ipfw nat не дает нужного результата. Да и просто ng_nat (как и сам netgraph) - это прикольная штука играться с которой уже само по себе интересно!

С того времени как ng_nat впервые был закоммичен в FreeBSD в нем многое изменилось. В первых реализациях не было некоторых важных функций (типа проброса портов), а теперь его функционал даже больше чем у ipfw nat! Нода ng_nat построена все на той же библиотеке libalias на которой работают как ipfw nat, так и natd и все что мы знаем о natd применимо к ng_nat. К слову сказать - даже модули протоколов libalias (alias_ftp.ko, alias_irc.ko, etc...) работают с ng_nat так же как они работали с ipfw nat.

Если провести сравнение с ipfw nat, то на вскидку получится следующий список фич в пользу ng_nat:
- работают правила проксирования proxy_rule, proxy_only
- менее "глючен" в работе, позволяет налету изменять правила проброса портов
- нет неприятных ошибок типа ограничений на количество редиректов (NAT_BUF_LEN)
- возможность добавлять к правилам проброса портов текстовые описания
- дополнительные, интересные настройки не реализованные в ipfw nat

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

В процессе освоения ng_nat возникли некоторые вопросы по его настройке. Хотелось бы выразить благодарность Вадиму Гончарову ака nuclight за то, что он дал полезную информацию о принципах настройки ng_nat, а так же за то, что он подготовил специальный rc.d скрипт ng_nat.sh для настройки экземпляров ng_nat - этот скрипт значительно облегчает работу с netgraph для тех кто с ним никогда не имел дела. Примеры в заметке будут использовать ng_nat.sh
Скрипт этот был сделан уже давно, но по непонятным причинам в базовую систему не вошел (снова хотелось бы передать ПРЕВЕД людям отвечающим за ipfw в FreeBSD - почему ng_nat принят, а этот полезный дополнительный функционал к нему не принят?!)

Ручное создание ноды ng_nat и связь ее с ipfw

Для того чтобы вручную создать экземпляр ng_nat и связать его с ipfw, надо проделать следующие шаги:

- загрузить через kldload (или /boot/loader.conf) модули netgraph.ko, ng_ipfw.ko и ng_nat.ko
- создать с помощью ngctl экземпляр ноды ng_nat и связать ее своими хуками с нодой ng_ipfw и ее хуками
- с помощью управляющих сообщений netgraph, настроить ноду ng_nat
- с помощью ipfw настроить пересылку входящего и исходящего трафика в netgraph через соответствующие хуки

Создание ноды ng_nat под именем nat1 и связь ее с ipfw:
ngctl mkpeer ipfw: nat 100 in
ngctl name ipfw:100 nat1
ngctl connect ipfw: nat1: 200 out
ngctl msg nat1: setaliasaddr 192.168.1.1

Была создана нода ng_nat под именем nat1, и в качестве первичной настройки ей было указано использовать IP адрес 192.168.1.1 для алиасинга. Нода под именем nat1 имеет два хука. Хук in, через который в ноду поступает трафик для демаскировки, соединен с хуком под номером 100 у ноды ipfw. Хук out, через который в ноду поступает трафик для маскировки, соединен с хуком под номером 200 у ноды ipfw.

Настройка ipfw для пересылки трафика в ng_nat:
ipfw add netgraph 100 all from any to any in via fxp0
ipfw add netgraph 200 all from any to any out via fxp0

Правила пересылают весь трафик приходящий к нам через внешний интефейс fxp0 в netgraph через хук 100, а весь исходящие трафик пересылается в netgraph через хук 200. Таким образом трафик из ipfw перенаправляется на обработку в экземпляр ng_nat.

Показанный выше пример дает общее представление о принципах настройки связки ipfw + ng_nat. Ниже будут приводиться примеры более детальной ручной настройки ng_nat, а в конце заметки будет пример использования rc.d скрипта ng_nat.sh с помощью которого можно отказаться от рутины и автоматизировать настройку через /etc/rc.conf

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

Ниже приводятся ключевые слова используемые при настройке ng_nat через сообщения netgraph, примеры сообщений netgraph, а так же их эквиваленты применяемые для настройки ноды ng_nat через rc.d интерфейс реализованный в ng_nat.sh.

Сообщения netgraph для настройки ng_nat:
setaliasaddr

Параметр указывает IP адрес используемый при 
маскировании и демаскировании.

Пример сообщения netgraph:
ngctl msg nat1: setaliasaddr 192.168.1.1

Пример настройки через rc.conf/ng_nat.sh:
ng_nat_nat1_interface="192.168.1.1"
ng_nat_nat1_interface="fxp0"

setmode

Устанавливает режимы работы экземпляра ната.
Для настройки доступны следующие опции (опция - шестнадцатеричное 
значение - [десятичный эквивалент]):

NG_NAT_LOG 0x01 [1]
NG_NAT_DENY_INCOMING 0x02 [2]
NG_NAT_SAME_PORTS 0x04 [4]
NG_NAT_UNREGISTERED_ONLY 0x10 [16]
NG_NAT_RESET_ON_ADDR_CHANGE 0x20 [32]
NG_NAT_PROXY_ONLY 0x40 [64]
NG_NAT_REVERSE 0x80 [128]

Каждое из этих значений в бинарном виде выражается с помощью установки одного разряда. Например NG_NAT_PROXY_ONLY [64]= 01000000. Комбинация этих значений задает режим работы экземпляра ната. Например для установки режимов NAT_LOG + DENY_INCOMING + SAME_PORTS + UNREGISTERED_ONLY + RESET_ON_ADDR_CHANGE мы должны передать управляющее сообщение содержащее десятичное значение 1+2+4+16+32=55

Пример сообщения netgraph:
ngctl msg nat1: setmode { flags=55 mask=55 }

Пример настройки через rc.conf/ng_nat.sh:
ng_nat_nat1_set_mode="log deny_incoming same_ports unregistered_only reset_on_addr_change"

settarget

Устанавливает адрес по-умолчанию на который должна происходить передача 
входящего трафика, когда в таблице переадресации нет полного совпадения 
для какой-либо из ранее установленных сессий или правил пересылки 
установленных вручную. Функционал аналогичный режиму "natd -t".

Пример сообщения netgraph:
ngctl msg nat1: settarget 172.16.0.100

Пример настройки через rc.conf/ng_nat.sh:
ng_nat_nat1_set_target="172.16.0.100"

redirectport

Проброс входящих TCP/UDP соединений на внутренние хосты.

Пример сообщения netgraph:
ngctl msg nat1: redirectport { local_addr=172.16.0.100 alias_addr=192.168.1.1 remote_addr=8.8.8.8 local_port=8080 alias_port=80 remote_port=12345 proto=6 description="this is test" }

Пример настройки через rc.conf/ng_nat.sh:
ng_nat_nat1_redirect_port0="tcp 172.16.0.100:8080 192.168.1.1:80 8.8.8.8:12345"
ng_nat_nat1_redirect_port0_description="this is test"

redirectaddr

Проброс входящих TCP/UDP соединений на внутренние хосты.

Пример сообщения netgraph:
ngctl msg nat1: redirectaddr { local_addr=172.16.0.100 alias_addr=192.168.1.1 description="this is test" }

Пример настройки через rc.conf/ng_nat.sh:
ng_nat_nat1_redirect_address0="172.16.0.100 192.168.1.1"
ng_nat_nat1_redirect_address0_description="this is test"

redirectproto

Проброс входящих TCP/UDP соединений на внутренние хосты.

Пример сообщения netgraph:
ngctl msg nat1: redirectproto { local_addr=172.16.0.100 alias_addr=192.168.1.1 remote_addr=8.8.8.8 proto=6 description="this is test" }

Пример настройки через rc.conf/ng_nat.sh:
ng_nat_nat1_redirect_proto0="tcp 172.16.0.100 192.168.1.1 18.8.8.8"
ng_nat_nat1_redirect_proto0_description="this is test"

redirectdynamic

Делает ранее установленное правило редирекции динамическим. 
После первого обмена пакетами через динамическое правило, 
оно будет автоматически удалено

Пример сообщения netgraph:
ngctl msg nat1: redirectdynamic 1

redirectdelete

Удаляет правило редирекции

Пример сообщения netgraph:
ngctl msg nat1: redirectdelete 1

Пример настройки через ng_nat.sh:
ng_nat.sh delete_redirect nat1 1

addserver

Реализация LSNAT - распределения коннекций на несколько 
серверов по round-robin. Сообщение netgraph принимает id 
номер ранее установленной редирекции и адрес + порт 
назначения которые надо добавить для данной редирекции.

Пример сообщения netgraph:
ngctl msg nat1: addserver { id=1 addr=1.2.3.4 port=8080}

Пример настройки через rc.conf/ng_nat.sh:
ng_nat_nat1_redirect_port0="tcp 172.16.0.100:80,172.16.0.102:80 192.168.1.1:80"

listredirects

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

Пример сообщения netgraph:
ngctl msg nat1: listredirects

Пример настройки через rc.conf/ng_nat.sh:
ng_nat.sh list_redirects nat1

proxyrule

Конфигурация правила проксирования проходящего трафика. 
Правила применяются к трафику полученному через хук in. 
Возможные значения type: encode_ip_hdr | encode_tcp_stream | no_encode

Пример сообщения netgraph:
msg nat1: proxyrule "type no_encode port 81 server 
172.16.1.1:8080 proto tcp dst 7.7.7.7"

Пример настройки через rc.conf/ng_nat.sh:
ng_nat_nat1_proxy_rule0="type no_encode port 80 server 172.16.1.1:8080 proto tcp dst 7.7.7.7"

Дополнительная информация о способах конфигурации режимов работы ng_nat

В примере использования сообщения setmode была показана конструкция такого вида:
ngctl msg nat1: setmode { flags=55 mask=55 }

Про способ подбора значения параметра flags было сказано (плюсуются десятичные значения соответствующих опций), но не было сказано про второй параметр - mask. Маска используется для указания какие именно биты конфигурации необходимо изменить. Как объяснил nuclight - в C коде есть такая часть в которой и происходит обработка флагов и маски. Там-то как раз и задается режим работы ноды ng_nat:
la->packetAliasMode = (flags & mask) | (la->packetAliasMode & ~mask);

Это значит, что когда заданы как флаги так и маска, между ними проводится логическая операция AND после чего в качестве конфигурации ноды ng_nat применяется полученное значение. В нашем случае применение AND между  flags=55 и mask=55 даст то же самое 55 - режим который мы хотим установить. С тем же успехом можно было применять flags=55 mask=0xffffffff - это бы дало те же самые 55. Если задать flags=55 и mask=54 то будет отключен режим логирования (убрали единицу в последнем разряде).

Маску можно использовать для управления режимом работы ната, когда не известно эталонное значение flags. Скажем, если мы хотим отключить режим DENY_INCOMING [2] то можно послать такое сообщение:
ngctl msg nat1: setmode { flags=0 mask=2 }

так как флаги равны 0 (false), то сработает вторая часть кода в которой будет взято теперешнее значение флагов, инвертирована переданная нами маска, и между ними будет проведена операция AND. В итоге флаги станут 53 и это значение будет применено к ноде ng_nat.

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

Пример 1

Случай использования правил проксирования для передачи http трафика на прозрачный прокси сервер. Прокси сервер работает на машине 192.168.1.80 у которой свое подключение к интернету. Весь проходящий через наш рутер трафик адресованный на 80 порт любого адреса получателя надо пересылать на 192.168.1.80:8080. Наш нат рутер имеет адреса 192.168.1.1 со стороны локальной сети и 1.2.3.4 со стороны интернета.

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

/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"

ng_nat_enable="YES"
ng_nat_nodes="nat1"
ng_nat_nat1_interface="em0"
ng_nat_nat1_cookies="1 2" # in out
ng_nat_nat1_ipfw_rules="20005 20008" # in out
ng_nat_nat1_ipfw_rule0="20005 netgraph 1 ip from any to me in recv em0"
ng_nat_nat1_ipfw_rule1="20008 netgraph 2 ip from any to any out xmit em0"
ng_nat_nat1_set_mode="same_ports reset_on_addr_change log deny_incoming"
ng_nat_nat1_proxy_rule0="type no_encode port 80 server 192.168.1.80:8080 proto tcp"

/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

# здесь в правилах с номерами 20005 и 20008 автоматически появятся
# директивы пересылающие трафик в ng_nat

add 65534 deny all from any to any

Файл ng_nat.sh надо скачать от сюда, поместить в /usr/local/etc/rc.d/ и сделать выполняемым через chmod 555 ng_nat.sh

Более подробно о ng_nat можно прочитать в манах

Так же про настройку различных режимов libalias тоже в манах

Подробное описание использования ng_nat.sh можно прочитать сдесь



Источник: http://www.lissyara.su/articles/freebsd/tuning/ng_nat/
Категория: Net | Добавил: oleg (31.03.2011) | Автор: terminus
Просмотров: 797 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Beastie

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
links

Copyright MyCorp © 2024