Примеры из жизни

Подробнее о настройке маршрутизации с использованием ipfw смотрите в разделе Policy-Based Routing (PBR).

а также Пример настройки сервера FreeBSD с NAT

ipfw add deny tcp from cracker.evil.org to wolf.kiev.ua telnet
С помощью данной конструкции можно запретить соединение по протоколу telnet (порт 23) с хоста evilhost.org на хост baby.ua
ipfw add reject tcp from any to 192.168.168.0/26 out
ipfw add reject tcp from 192.168.168.0/26 to me in
Данное правило отвергает все входящие соединения с компьютеров, имеющих IP-адреса 192.168.168.1 по 192.168.168.254 При этом выдается соответствующее ICMP-сообщение.
ipfw add allow tcp from 10.10.10.0/24 to any via fxp1 setup limit src-addr 10
ipfw add allow tcp from any to me limit src-addr 4
Данное правило ограничивает число соединений, которое может быть открыто пользователем. Брандмауэр (предполагается, что он запущен на шлюзе) разрешает каждому хосту в сети 10.10.10.0/24 открыть максимум 10 соединений. Кроме того, брандмауэр может может быть настроен на сервер так, чтобы убедиться, что один клиентский компьютер совершает не более четырех одновременных соединений.

ВНИМАНИЕ: Такое правило может быть использовано для атак типа DoS (отказ в обслуживании) путем "SYN-затопления", которое открывает огромное число динамических правил. Ущерб от таких атак может быть значительно ограничен путем варьирования установок переменно sysctl, которые контролируют действие брандмауэра.
ipfw add pipe 31 ip from any to 192.168.0.9 out via fxp1
ipfw pipe 31 config 31 bw 64Kbit/s
Это правило вводит ограничение скорости для хоста 192,168.0.9. Скорость ограничивается 64Кбит/с
ipfw add pipe 101 ip from any to 192.168.168.0:255.255.255.246 via ed0
ipfw pipe config 101 delay 100ms plr 0.75
Это правило может быть полезно для "проштрафившихся" пользователей, например, которые не оплачивают работу долгое время. Работать-то можно, но теряется большая часть пакетов (75%) и задержка оставшихся составляет 100 мс, следовательно, страницы будут открываться очень медленно.
ipfw add pipe 1025 tcp from me to any 25 out via fxp0
ipfw pipe 1025 config bw 128Kbit/s delay 120ms
В данном примере скорость ограничивается значением 128Кбит/с, но при этом задержка каждого пакета составляет 120 мс.
ipfw add pipe 23 ip from any to 192.168.0.87 out
ipfw add pipe 24 ip from 192.168.0.87 to any in
ipfw pipe 23 config 57600bit/s
ipfw pipe 24 config 33600bit/s
Эмуляция полнодуплексного канала, более похожая на работу по протоколу V.90. Здесь трафик имеет асимметричных характер: относительно пользователя 192.168.0.87 трафик имеет асимметричный характер - скорость входящего трафика 57600 бит/с, а скорость исходящего трафика - 33600 бит/с.
ipfw add pipe 6 ip from any to 192.168.0.100 out via ed0
ipfw add pipe 6 ip from 192.168.0.100 to any in via ed0
А это эмуляция полудуплексного канала.
ipfw add prob 0.33 pipe 1 ip from A to B
ipfw add prob 0.5 pipe 2 ip from A to B
ipfw add           pipe 3 ip from A to B
ipfw pipe 1 config ...
ipfw pipe 2 comfig ...
ipfw pipe 3 config ...
Одной из положительных особенностей новой версии dummynet является способность имитировать множество путей между отправителем и получателем. Это делается с использованием вероятностей величины prob. При условии, что пакет является правильным (т. е. он циркулирует от хоста А к хосту В), первое правило будет выполняться с вероятностью 1/3; в оставшихся 2/3 случаях будет происходить переход ко 2-му правилу, которое будет выполняться с вероятностью 1/2 (0.5) (так что 1/2*2/3=1/3); в оставшихся 1/3 случаев будет происходить переход к третьему правилу, которое имеет вероятность 1. Мы можем конфигурировать эти 3 канала по желанию, чтобы эмулировать, например, такие явления, как повторный запрос пакета и т. д.
ipfw add queue 16 tcp  from any to 192.168.0.110 out via ed0
ipfw add queue 17 tcp from 192.168.0.110 to any in via ed0
ipfw queue 16 config weight 10 pipe 160
ipfw queue 17 config weight 7  pipe 160
ipfw pipe 160 config bw
128Kbit/s
Несколько более сложный пример эмуляции полудуплексного канала, когда трафик, направляемый компьютеру с адресом 192.168.0.110 имеет более высокий приоритет, чем получаемый от него. Это может иметь смысл, чтобы, например, отправляемая почта больших размеров не мешала ходить по сайтам.



