- Файрвол PF в ОС FreeBSD
- FreeBSD. Фильтрация трафика PF
- FreeBSD. трансляции, тэги и якоря в PF
- FreeBSD. Условная маршрутизация средствами PF <- Вы здесь
Введение
В предыдущих статьях мы разобрали базовые элементы конфигурации PF. Создали конфигурации, способные защитить сервер в Интернет и простейший офис.
В этой статье разберем возможности PF и FreeBSD в части продвинутой маршрутизации. Policy Based Routing (PBR), Source Based Routing (SBR), условная маршрутизация, маршрутизация на основе политик, все эти понятия, по сути, равнозначны и описывают одну возможность. Выбирать маршруты, либо таблицы маршрутизации для трафика на основе правил фаервола.
Можно, к примеру, отправить разные локальные сети через разных провайдеров, либо устроить распределение трафика между ВПН каналами. Рассмотрим оба эти варианта.
Для уменьшения файлов конфигурации и большей наглядности, в этой статье правила фильтрации будут максимально упрощены.
Задачи
Возьмем офис из прошлой статьи и добавим туда второго провайдера.
- Нужно отправить трафик от одной локальной сети через одного провайдера.
- Вторую локальную сеть — через второго провайдера.
- Так же нужно пробросить веб-порты сервера через обоих провайдеров так, чтобы были доступны оба IP адреса.
В эту схему добавим второй офис, у которого так же 2 провайдера. Между офисами есть 2 туннеля.
- Нужно пустить трафик до второго офиса через ВПН1
- кроме сервера, который должен работать через ВПН2
Решим эти задачи средствами исключительно PF и отдельно — средствами множественных таблиц маршрутизации.
Получается вот такая схема окончательной настройки:
Подготовка
Конфигурации PF офисов будут практически одинаковы. Различия касаются макросов и количества локальных сетей. Конфигурация второго будет приведена в конце статьи.
######## macros section ########
ExtIf1="re0" # внешний интерфейс
ExtIf1Ip1="172.16.1.1" # Внешний IP адрес первого
ExtIf1Gw="172.16.1.254" # шлюз первого провайдера
ExtIf2="re1" # второй внешний интерфейс
ExtIf2Ip1="172.17.1.1" # Внешний IP адрес второго провайдера
ExtIf2Gw="172.17.1.254" # шлюз второго провайдера
IntIf1="em0" # локальный 1
IntIf1Ip="172.16.2.254" # IP локального 0
IntIf1Net="172.16.2.0/24"
IntIf2="em1" # локальный 2
IntIf2Ip="172.16.3.254" # IP локального 1
IntIf2Net="172.16.3.0/24"
IntSRV="172.16.3.1"
# туннели
Tun0="gif0"
Tun0Ip="10.0.0.1"
Tun0Gw="10.0.0.2"
Tun1="gif1"
Tun1Ip="10.0.1.1"
Tun1Gw="10.0.1.2"
# удалённый офис
RemoteExtIp1="172.16.1.2"
RemoteExtIp2="172.17.1.2"
RemoteSRV="172.17.2.1"
# разрешенные порты для исходящих соединений
permit_tcp_ports="22,53,80,443"
permit_udp_ports="53,123"
######## table section ########
# сети удалённого офиса
table <remote_nets> { 172.17.2.0/24 }
######## options section ########
# разрываем соединения с ответом, а не просто дропаем пакеты
set block-policy return
# пропускаем проверку на локальной петле, там фильтрация не нужна
set skip on lo0
#scrub section
# нормализация всего входящего трафика
scrub in all
#Queueing section
# в данный момент пустая
Дальше — трансляции. Так как у нас 2 провайдера, nat нужен для каждого.
#NAT для клиентов
nat pass on $ExtIf1 from { $IntIf1Net, $IntIf2Net } to any -> $ExtIf1Ip1
nat pass on $ExtIf2 from { $IntIf1Net, $IntIf2Net } to any -> $ExtIf2Ip1
Пробросы портов — http(s) и порт 2022 с каждого провайдера на порт 22 внутреннего сервера.
#Проброс на сервер
rdr on $ExtIf1 proto tcp from any to $ExtIf1Ip1 port { http, https} tag DSTNAT -> $IntSRV
rdr on $ExtIf2 proto tcp from any to $ExtIf2Ip1 port { http, https} tag DSTNAT -> $IntSRV
rdr on $ExtIf1 proto tcp from any to $ExtIf1Ip1 port { 2022 } tag DSTNAT -> $IntSRV port ssh
rdr on $ExtIf2 proto tcp from any to $ExtIf2Ip1 port { 2022 } tag DSTNAT -> $IntSRV port ssh
В прошлой статье, упоминая тэги, я писал, что они крайне удобны при трансляциях. Вот самый яркий пример. Без этого тега пришлось бы делать кучу правил для каждого интерфейса. Если же пробросов действительно много, эта куча растет бесконечно. Тэг позволит сделать по одному особому разрешающему правилу для каждого провайдера.
Маршрутизация ответных пакетов
Основная проблема работы через двух провайдеров в том, что в нашей таблице маршрутизации есть только один шлюз по умолчанию. Во FreeBSD нет метрик маршрутов, так что дефолтный маршрут действительно может быть только один. Соответственно, наш роутер попытается ответить именно с того интерфейса, куда указывает этот маршрут. То есть, получили пакет на re1 и отправили с re0 ответ. Так работать не будет.
Решается вопрос очень легко. У правила pass в PF есть опция reply-to (Interface [Gateway]), которая указывает, куда отправить ответный пакет. Все опции маршрутизации лучше указывать на входящих правилах.
Как это работает:
- Приходит первый пакет, проходит по правилу.
- PF создаёт стейт, соединение, по которому пакеты пойдут как в одну, так и в другую сторону.
- Пакет отправляется по адресу. На него приходит ответ.
- И вот этот ответ маршрутизируется туда, куда указано в опции reply-to.
Разрешающие правила из Интернет.
pass in quick on $ExtIf1 proto tcp to { $ExtIf1Ip1 } port 22
И для второго интерфейса:
pass in quick on $ExtIf2 reply-to ( $ExtIf2 $ExtIf2Gw ) proto tcp to { $ExtIf2Ip1 } port 22
Этого достаточно, чтобы полученные на 22 порту со второго провайдера соединения работали.
Добавим icmp
pass in quick on $ExtIf1 proto icmp
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) proto icmp
И разрешения для проброшенных портов, тэг позволит обойтись минимальным количеством правил для любого количества проброшенных портов:
pass in quick on $ExtIf1 tagged DSTNAT
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) tagged DSTNAT
Теперь разрешения ходить к нам со второго филиала:
pass in quick on $ExtIf1 from $RemoteExtIp1 tag PASS
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) from $RemoteExtIp2 tag PASS
Этого достаточно, чтобы входящие сессии строились симметрично. Ответный пакет будет всегда отправлен через тот же интерфейс, через который получен первый пакет сессии.
Маршрутизация средствами PF
Нам нужно отправить трафик от первой локальной сети через первого провайдера, а от второй через второго. Для этого у правила pass есть опция route-to (Interface [Gateway]). Указывает, куда отправлять трафик, прошедший по этому правилу.
Правило, для маршрутизации к серверу через второй туннель:
pass in quick on $IntIf1 route-to ( $Tun1 $Tun1Gw ) from ($IntIf1:network) to $RemoteSRV tag PASS
pass in quick on $IntIf2 route-to ( $Tun1 $Tun1Gw ) from ($IntIf2:network) to $RemoteSRV tag PASS
Разрешаем ходить в Интернет первой сети:
pass in on $IntIf1 from { ($IntIf1:network) } tag PASS
И второй, указывая, что нужно пойти через второго провайдера:
pass in quick on $IntIf2 route-to ( $ExtIf2 $ExtIf2Gw ) from { $IntIf2Net}
Если есть необходимость, можно сменить шлюз на выходе из интерфейса правилом такого вида:
pass out quick on $ExtIf1 route-to ($ExtIf1 $ExtIf1SomeOtherGw) proto tcp from $ExtIf1 to $SomeServer port 80
Маршрутизация средствами PF — очень гибкий инструмент. Однако, следует использовать его осторожно, потому что легко запутаться: куда, что и зачем идет. Правила следует аккуратно оптимизировать во избежание "распухания" конфигурационного файла. Также нужно заботиться о правильной последовательности правил, что обычно для любого фаервола.
######## macros section ########
ExtIf1="re0" # внешний интерфейс
ExtIf1Ip1="172.16.1.1" # Внешний IP адрес первого
ExtIf1Gw="172.16.1.254" # шлюз первого провайдера
ExtIf2="re1" # второй внешний интерфейс
ExtIf2Ip1="172.17.1.1" # Внешний IP адрес второго провайдера
ExtIf2Gw="172.17.1.254" # шлюз второго провайдера
IntIf1="em0" # локальный 1
IntIf1Ip="172.16.2.254" # IP локального 0
IntIf1Net="172.16.2.0/24"
IntIf2="em1" # локальный 2
IntIf2Ip="172.16.3.254" # IP локального 1
IntIf2Net="172.16.3.0/24"
IntSRV="172.16.3.1"
# туннели
Tun0="gif0"
Tun0Ip="10.0.0.1"
Tun0Gw="10.0.0.2"
Tun1="gif1"
Tun1Ip="10.0.1.1"
Tun1Gw="10.0.1.2"
# удалённый офис
RemoteExtIp1="172.16.1.2"
RemoteExtIp2="172.17.1.2"
RemoteSRV="172.17.2.1"
# разрешенные порты для исходящих соединений
permit_tcp_ports="22,53,80,443"
permit_udp_ports="53,123"
######## table section ########
# сети удалённого офиса
table <remote_nets> { 172.17.2.0/24 }
######## options section ########
# разрываем соединения с ответом, а не просто дропаем пакеты
set block-policy return
# пропускаем проверку на локальной петле, там фильтрация не нужна
set skip on lo0
#scrub section
# нормализация всего входящего трафика
scrub in all
#Queueing section
# в данный момент пустая
######## nat section ########
#NAT для клиентов
nat pass on $ExtIf1 from { $IntIf1Net, $IntIf2Net } to any -> $ExtIf1Ip1
nat pass on $ExtIf2 from { $IntIf1Net, $IntIf2Net } to any -> $ExtIf2Ip1
#Проброс на сервер
rdr on $ExtIf1 proto tcp from any to $ExtIf1Ip1 port { http, https} tag DSTNAT -> $IntSRV
rdr on $ExtIf2 proto tcp from any to $ExtIf2Ip1 port { http, https} tag DSTNAT -> $IntSRV
rdr on $ExtIf1 proto tcp from any to $ExtIf1Ip1 port { 2022 } tag DSTNAT -> $IntSRV port ssh
rdr on $ExtIf2 proto tcp from any to $ExtIf2Ip1 port { 2022 } tag DSTNAT -> $IntSRV port ssh
######## filtering section ########
# запрет всего по умолчанию, помним, что это не означает окончание обработки пакета.
block log all
## Разрешения для входящих пакетов из Интернет. ##
# разрешаем ssh и icmp
pass in quick on $ExtIf1 proto tcp to { $ExtIf1Ip1 } port 22
pass in quick on $ExtIf2 reply-to ( $ExtIf2 $ExtIf2Gw ) proto tcp to { $ExtIf2Ip1 } port 22
pass in quick on $ExtIf1 proto icmp
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) proto icmp
pass in quick on $ExtIf1 tagged DSTNAT
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) tagged DSTNAT
# разрешаем всё с нашего второго филиала
pass in quick on $ExtIf1 from $RemoteExtIp1 tag PASS
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) from $RemoteExtIp2 tag PASS
## Разрешения для внутренних сетей ##
# маршрутизируем трафик на удалённый сервер
pass in quick on $IntIf1 route-to ( $Tun1 $Tun1Gw ) from ($IntIf1:network) to $RemoteSRV tag PASS
pass in quick on $IntIf2 route-to ( $Tun1 $Tun1Gw ) from ($IntIf2:network) to $RemoteSRV tag PASS
# разрешаем ходить в удалённую сеть
pass in quick on $IntIf1 from $IntIf1Net to <remote_nets> tag PASS
pass in quick on $IntIf2 from { $IntIf2Net } to <remote_nets> tag PASS
# разрешаем ходить в интернет первой сети
pass in quick on $IntIf1 from { ($IntIf1:network) } tag PASS
# разрешаем ходить в интернет и маршрутизируем через второго провайдера вторую сеть
pass in quick on $IntIf2 route-to ( $ExtIf2 $ExtIf2Gw ) from { $IntIf2Net }
## И для туннелей ##
pass in quick on $Tun0 from <remote_nets> tag PASS
pass in quick on $Tun1 reply-to ( $Tun1 $Tun1Gw) from <remote_nets> tag PASS
## разрешаем исходящий трафик ##
pass out on { $IntIf1,$IntIf2 }
pass out quick on { $ExtIf1, $ExtIf2, gif0, gif1 } proto tcp to any port { $permit_tcp_ports }
pass out quick on { $ExtIf1, $ExtIf2, gif0, gif1 } proto udp to any port { $permit_udp_ports }
pass out quick on { $ExtIf1, $ExtIf2, gif0, gif1 } proto icmp
pass out tagged DSTNAT
pass out tagged PASS
Альтернативные таблицы маршрутизации
Для упрощения правил фаервола в ОС FreeBSD можно использовать multiple routing tables. Для включения дополнительных таблиц достаточно в /etc/loader.conf прописать строку
net.fibs=2
И перезагрузить сервер. Это число таблиц маршрутизации. Максимально — 16.
После этого, пользуясь утилитой setfib можно запускать приложения в контексте соответствующей таблицы.
Основная таблица маршрутизации системы — нулевая
# netstat -4 -rn
# setfib 0 netstat -4 -rn
Команды равнозначны. Основная таблица (лишние строки удалены):
Routing tables
Internet:
Destination Gateway Flags Netif Expire
default 172.16.1.254 UGS re0
10.0.0.2 link#7 UH gif0
10.0.1.2 link#8 UH gif1
127.0.0.1 link#5 UH lo0
172.16.1.0/24 link#1 U re0
172.16.2.0/24 link#2 U em0
172.16.3.0/24 link#3 U em1
172.17.1.0/24 link#4 U re1
172.17.2.0/24 10.0.0.2 UGS gif0
Для запуска утилиты в контексте другой таблицы используется setfib с нужным номером :
# setfib 1 netstat -4 -rn
Альтернативная таблица маршрутизации будет выглядеть вот так:
Routing tables (fib: 1)
Internet:
Destination Gateway Flags Netif Expire
default 172.17.1.254 UGS re1
10.0.0.2 link#7 UH gif0
10.0.1.2 link#8 UH gif1
127.0.0.1 link#5 UH lo0
172.16.1.0/24 link#1 U re0
172.16.2.0/24 link#2 U em0
172.16.3.0/24 link#3 U em1
172.17.1.0/24 link#4 U re1
172.17.2.0/24 10.0.1.2 UGS gif1
Маршрут по умолчанию через второго провайдера, маршрут до удалённой сети через второй туннель.
Для маршрутизации по нужной таблице нужно в правиле PF указать её номер опцией rtable:
pass in quick on $IntIf1 from ($IntIf1:network) to $RemoteSRV rtable 1 tag PASS
pass in quick on $IntIf2 from ($IntIf2:network) to $RemoteSRV rtable 1 tag PASS
pass in quick on $IntIf2 from { $IntIf2Net } rtable 1 tag PASS
######## macros section ########
ExtIf1="re0" # внешний интерфейс
ExtIf1Ip1="172.16.1.1" # Внешний IP адрес первого
ExtIf1Gw="172.16.1.254" # шлюз первого провайдера
ExtIf2="re1" # второй внешний интерфейс
ExtIf2Ip1="172.17.1.1" # Внешний IP адрес второго провайдера
ExtIf2Gw="172.17.1.254" # шлюз второго провайдера
IntIf1="em0" # локальный 1
IntIf1Ip="172.16.2.254" # IP локального 0
IntIf1Net="172.16.2.0/24"
IntIf2="em1" # локальный 2
IntIf2Ip="172.16.3.254" # IP локального 1
IntIf2Net="172.16.3.0/24"
IntSRV="172.16.3.1"
# туннели
Tun0="gif0"
Tun0Ip="10.0.0.1"
Tun0Gw="10.0.0.2"
Tun1="gif1"
Tun1Ip="10.0.1.1"
Tun1Gw="10.0.1.2"
# удалённый офис
RemoteExtIp1="172.16.1.2"
RemoteExtIp2="172.17.1.2"
RemoteSRV="172.17.2.1"
# разрешенные порты для исходящих соединений
permit_tcp_ports="22,53,80,443"
permit_udp_ports="53,123"
######## table section ########
# сети удалённого офиса
table <remote_nets> { 172.17.2.0/24 }
######## options section ########
# разрываем соединения с ответом, а не просто дропаем пакеты
set block-policy return
# пропускаем проверку на локальной петле, там фильтрация не нужна
set skip on lo0
#scrub section
# нормализация всего входящего трафика
scrub in all
#Queueing section
# в данный момент пустая
######## nat section ########
#NAT для клиентов
nat pass on $ExtIf1 from { $IntIf1Net, $IntIf2Net } to any -> $ExtIf1Ip1
nat pass on $ExtIf2 from { $IntIf1Net, $IntIf2Net } to any -> $ExtIf2Ip1
#Проброс на сервер
rdr on $ExtIf1 proto tcp from any to $ExtIf1Ip1 port { http, https} tag DSTNAT -> $IntSRV
rdr on $ExtIf2 proto tcp from any to $ExtIf2Ip1 port { http, https} tag DSTNAT -> $IntSRV
rdr on $ExtIf1 proto tcp from any to $ExtIf1Ip1 port { 2022 } tag DSTNAT -> $IntSRV port ssh
rdr on $ExtIf2 proto tcp from any to $ExtIf2Ip1 port { 2022 } tag DSTNAT -> $IntSRV port ssh
######## filtering section ########
# запрет всего по умолчанию, помним, что это не означает окончание обработки пакета.
block log all
## Разрешения для входящих пакетов из Интернет. ##
pass in quick from 192.168.11.0/24 tag PASS
# разрешаем ssh и icmp
pass in quick on $ExtIf1 proto tcp to { $ExtIf1Ip1 } port 22
pass in quick on $ExtIf2 reply-to ( $ExtIf2 $ExtIf2Gw ) proto tcp to { $ExtIf2Ip1 } port 22
pass in quick on $ExtIf1 proto icmp
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) proto icmp
pass in quick on $ExtIf1 tagged DSTNAT
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) tagged DSTNAT
# разрешаем всё с нашего второго филиала
pass in quick on $ExtIf1 from $RemoteExtIp1 tag PASS
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) from $RemoteExtIp2 tag PASS
## Разрешения для внутренних сетей ##
# маршрутизируем трафик на удалённый сервер
pass in quick on $IntIf1 from ($IntIf1:network) to $RemoteSRV rtable 1 tag PASS
pass in quick on $IntIf2 from ($IntIf2:network) to $RemoteSRV rtable 1 tag PASS
# разрешаем ходить в удалённую сеть
pass in quick on $IntIf1 from $IntIf1Net to <remote_nets> tag PASS
pass in quick on $IntIf2 from $IntIf2Net to <remote_nets> tag PASS
pass in quick on $IntIf1 from { ($IntIf1:network) } tag PASS
pass in quick on $IntIf2 from { $IntIf2Net } rtable 1 tag PASS
## И для туннелей ##
pass in quick on $Tun0 from <remote_nets> tag PASS
pass in quick on $Tun1 reply-to ( $Tun1 $Tun1Gw) from <remote_nets> tag PASS
## разрешаем исходящий трафик ##
pass out on { $IntIf1,$IntIf2 }
pass out quick on { $ExtIf1, $ExtIf2, gif0, gif1 } proto tcp to any port { $permit_tcp_ports }
pass out quick on { $ExtIf1, $ExtIf2, gif0, gif1 } proto udp to any port { $permit_udp_ports }
pass out quick on { $ExtIf1, $ExtIf2, gif0, gif1 } proto icmp
pass out tagged DSTNAT
pass out tagged PASS
######## macros section ########
ExtIf1="re0" # внешний интерфейс
ExtIf1Ip1="172.16.1.2" # Внешний IP адрес первого
ExtIf1Gw="172.16.1.254" # шлюз первого провайдера
ExtIf2="re1" # второй внешний интерфейс
ExtIf2Ip1="172.17.1.2" # Внешний IP адрес второго провайдера
ExtIf2Gw="172.17.1.254" # шлюз второго провайдера
IntIf1="em0" # локальный 1
IntIf1Ip="172.17.2.254" # ip локального 0
IntIf1Net="172.17.2.0/24"
IntSRV="172.17.2.1"
# туннели
Tun0="gif0"
Tun0Ip="10.0.0.2"
Tun0Gw="10.0.0.1"
Tun1="gif1"
Tun1Ip="10.0.1.2"
Tun1Gw="10.0.1.1"
# удалённый офис
RemoteExtIp1="172.16.1.1"
RemoteExtIp2="172.17.1.1"
RemoteSRV="172.17.3.1"
# разрешенный порты для исходящих соединений
permit_tcp_ports="22,53,80,443"
permit_udp_ports="53,123"
######## table section ########
# сети удалённого офиса
table <remote_nets> { 172.16.2.0/24, 172.16.3.0/24 }
######## options section ########
# разрываем соединения с ответом, а не просто дропаем пакеты
set block-policy return
# пропускаем проверку на локальной петле, там фильтрация не нужна
set skip on lo0
#scrub section
# нормализация всего входящего трафика
scrub in all
#Queueing section
# в данный момент пустая
######## nat section ########
#NAT для клиентов
nat pass on $ExtIf1 from { $IntIf1Net } to any -> $ExtIf1Ip1
nat pass on $ExtIf2 from { $IntIf1Net } to any -> $ExtIf2Ip1
#Проброс на сервер
rdr on $ExtIf1 proto tcp from any to $ExtIf1Ip1 port { http, https} tag DSTNAT -> $IntSRV
rdr on $ExtIf2 proto tcp from any to $ExtIf2Ip1 port { http, https} tag DSTNAT -> $IntSRV
rdr on $ExtIf1 proto tcp from any to $ExtIf1Ip1 port { 2022 } tag DSTNAT -> $IntSRV port ssh
rdr on $ExtIf2 proto tcp from any to $ExtIf2Ip1 port { 2022 } tag DSTNAT -> $IntSRV port ssh
######## filtering section ########
# запрет всего по умолчанию, помним, что это не означает окончание обработки пакета.
block log all
## Разрешения для входящих пакетов из Интернет. ##
pass in quick from 192.168.11.0/24 tag PASS
# разрешаем ssh и icmp
pass in quick on $ExtIf1 proto tcp to { $ExtIf1Ip1 } port 22
pass in quick on $ExtIf2 reply-to ( $ExtIf2 $ExtIf2Gw ) proto tcp to { $ExtIf2Ip1 } port 22
pass in quick on $ExtIf1 proto icmp
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) proto icmp
pass in quick on $ExtIf1 tagged DSTNAT
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) tagged DSTNAT
# разрешаем всё с нашего второго филиала
pass in quick on $ExtIf1 from $RemoteExtIp1 tag PASS
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) from $RemoteExtIp2 tag PASS
## Разрешения для внутренних сетей ##
pass in on $IntIf1 from { ($IntIf1:network) } tag PASS
## И для туннелей ##
pass in quick on $Tun0 from <remote_nets> tag PASS
pass in quick on $Tun1 reply-to ( $Tun1 $Tun1Gw) from <remote_nets> tag PASS
## разрешаем исходящий трафик ##
pass out on { $IntIf1,$IntIf2 }
pass out quick on { $ExtIf1, $ExtIf2, gif0, gif1 } proto tcp to any port { $permit_tcp_ports }
pass out quick on { $ExtIf1, $ExtIf2, gif0, gif1 } proto udp to any port { $permit_udp_ports }
pass out quick on { $ExtIf1, $ExtIf2, gif0, gif1 } proto icmp
pass out tagged DSTNAT
pass out tagged PASS
Заключение
Мы разобрали, как обеспечить симметричную маршрутизацию через провайдеров и туннели. Source Based Routing — это гибкий инструмент в руках администратора, сильно упрощающий жизнь в сложных сетях.
У нас в ИКС поддерживается условная маршрутизация средствами PF, что позволяет легко встроить его в самую сложную инфраструктуру, имея базовое понимание принципов построения сетей.
В следующей статье будет погружение в сетевой стэк FreeBSD и его взаимодействие с файрволами. А пока я буду ее готовить, у вас хватит времени протестировать ИКС в своей корпоративной сети. Триал 35 дней, бонус в виде доброжелательной бесплатной техподдержки.