From: Vyacheslav Fedenko
Newsgroups: email
Date: Mon, 25 May 2009 17:02:14 +0000 (UTC)
Subject: FreeBSD Маршрутизатор IPFW+NAT для начинающих
Введение
--------
Недорогим решением для малого и среднего бизнеса является использование
маршрутизаторов под управлением операционной системы FreeBSD. В статье
будет описана настройка маршрутизатора и его программного обеспечения
для реализации маршрутизации. А так же настройка и управление штатными
службами IPFW (ipfirewall) и NAT (Network Address Translation). Целью
статьи является конфигурирование маршрутизатора для небольшой
организации, основной задачей которого является обеспечение доступа в
Интернет компьютерам из локальной сети. Немаловажным принципом при
инсталляции является необходимость распределения пропускной способности
сети Интернет между компьютерами локальной сети, что бы избежать
перегрузок и снижения неработоспособности, так называемого простоя в
сети.
Общие сведения
IPFW (ipfirewall) -- это штатный фаервол, который входит в состав
операционной системы FreeBSD. Является очень надежным, функциональным и
гибко настраиваемым.
Фильтрация пакетов происходит следующих типов:
* tcp (Transmission Control Protocol -- протокол управления передачей)
* udp (User Datagram Protocol -- протокол пользовательских датаграмм)
* icmp(Internet Control Message Protocol -- межсетевой протокол управляющих сообщений)
* in и out в правилах показывают направление движение пакета.
* in - входящий пакет.
* out - исходящий.
Нужно заметить то, что определение типа пакета происходит не
относительно сетевых устройств, а относительно операционной системы.
Входящим либо исходящим может быть пакет независимо от интерфейса,
через который он проходит.
В правилах так же могут использоваться опции как recv, xmit, via.
Данные опции используются относительно сетевых интерфейсов.
* recv - означает, что интерфейс получил пакет.
* xmit - говорит о том, что пакет был передан.
* via - указывает на интерфейс. В данном случае нет значения, в каком
направлении, так как данная функция разрешает передачу, как входящих,
так и исходящих пакетов.
Рассмотрим несколько примеров:
разрешать весь входящий трафик на интерфейсе sk0.
ipfw add allow all from any to any in recv sk0
разрешать весь исходящий трафик на интерфейсе sk0.
ipfw add allow all from any to any out xmit sk0
Прошу заметить, что out xmit = out via, а in recv = in via. Два правила
описанные выше могут быть записаны следующим образом:
ipfw add allow all from any to any in via sk0
ipfw add allow all from any to any out via sk0
Далее описываются псевдонимы для опций при составлении правил.
ipfw add allow all from any to any
allow = pass = permit = accept
all = ip
Настройка ядра
По умолчанию поддержка межсетевого экрана не вкомпилирована в ядро, а
подгружается через модули. При желании можно пересобрать ядро со встроенной
поддержкой фаервола. Рассмотрим базовые директивы, определяющие функции фаервола.
options IPFIREWALL
Данная опция включает функции фаервола в операционной системе. Для
базовой работы и выполнения минимальных функций этой опции вполне
достаточно. Но если требуется большая функциональность, смотрите
функции, описанные ниже.
options IPFIREWALL_VERBOSE
Эта опция позволяет вести полную статистику пакетов, которые попадают
под данное правило. Необходимо для аналитики трафика и контроля за
безопасностью системы.
options IPFIREWALL_VERBOSE_LIMIT=50
Данная директива позволяет ввести ограничение по количеству записей в
системный журнал статистики. Цифра после знака равно указывает на
максимальную сумму записей, которые будут отмечены в системном журнале
в секунду времени.
options IPFIREWALL_FORWARD
При помощи данной опции можно реализовать прозрачный прокси-сервер, то
есть такой сервер, клиенты которого не будут нуждаться в каких-либо
настройках (указания порта и ip-адреса прокси-сервера). Пакеты будут
автоматически перенаправляться в самой системе.
options IPDIVERT
С наличием данной опции в ядре, система сможет взаимодействовать с
программами, позволяющими выполнять более сложные механизмы работы
с пакетами. Например, как Network Address Translation (NAT), который
служит для преобразования сетевых адресов.
options DUMMYNET
Данная опция позволяет посредством фаервола IPFW управлять входящим и
сходящим трафиком, ограничивая, распределяя пропускную способность
относительно сетевых интерфейсов и т.д.
options IPFIREWALL_DEFAULT_TO_ACCEPT
С такой опцией IPFW принимает значение open или allow all from any to
any. Это говорит о том, что разрешается весь входящий и исходящий
трафик от всех во всех направлениях.
Если данная опция не включена в состав ядра, то по умолчанию фаервол
примет значение CLOSE или deny all from any to any
Для сборки собственного ядра системы необходимо установить
системные фалы и папки директории /usr/src/
Отредактировать следующий файл, внеся все необходимые изменения
/usr/src/sys/i386/conf/GENERIC
Перейти в каталог /usr/src и выполнить команду
make kernel
IPFW и преобразователь сетевых адресов NAT
NAT (Network Address Translation -- "преобразование сетевых
адресов"). Так же можно встретить и названия, как IP Masquerading,
Network Masquerading и Native Address Translation. Проще говоря, NAT
служит для преобразования пакетов, которые исходят от компьютеров
внутренней локальной сети таким образом, что в итоге получается, что
пакеты исходят от самого сервера.
В следующем примере будет описано взаимодействие NAT с IPFW в случае,
когда из локальной сети с адресом 192.168.0.10 отправляется запрос на
ресурс example.com с ip-адресом 123.123.123.123. Внешний сетевой
интерфейс -- sk1, а внутренний -- sk0. Внешний адрес роутера --
111.111.111.111.
1. ipfw add divert natd ip from 192.168.0.10 to 123.123.123.123 out via sk1
2. ipfw add divert natd ip from 123.123.123.123 to 111.111.111.111 in via sk1
3. ipfw add allow all from 111.111.111.111 to 123.123.123.123 out via sk1
4. ipfw add allow all from 123.123.123.123 to 111.111.111.111 in via sk1
5. ipfw add allow all from 192.168.0.10 to 123.123.123.123 out via sk1
6. ipfw add allow all from 192.168.0.10 to 123.123.123.123 in via sk0
7. ipfw add allow all from 123.123.123.123 to 192.168.0.10 in via sk1
8. ipfw add allow all from 123.123.123.123 to 192.168.0.10 out via sk0
Компьютер из локальной сети запрашивает ресурс в Интернете example.com
с ip-адресом 123.123.123.123. Правило 6.
ipfw add allow all from 192.168.0.10 to 123.123.123.123 in via sk0
По таблице маршрутизации роутера пакет отправляется на внешний
интрефейс sk1. Правило No. 5.
ipfw add allow all from 192.168.0.10 to 123.123.123.123 out via sk1
Далее начинает работать с NAT, преобразуя пакет, словно он уходит от
самого сервера. Правило No. 1.
ipfw add divert natd ip from 192.168.0.10 to 123.123.123.123 out via sk1
После того как NAT выполнил свою работу необходимо разрешить пакету
отправиться от самого сервера (с внешнего интерфейса). Правило No. 3.
ipfw add allow all from 111.111.111.111 to 123.123.123.123 out via sk1
Преобразованный пакет успешно отправлен от компьютера в локальной сети
с ip-адресом 192.168.0.10 к ресурсу example.com с ip-адресом
123.123.123.123.
Как видим, что для отправки пакетов используются правила 6, 5,1 и 3.
Далее рассмотрим схему получения пакета роутером от ресурса example.com
с последующим перенаправлением к компьютеру в локальной сети.
Когда example.com (123.123.123.123) успешно принял пакет, отправляет
ответ. Правило No. 4.
ipfw add allow all from 123.123.123.123 to 111.111.111.111 in via sk1
Далее работает NAT. Он преобразует входящий пакет от example.com
(123.123.123.123) к роутеру 111.111.111.111. Правило No. 2.
ipfw add divert natd ip from 123.123.123.123 to 111.111.111.111 in via sk1
Затем следует правило, которое позволяет принимать пакеты от
example.com к компьютеру локальной сети на внешнем интерфейсе. Правило 7.
ipfw add allow all from 123.123.123.123 to 192.168.0.10 in via sk1
После всего роутер направляет все пакеты с example.com к компьютеру в
локальной сети. Правило No. 8
ipfw add allow all from 123.123.123.123 to 192.168.0.10 out via sk0
Как видим, для отправки пакета использовались правила 6, 5, 1 и 3
А для приёма правила 4, 2, 7 и 8.
ipfw add divert natd ip from 192.168.0.10 to 123.123.123.123 out via sk1
ipfw add divert natd ip from 123.123.123.123 to 111.111.111.111 in via sk1
ipfw add allow all from 111.111.111.111 to 123.123.123.123 out via sk1
ipfw add allow all from 123.123.123.123 to 111.111.111.111 in via sk1
ipfw add allow all from 192.168.0.10 to 123.123.123.123 out via sk1
ipfw add allow all from 192.168.0.10 to 123.123.123.123 in via sk0
ipfw add allow all from 123.123.123.123 to 192.168.0.10 in via sk1
ipfw add allow all from 123.123.123.123 to 192.168.0.10 out via sk0
192.168.0.10 - компьютер в локальной сети.
111.111.111.111 - внешний ip-адрес роутера.
123.123.123.123 - example.com использовался для примера ресурса в сети Интернет.
sk1 - внешний интерфейс.
sk0 - внутренний сетевой интерфейс.
В примере показан простой вариант использования IPFW, когда нет
необходимости в разделении пропускной способности.
Где rl0 - внутренний интерфейс, который смотрит в локальную сеть; rl1 -
внешний сетевой интерфейс, который смотрит в мир; локальная сеть имеет
диапазон адресов от 192.168.0.1 до 192.168.0.255. Внутренний адрес
роутера, будет, к примеру, 192.168.0.1, а внешний 123.123.123.123
ipfw -f flush
ipfw -f pipe flush
ipfw -f queue flush
ipfw add allow ip from any to any via lo0
ipfw add allow ip from 192.168.0.0/24 to 192.168.0.0/24 via rl0
ipfw add divert natd ip from 192.168.0.0/24 to any out via rl1
ipfw add divert natd ip from any to 123.123.123.123 in via rl1
ipfw add allow all from any to 123.123.123.123 in via rl1
ipfw add allow all from 123.123.123.123 to any out via rl1
ipfw add allow all from 192.168.0.0/24 to any in via rl0
ipfw add allow all from any to 192.168.0.0/24 in via rl1
ipfw add allow all from any to 192.168.0.0/24 out via rl0
ipfw add deny log ip from any to any
Использование IPFW для распределения пропускной способности сети
После установки и настройки маршрутизатора необходимо разделить
пропускную способность сети интернет между компьютерами внутренней
локальной сети. Необходимо это для того, что бы обеспечить лучшую
работоспособность и использовать сеть интернет с большей
эффективностью. Примером будет служить локальная сеть из 8 компьютеров,
между которыми будет распределен 1 мегабит в секунду пропускной
способности внешней линии. Для этого внесём определённые исправления в
набор команд описанные выше, только вместо команд:
ipfw add allow all from 192.168.0.0/24 to any in via rl0
ipfw add allow all from any to 192.168.0.0/24 in via rl1
ipfw add allow all from any to 192.168.0.0/24 out via rl0
Будут внесены ip-адреса и указана пропускная способность:
ipfw add pipe 1 all from 192.168.0.2 to any in via rl0
ipfw pipe 1 config bw 64K queue 32K
ipfw add pipe 2 all from 192.168.0.3 to any in via rl0
ipfw pipe 2 config bw 64K queue 32K
ipfw add pipe 3 all from 192.168.0.4 to any in via rl0
ipfw pipe 3 config bw 64K queue 32K
ipfw add pipe 4 all from 192.168.0.5 to any in via rl0
ipfw pipe 4 config bw 64K queue 32K
ipfw add pipe 5 all from 192.168.0.6 to any in via rl0
ipfw pipe 5 config bw 64K queue 32K
ipfw add pipe 6 all from 192.168.0.7 to any in via rl0
ipfw pipe 6 config bw 64K queue 32K
ipfw add pipe 7 all from 192.168.0.8 to any in via rl0
ipfw pipe 7 config bw 64K queue 32K
ipfw add pipe 8 all from 192.168.0.9 to any in via rl0
ipfw pipe 8 config bw 64K queue 32K
В данном случае указывается ip-адрес компьютера из локальной сети,
пропускная способность и размер очереди равной 32 килобайтам. Так же
следует заметить, что этот набор команд ограничивает скорость входящего
трафика на внутренний интерфейс маршрутизатора до 64 Кб/с, что
определяет скорость передачи данных от клиента в интернет - upload
speed.
Скорость загрузки (download speed) будет определена следующим набором
команд:
ipfw add pipe 9 all from any to 192.168.0.2 out via rl0
ipfw pipe 9 config bw 64K queue 32K
ipfw add pipe 10 all from any to 192.168.0.3 out via rl0
ipfw pipe 10 config bw 64K queue 32K
ipfw add pipe 11 all from any to 192.168.0.4 out via rl0
ipfw pipe 11 config bw 64K queue 32K
ipfw add pipe 12 all from any to 192.168.0.5 out via rl0
ipfw pipe 12 config bw 64K queue 32K
ipfw add pipe 13 all from any to 192.168.0.6 out via rl0
ipfw pipe 13 config bw 64K queue 32K
ipfw add pipe 14 all from any to 192.168.0.7 out via rl0
ipfw pipe 14 config bw 64K queue 32K
ipfw add pipe 15 all from any to 192.168.0.8 out via rl0
ipfw pipe 15 config bw 64K queue 32K
ipfw add pipe 16 all from any to 192.168.0.9 out via rl0
ipfw pipe 16 config bw 64K queue 32K
Так же не забываем про правило:
ipfw add allow all from any to 192.168.0.0/24 in via rl1
Можно конечно было все правила заменить следующими командами:
ipfw add pipe 1 all from 192.168.0.0/24 to any in via rl0
ipfw pipe 1 config bw 64K queue 32K
ipfw add allow all from any to 192.168.0.0/24 in via rl1
ipfw add pipe 2 all from any to 192.168.0.0/24 out via rl0
ipfw pipe 2 config bw 64K queue 32K
Но подробный пример был описан для удобства дальнейшего
администрирования и назначения пропускной способности различной
величины.
Конечным результатом является возможность хоть и медленной, но
стабильной работы всех компьютеров локальной сети. Стоит так же
заметить, что в случае, когда все компьютеры одновременно будут
отправлять и принимать информацию, перегрузок не возникнет, и все
клиенты будут иметь доступ в интернет.
В итоге имеем следующий набор команд:
ipfw -f pipe flush
ipfw -f queue flush
ipfw add allow ip from any to any via lo0
ipfw add allow ip from 192.168.0.0/24 to 192.168.0.0/24 via rl0
ipfw add divert natd ip from 192.168.0.0/24 to any out via rl1
ipfw add divert natd ip from any to 123.123.123.123 in via rl1
ipfw add allow all from any to 123.123.123.123 in via rl1
ipfw add allow all from 123.123.123.123 to any out via rl1
ipfw add pipe 1 all from 192.168.0.2 to any in via rl0
ipfw pipe 1 config bw 64K queue 32K
ipfw add pipe 2 all from 192.168.0.3 to any in via rl0
ipfw pipe 2 config bw 64K queue 32K
ipfw add pipe 3 all from 192.168.0.4 to any in via rl0
ipfw pipe 3 config bw 64K queue 32K
ipfw add pipe 4 all from 192.168.0.5 to any in via rl0
ipfw pipe 4 config bw 64K queue 32K
ipfw add pipe 5 all from 192.168.0.6 to any in via rl0
ipfw pipe 5 config bw 64K queue 32K
ipfw add pipe 6 all from 192.168.0.7 to any in via rl0
ipfw pipe 6 config bw 64K queue 32K
ipfw add pipe 7 all from 192.168.0.8 to any in via rl0
ipfw pipe 7 config bw 64K queue 32K
ipfw add pipe 8 all from 192.168.0.9 to any in via rl0
ipfw pipe 8 config bw 64K queue 32K
ipfw add allow all from any to 192.168.0.0/24 in via rl1
ipfw add pipe 9 all from any to 192.168.0.2 out via rl0
ipfw pipe 9 config bw 64K queue 32K
ipfw add pipe 10 all from any to 192.168.0.3 out via rl0
ipfw pipe 10 config bw 64K queue 32K
ipfw add pipe 11 all from any to 192.168.0.4 out via rl0
ipfw pipe 11 config bw 64K queue 32K
ipfw add pipe 12 all from any to 192.168.0.5 out via rl0
ipfw pipe 12 config bw 64K queue 32K
ipfw add pipe 13 all from any to 192.168.0.6 out via rl0
ipfw pipe 13 config bw 64K queue 32K
ipfw add pipe 14 all from any to 192.168.0.7 out via rl0
ipfw pipe 14 config bw 64K queue 32K
ipfw add pipe 15 all from any to 192.168.0.8 out via rl0
ipfw pipe 15 config bw 64K queue 32K
ipfw add pipe 16 all from any to 192.168.0.9 out via rl0
ipfw pipe 16 config bw 64K queue 32K
ipfw add deny log ip from any to any
Где rl0 - внутренний интерфейс, который смотрит в локальную сеть; rl1 -
внешний сетевой интерфейс, который смотрит в мир; локальная сеть имеет
диапазон адресов от 192.168.0.1 до 192.168.0.255. Внутренний адрес
роутера, будет, к примеру, 192.168.0.1, а внешний 123.123.123.123
Дополнительная информация
В /etc/rc.conf нужно внести следующие опции для работы ipfw и nat:
Запускает службу NAT при загрузке системы:
natd_enable="YES"
Указывает внешний интерфейс маршрутизатора, на котором происходят
операции NAT:
natd_interface="rl1"
Кофигурационный файл NAT:
natd_flags="-f /etc/natd.conf"
Запуск службы IPFW при старте системы:
firewall_enable="YES"
Скрипт с правилами фаервола:
firewall_script="/etc/script.sh"
Загружаем модуль ядра для работы ограничения трафика:
Для перенаправления входящего трафика с внешнего интерфейса во
внутреннюю сеть можно внести следующие опции в конфигурационном файле
/etc/natd.conf : redirect_port tcp (ip-адрес внутреннего
компьютера):(порт приложения) (внешний порт маршрутизатора).
Например, настройка доступа из внешней сети к внутреннему компьютеру,
на котором установлено приложение VNC: