Пример конфигурации FreeBSD маршрутизатора с тремя внешними каналами [2008]
В данной заметке привожу рабочий конфигурационный файл маршрутизатора с тремя внешними каналами, трансляцией адресов, переадресацией сервисов во внутреннюю сеть. Работает симметричная маршрутизация для правильного возврата пакетов в канал, с которого соединение было инициировано. Внутри локальной сети терминальный сервер 192.168.1.3. На самом сервере доступно из вне ftp ssh и почта. На втором и третьем внешнем интерфейсе на 5000 порту работает сервер vtun. У локальной сети 192.168.1.0/24. У туннельных сетей 192.168.3.0/24 и 192.168.4.0/24. Из локалки наружу разрешено 110, 3389, 53, остальное через прокси сервер squid.
#/etc/pf.conf # Внешний интерфейс и шлюз для канала A (WAN_1).# ext_if_a = "em0" ext_gw_a = "x.x.x.x"
# Внешний интерфейс и шлюз для канала B (WAN_2).# ext_if_b = "em2" ext_gw_b = "x.x.x.x"
# Внешний интерфейс и шлюз для канала C (WAN_3).# ext_if_c = "fxp0" ext_gw_c = "x.x.x.x"
# TCP сервисы, обслуживаемые сервером из внутренней сети, и адрес сервера. # 3389 tcp_svc_lan_terminal = "3389" tcp_rdr_lan_terminal = "192.168.1.3"
# Не фильтровать трафик на lo интерфейсах.# set skip on lo0
# Нормализовать весь входящий трафик.# scrub in
# Включить трансляцию адресов на внешних интерфейсах.# nat on $ext_if_a inet from !(self) -> $ext_if_a:0 nat on $ext_if_b inet from !(self) -> $ext_if_b:0 nat on $ext_if_c inet from !(self) -> $ext_if_c:0
# Переадресовать TCP сессии для сервисов, обслуживаемых локальным сервером. # Правила rdr здесь НЕ должны содержать слова pass. rdr on $ext_if_a inet proto tcp to $ext_if_a:0 port { $tcp_svc_lan_terminal\ } tag EXT_IF_A -> $tcp_rdr_lan_terminal rdr on $ext_if_b inet proto tcp to $ext_if_b:0 port { $tcp_svc_lan_terminal\ } tag EXT_IF_B -> $tcp_rdr_lan_terminal rdr on $ext_if_c inet proto tcp to $ext_if_c:0 port { $tcp_svc_lan_terminal\ } tag EXT_IF_C -> $tcp_rdr_lan_terminal
# Разрешить подключение к переадресованным сервисам из локальной сети по # внешним адресам. rdr pass on $int_if inet proto tcp to { $ext_if_a:0 $ext_if_b:0 $ext_if_c:0\ } port { $tcp_svc_lan_terminal } tag INT_IF_RDR -> $tcp_rdr_lan_terminal nat on $int_if tagged INT_IF_RDR -> $int_if:0
# По умолчанию блокировать весь трафик на всех интерфейсах. Для входящих TCP # соединений возвращать RST. block on { $ext_if_a $ext_if_b $ext_if_c $int_if} block return on { $ext_if_a $ext_if_b $ext_if_c $int_if} inet proto tcp
#Разрешить доступ через лок интерфейс к терминал серверу pass out quick on $int_if inet proto tcp from any to $tcp_rdr_lan_terminal\ port $tcp_svc_lan_terminal keep state
# Пропускаем входящие пакеты для переадресованых сервисов. Устанавливаем # для них симметричную маршрутизацию (если пакет пришел # из канала A, ответ пойдет через канал A независимо от default route). pass in quick reply-to ($ext_if_a $ext_gw_a) tagged EXT_IF_A keep state pass in quick reply-to ($ext_if_b $ext_gw_b) tagged EXT_IF_B keep state pass in quick reply-to ($ext_if_c $ext_gw_c) tagged EXT_IF_C keep state
# Выпускать исходящие пакеты. Установить маршрутизацию в зависимости от # адреса источника. Пакеты с адресом интерфейса A уходят в канал A, # с адресом интерфейса B - в канал B. pass out route-to ( $ext_if_a $ext_gw_a ) inet from $ext_if_a:0 keep state pass out route-to ( $ext_if_b $ext_gw_b ) inet from $ext_if_b:0 keep state pass out route-to ( $ext_if_c $ext_gw_c ) inet from $ext_if_c:0 keep state
# Разрешить входящие ICMP PING пакеты.# pass in on $ext_if_a reply-to ($ext_if_a $ext_gw_a) inet proto icmp\ to $ext_if_a:0 icmp-type echoreq code 0 keep state pass in on $ext_if_b reply-to ($ext_if_b $ext_gw_b) inet proto icmp\ to $ext_if_b:0 icmp-type echoreq code 0 keep state pass in on $ext_if_c reply-to ($ext_if_c $ext_gw_c) inet proto icmp\ to $ext_if_c:0 icmp-type echoreq code 0 keep state
# Разрешить входящие TCP сессии для обслуживаемых сервисов.# pass in on $ext_if_a reply-to ($ext_if_a $ext_gw_a) inet proto tcp\ to $ext_if_a:0 port { $tcp_svc } flags S/SA keep state pass in on $ext_if_b reply-to ($ext_if_b $ext_gw_b) inet proto tcp\ to $ext_if_b:0 port { $tcp_svc } flags S/SA keep state pass in on $ext_if_c reply-to ($ext_if_c $ext_gw_c) inet proto tcp\ to $ext_if_c:0 port { $tcp_svc} flags S/SA keep state
#Разрешим туннели на интерфейсе WAN_2 и WAN3 pass in on $ext_if_b reply-to ($ext_if_b $ext_gw_b) inet proto tcp\ from x.x.x.x to $ext_if_b:0 port 5000 flags S/SA keep state pass in on $ext_if_c reply-to ($ext_if_c $ext_gw_c) inet proto tcp\ from x.x.x.x to $ext_if_c:0 port 5000 flags S/SA keep state pass quick on tun0 all pass quick on tun1 all
#Разрешить в локалку пакеты от внутреннего интерфейса, из локальных сетей # туннелей pass out on $int_if inet from { $int_if:0, 192.168.3.0/24,\ 192.168.4.0/24 } to $int_if:network:0 keep state
#Разрешить из локалки пакеты на внутренний интерфейс, в локальные сети # туннелей pass in on $int_if inet from $int_if:network:0 to { $int_if:0,\ 192.168.3.0/24, 192.168.4.0/24 } keep state
#Разрешить из локалки пинг pass in on $int_if inet proto icmp from $int_if:network:0 to any\ icmp-type echoreq code 0 keep state
#Разрешить из локалки 110, 3389, 53 pass in on $int_if inet proto tcp from $int_if:network:0 to any port\ { 110, 3389 } flags S/SA keep state pass in on $int_if inet proto udp from $int_if:network:0 to any port\ 53 keep state
P.S. И теперь снаружи со всех трех каналов видно терминальный сервер, фтп и почтовый сервера. Кто-то скажет что фаервол это не маршрутизатор и я согласен. Но на циску денег не дают. Поэтому чем не выход.