Для приоретизации трафика можно применять следующую конструкцию.
ipfw add queue 10 tcp from any 20,21 to any 1024-65535 in via fxp0
ipfw add queue 20 tcp from any 1024-65535 to any 20,21 out via fxp0
ipfw add queue 10 tcp from any 1024-65535 to any 1024-65535 in via fxp0
ipfw add queue 10 tcp from any 1024-65535 to any 1024-65535 out via fxp0
ipfw queue 10 config weight 1 pipe 10
ipfw queue 20 config weight 1 pipe 20
ssh
ipfw add queue 50 tcp from any 22 to any 1024-65535 in via fxp0
ipfw add queue 60 tcp from any 1024-65535 to any 22 out via fxp0
ipfw queue 50 config pipe 10 weight 100
ipfw queue 60 config pipe 20 weight 100
pipes
ipfw add pipe 10 tcp from any to any in via fxp0
ipfw pipe 10 config
ipfw add pipe 20 tcp from any to any out via fxp0
ipfw pipe 20 config
all traffic (весь остальной трафик).
ipfw add check-state
ipfw deny tcp from any to any established
ipfw allow tcp from 192.168.0.0/24 to any setup keep-state
Это пример динамического правила.

При помощи конструкции probe можно использовать разделение трафика по двум различным каналам. Например:
ipfw add prob 0.34 forward 212.1.1.254 ip from 212.1.2.0/24 to any
Здесь часть пакетов (примерно 34%), поступающих из сети 212.1.2.0:255.255.255.0, будет перенаправлено на "альтернативный" шлюз - хост 212.1.1.254.

Policy-Based Routing (PBR) в ОС FreeBS

Когда возникает необходимость в PBR?

В сегодняшних компьютерных сетях высокой производительности, возникает необходимость в выполнении пересылки пакетов соответственно определенной политике (правилу или набору правил), которая, в некотором отношении, выходит за границы традиционных принципов работы протоколов маршрутизации. PBR используется там, где, в силу различных обстоятельств, необходимо дифференцировать трафик по какому-либо признаку, и выбирать различный дальнейший маршрут для каждого случая отдельно. Классическим решением работы по двум и более каналам является регистрация автономной системы (AS) и получения сети независимых адресов. Затем по одному из протоколов внешнего шлюза - BGP или EGP - строятся маршруты прохождения трафика через один или другой канал. Однако регистрация AS и получение независимой сети адресов - дело дорогое и достаточно сложное, причем для орагнизации подключения корпоративной сети не всегда оправдано.

