СЕРГЕЙ СУПРУНОВ
FreeBSD tips: использование ipnat
В одной из предыдущих статей [1] было рассмотрено построение сервера NAT на основе FreeBSD и natd. Данная статья будет посвящена другому средству – модулю ipnat, входящему в пакет IPFilter. Сам IPFilter уже рассматривался на страницах журнала [2].
Некоторые основополагающие моменты я повторю, чтобы сохранить целостность и самодостаточность этого материала, а сосредоточимся мы именно на построении сервера NAT.
Во FreeBSD 5.3 IPFilter (ipf), входящий в состав системы, может быть встроен в ядро, для чего ядро нужно пересобрать с опциями IPFILTER и IPFILTER_LOG. Так же ipf может быть запущен как модуль. Я воспользуюсь второй возможностью.
Итак, ядро трогать не будем. Для работы ipnat фильтр ipf должен быть настроен и запущен. В простейшем случае достаточно запустить его с парой правил, разрешающих прохождение любых пакетов, что может быть оправдано в том случае, если регулирование пакетов вы уже осуществляете другим фильтром. Правила заносятся по умолчанию в /etc/ipf.rules:
Файл /etc/ipf.rules
pass in from any to any
pass out from any to any
Запуск фильтра можно выполнить из командной строки:
# ipf -Fa -f /etc/ipf.rules
Ключ -Fa очищает все ранее заданные правила и загружает те, которые перечислены в конфигурационном файле. Для автоматического запуска фильтра при перезагрузке добавьте опцию «ipfilter_enable = “YES”» в /etc/rc.conf. Если поддержка фильтра не включалась в ядро, в списке подгруженных модулей появится модуль ipl.ko.
Аналогично правила трансляции адресов записываются по умолчанию в файл /etc/ipnat.rules. Запуск ipnat выполняется командой:
# ipnat -CF -f /etc/ipnat.rules
Ключ -C очищает таблицу правил, ключ -F удаляет записи из таблицы трансляций. Поскольку ipnat является, по сути, частью пакетного фильтра, то никакого перенаправления трафика на вход этого NAT-сервера не требуется. Входящие пакеты сначала будут подвергаться трансляции (пройдут через правила ipnat), затем поступят на вход ipf. Исходящие пакеты, наоборот, сначала фильтруются на ipf, а что будет пропущено, подвергается трансляции в соответствии с правилами ipnat.
Для автоматического запуска при перезагрузке в /etc/rc.conf добавьте строчку «ipnat_enable = “YES”».
Итак, приступим к рассмотрению правил трансляции. Замечу, что, в отличие от ipfw, в ipf и ipnat, правила не нумеруются, и их порядок определяется последовательностью загрузки, то есть местом в конфигурационном файле.
Собственно трансляция пакетов, исходящих с машин локальной сети в Интернет (маскарадинг), осуществляется правилом map:
map rl0 from 192.168.0.0/24 to any -> 100.100.100.101/32
Читать его очень просто, почти как на естественном языке: преобразовывать пакеты, проходящие через интерфейс rl0, с адресов, принадлежащих указанной подсети, на любые адреса, заменив адрес отправителя указанным реальным. Если конкретизация адресов назначения не требуется, можно использовать и упрощенный синтаксис:
map rl0 192.168.0.0/24 -> 100.100.100.101/32
Правило может быть дополнено некоторыми опциями, из которых наиболее часто используется portmap. Она конкретизирует, на какие номера портов отображать пакеты. Диапазон портов, которые разрешается использовать для целей трансляции, задается в виде begin:endN. Например, следующее правило позволяет использовать только TCP-порты с 10000 по 10999:
map rl0 192.168.0.0/24 -> 100.100.100.101/32 portmap tcp 10000:10999
После символов «–>» может быть указан не только один адрес, но и подсеть внешних адресов. В этом случае правило map сможет использовать любой свободный адрес из указанной подсети.
Для безусловной двунаправленной трансляции между внутренним и внешним адресами используется правило bimap:
bimap rl0 192.168.0.125/32 -> 100.100.100.125/32
Помимо трансляции исходящих пакетов все входящие пакеты, адресованные хосту 100.100.100.125, будут перенаправляться на «внутреннюю» машину. Это правило позволит машине с адресом 192.168.0.125 выглядеть снаружи так, как будто она имеет реальный адрес 100.100.100.125.
Если нужно пропускать пакеты, приходящие на определенные порты, внутрь локальной сети, например, если там размещен Web- или FTP-сервер, используются правила перенаправления:
rdr rl0 100.100.100.180/32 port 80 -> 192.168.0.80 port 8080 tcp
В этом случае TCP-пакеты, адресованные на 80-й порт хоста 100.100.100.125, будут транслироваться на порт 8080 машины, расположенной внутри локальной сети.
Одним из интересных свойств редиректа является возможность создавать балансировщик нагрузки между несколькими серверами, хотя и довольно примитивный. Например, следующие правила будут поочередно перенаправлять входящие запросы то на один, то на другой сервер:
rdr rl0 100.100.100.180/32 port 80 -> 192.168.0.80 port 8080 tcp round-robin
rdr rl0 100.100.100.180/32 port 80 -> 192.168.0.81 port 8080 tcp round-robin
Опция round-robin заставляет динамически менять порядок правил таким образом, что эти правила срабатывают по очереди.
Для контроля за работой ipnat используются два ключа: -s и -l. Первый выдает общую статистику работы NAT-сервера:
# ipnat –s
mapped in 476 out 460
added 29 expired 27
no memory 0 bad nat 0
inuse 1
rules 1
wilds 0
|
Ipnat со вторым ключом выводит список активных правил и список активных в данный момент сеансов:
# ipnat –l
List of active MAP/Redirect filters:
map rl0 from 192.168.0.100/32 to any -> 100.100.100.100/32
List of active sessions:
MAP 192.168.0.100 1035 <- -> 100.100.100.100 1035 [64.12.26.148 443]
|
Дополнительные сведения можно, как обычно, получить на страницах справочного руководства man ipnat(5), ipnat(1).
Замечу, что ipfw, natd, ipf, ipnat отлично уживаются вместе. Нужно только не забывать про особенности фильтров: ipfw срабатывает по первому совпадению, а ipf (без опции quick в правиле) – по последнему. Ну и всегда следует иметь в виду порядок прохождения пакета через фильтры. Так, если поддержка ipf собрана в ядре, то независимо от того, как запущен ipfw, в первую очередь пакеты будут проходить через правила ipf, а ipfw получит на вход только то, что будет им пропущено. Если же ipfw собран в ядре, а ipf подгружен как модуль, то правом первенства будет пользоваться ipfw.
Как natd, так и ipnat, отлично справляются с типовыми задачами трансляции адресов, и выбор между ними – скорее дело вкуса. В «экзотических» случаях могут понадобиться уникальные свойства того или иного сервера. Например, средства проксирования у natd более развиты, чем у ipnat, зато с помощью ipnat намного проще реализовать трансляцию различных групп адресов по разным правилам. Если ipnat способен решать те задачи, которые вам требуются, то, учитывая его «близость» к ядру и, следовательно, лучшее быстродействие, рекомендуется использовать этот сервер NAT. К тому же его конфигурация выглядит немного более удобной.
Литература:
- Супрунов С. FreeBSD tips: NAT по старинке. – журнал «Системный администратор» №2, 2005 г.
- Ильченко Т. IPFilter с самого начала. – журнал «Системный администратор» №5, 2004 г.