Достоинства PBR

  • Bыбор маршрута, основанный на источнике - позволяет пропускать трафик, приходящий из различных мест, через разные каналы подключения к Интернет
  • Эффективное использование имеющихся каналов подключения к Интернет
  • Расширение возможностей динамической маршрутизации
  • Что такое PBR?

    PBR предоставляет механизм реализации пересылки (forwarding)/ маршрутизации (routing) пакетов данных, основанный на политике, представляющей собой набор правил, определенной администраторами сети. Это предоставляет более гибкий механизм для обработки пакетов на маршрутизаторах, дополняя существующий механизм, предоставленный протоколами маршрутизации.

    Маршрутизаторы выбирают дальнейший путь следования пакетов данных по полю "адрес назначения", основываясь на информации из таблицы статических маршрутов или полученной от динамических протоколов маршрутизации, как, например Routing Information Protocol (RIP), Open Shortest Path First (OSPF), или Enhanced Interior Gateway Routing Protocol (Enhanced IGRP). Вместо выбора дальнейшего маршрута, основанного на адресе назначения, PBR позволяет администраторам сети определить свои правила, по которым будет осуществляться маршрутизация пакетов.

    Сфера применения.

    Наиболее часто на практике PBR используется в ситуации, которая представлена на рисунке. Т. е. когда какая-либо организация имеет 2 или более канала подключения к Интернет. В стандартном случае один канал является основным (через него организация выходит в Интернет), а второй - вспомогательным (он подключается, когда неисправен первый канал, в остальное время обычно используется для доступа к локальным ресурсам одного из провайдеров, т.е. mp3, video и т.д.). При таком варианте эффективность использования двух каналов чрезвычайно низка. Конечно, и такой вариант имеет право на существование, но рано или поздно перед развивающейся организацией появляется задача более эффективного использования имеющихся каналов подключения к Интернет или, возможно, разделения этих каналов между своими отделами (например, отдел производства будет использовать канал на ISP1, а отдел маркетинга - канал на ISP2). Именно в этом случае на помощь приходит policy-based routing.

    Практическая реализация в ОС FreeBSD

    В ОС FreeBSD policy-based routing осуществляется с помощью механизма ip forwarding и пакетного фильтра ipfw. Чтобы включить возможность пакетной фильтрации в ОС FreeBSD необходимо вставить в файл конфигурации ядра ОС следующие строки:
    options IPFIREWALL
    options	IPDIVERT
    options IPFIRWALL_FORWARD
    В результате мы активируем следующие механизмы: пакетный фильтр, NAT (сетевая трансляция адресов, позволяет разделять один канал выхода в Интернет между множеством пользователей) и механизм ip forwarding.

    Рассмотрим следующий вариант. Имеется сервер с ОС FreeBSD с двумя каналами доступа к Интернет (ISP1, ISP2) и двумя подключения локальной сети (отдел А, отдел Б).

    Примем следующую конфигурацию сетевых интерфейсов:
    rl0 - 1.1.1.1 /24(gateway 1.1.1.254 ISP1)
    rl1 - 2.2.2.2 /24(gateway 2.2.2.254 ISP2)
    rl2 - 3.3.3.3/24 (lan1, отдел А)
    rl3 - 4.4.4.4 /24(lan2, отдел Б)

    Поставим такую задачу, чтобы пользователи lan1 выходили в Интернет через первого провайдера ISP1, а пользователи lan2 - через ISP2. Заранее оговорю, что приведенные ниже примеры будут работать вне зависимости от того, какой маршрут по умолчанию (через ISP1 или ISP2) определен в настройках ОС.

    Сначала необходимо запустить NAT на интерфейсах rl0 и rl1:
    natd -a 1.1.1.1 -p 8668 
    natd -a 2.2.2.2 -p 8778 
    Создадим набор правил для ipfw:
    ipfw 10 add divert 8668 ip from 3.3.3.0/24 to any
    ipfw 20 add divert 8778 ip from 4.4.4.0/24 to any 
    ipfw 30 add fwd 1.1.1.254 ip from 1.1.1.1 to any 
    ipfw 40 add fwd 2.2.2.254 ip from 2.2.2.2 to any 
    ipfw 50 add divert 8668 ip from any to 1.1.1.1 
    ipfw 60 add divert 8778 ip from any to 2.2.2.2 
    В некоторых случаях имеется только одно подключение к локальной сети и необходимо "пропустить" через другой канал доступа к Интернет не локальную сеть, а один или несколько компьютеров. Допустим, есть только lan1 и через ISP1 в Интернет будет "выходить" компьютер с ip адресом 3.3.3.10

    Опять же запускаем NAT:
    natd -a 1.1.1.1 -p 8668
    natd -a 2.2.2.2 -p 8778
    Следующий набор правил пакетного фильтра ipfw решает эту задачу:
    ipfw 10 add divert 8668 ip from 3.3.3.10 to any 
    ipfw 20 add divert 8778 ip from any  to any 
    ipfw 30 add fwd 1.1.1.254 ip from 1.1.1.1 to any
    ipfw 40 add fwd 2.2.2.254 ip from 2.2.2.2 to any
    ipfw 50 add divert 8668 ip from any to 1.1.1.1
    ipfw 60 add divert 8778 ip from any to 2.2.2.2
    Иногда возникает и более сложная задача, когда необходимо не "жестко" разделять каналы, а когда пользователи, допустим, lan1 должны "выходить" в Интернет через ISP1, но также должны "видеть" и локальные ресурсы второго провайдера, и наоборот, пользователи lan2 "выходят" в Интернет через ISP2 и "видят" ресурсы ISP1.

    Допустим, локальные ресурсы ISP1 находятся по адресам 5.5.5.0/24, а ресурсы ISP2 -6.6.6.0/24.

    Конечно, не забываем запустить NAT:
    natd -a 1.1.1.1 -p 8668
    natd -a 2.2.2.2 -p 8778
    Для этого случая правила ipfw выглядят так:
    ipfw 10 add divert 8778 ip from 3.3.3.0/24 to 6.6.6.0/24 
    ipfw 20 add divert 8668 ip from 3.3.3.0/24 to any
    ipfw 30 add divert 8668 ip from 4.4.4.0/24 to 5.5.5.0/24
    ipfw 40 add divert 8778 ip from 4.4.4.0/24 to any
    ipfw 50 add fwd 1.1.1.254 ip from 1.1.1.1 to any
    ipfw 60 add fwd 2.2.2.254 ip from 2.2.2.2 to any
    ipfw 70 add divert 8668 ip from any to 1.1.1.1
    ipfw 80 add divert 8778 ip from any to 2.2.2.2

    Некоторые замечания

    Реализация PBR в ОС FreeBSD средствами ipfw достаточна проста. Однако в некоторых ситуациях могут возникать непредвиденные осложнения, при которых рассмотренные выше примеры окажутся неработоспособными. Это произойдет, например, если на Вашем маршрутизаторе настроен web сервер (или какой-то другой сервис), который привязан к ip адресу внешнего интерфейса. Тогда необходимо вставить перед правилами, осуществляющим policy-based routing, правила, которые разрешат пользователям осуществить доступ к внешним интерфейсам.

    Важным моментом также является порядок и нумерация правил. Очень осторожно относитесь к этим вещам. Например, если в последнем примере все правила будут иметь один и тот же номер, то ничего хорошего из этого не выйдет. Это связано с особенностями обработки правил divert. Как известно, в ipfw каждый пакет проходит цепочку правил от правил с меньшими номерами к большим номерам до совпадения параметров пакета с параметрами правила. При "попадании" пакета в правило выполняются предписанные им действия, и дальнейшее прохождение по цепочке останавливается (пакет, конечно, может еще попасть в правила пакетного фильтра, например, при прохождении его через следующий сетевой интерфейс). Но при "попадании" пакета в правила divert прохождение по цепочке не останавливается, а продолжается с правила, номер которого превышает текущее. Т.е. если правила имеют одинаковый номер, то после правил divert в правила fwd пакет не "попадет". Вообще, как ведет себя пакет после "попадания" в правила divert определяется той программой, которой он обрабатывается. В нашем случае это natd. А natd работает именно так, как описано выше.

    Если же Вы все сделали как надо, но все равно ничего не работает, то вставьте в правила параметр log. Например:
    ipfw 10 add divert 8778 log ip from 3.3.3.0/24 to 6.6.6.0/24
    или
    ipfw 50 add fwd 1.1.1.254 log ip from 1.1.1.1 to any
    Это позволит вам посмотреть в /var/log/security как "ходят" пакеты, в какие правила "попадают" (для этого необходимо включить в конфигурационном файле ядра ОС опцию IPFIREWALL_VERBOSE).

    Незаменимым инструментом при отладке также является программа tcpdump. С ее помощью Вы можете своими глазами увидеть и проверить все параметры пакетов данных, которые проходят через Ваш маршрутизатор.


    Простейший сервер доступа с NAT

    В этой главе мы попытемся превратить Ваш компьютер в простой сервер под управлением операционной системы FreeBSD и дать доступ в Internet небольшой локальной сети. Предполагается, что в Вашем компьютере установлены две сетевые карты, одна из которых имеет реальный адрес сети интернет (далее будет использоваться 193.232.100.100), вторая подключена к локальной сети, и имеет адрес 192.168.0.1. В моем компьютере первая сетевая карта - RTL 8139, вторая 3Com905. В системе FreeBSD эти сетевые карты доступны как устройства rl0 и xl0

    Подробнее о работе с FreeBSD можно узнать из "Библии FreeBSD" - handbook. FreeBSD устанавливается с ядром GENERIC, в которое (в зависимости от версии ) могут быть не включены необходимые нам функции, поэтому нам придется собрать новое ядро под наши нужды.

    Проверьте наличи следующих опций:
    options IPFIREWALL
    эта строка включит поддержку пакетного фильтра TCP/IP, который нам очень понадобится.
    options IPDIVERT
    эта строка необходима для работы демона NAT, она позволит пакетному фильтру отправлять некоторые пакеты на "переработку".

    При необходимости пересоберите ядро. Для этого, находясь в каталоге /usr/src/sys/i386/config нужно ввести следующие команды:
    config MYROUTER
    cd ../../compile/MYROUTER
    make depend
    make
    make install

    Конфигурирование.

    В файл /etc/rc.conf нужно дописать следующие строки:
    firewall_enable="YES"
    firewall_script="/usr/local/billing/rc.firewall"
    natd_enable="YES"
    natd_interface="rl0"
    gateway_enable="YES"
    Этими строчками мы укажем, что мы хотим сделать наш сервер роутером, хотим использовать NAT, и хотим использовать пакетный фильтр. В параметре firewall_script мы указываем, что при загрузке системы хотим самостоятельно сконфигурировать firewall, а значение rl0 в параметре natd_interface указывает сетевую карту, которая подключена к провайдеру (грубо говоря - c какой стороны у нас интернет подключен).

    Теперь осталось только создать скрипт, который автоматически сконфигурирует пакетный фильтр при загрузке системы. Для этого нам нужно создать исполняемый файл rc.firewall с правами 0700. В файл rc.firewall запишем:
    ipfw='/sbin/ipfw -q'
    ${ipfw} -f flush
    ${ipfw} add divert natd all from any to any via rl0
    ${ipfw} add allow all from any to any
    где rl0, как мы помним - наша внешняя сетевая карта.

    Еще раз все проверили, и можно перезагружаться... командой shutdown -r now.