#/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"
# Внутренний интерфейс (LAN).#
int_if = "em1"
# Обслуживаемые TCP и UDP сервисы.
tcp_svc = "22 25 21 35000:35100"
# 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. И теперь снаружи со всех трех каналов видно терминальный сервер, фтп и почтовый сервера.
Кто-то скажет что фаервол это не маршрутизатор и я согласен. Но на циску денег не дают. Поэтому чем не выход.
Обсудить сообщение можно в форуме admins.arg.su
36 комментариев:
А я вот не считаю, что Firewall — это не маршрутизатор. Даже термин есть такой — FBR, то есть, Firewall-based Routing.
Так что идея сама делать маршрутизацию pf'ом очень и очень даже здрава.
т.е балансировки нагрузки нет, просто Policy Routing ???
да интересная конструкция только не ясно какй шлюз по умолчанию
Балансировка в моем случае не нужна.
На счет шлюза по умолчанию. А какая разница то?
А если потребуется мониторить оба соединения, делать ping со сменой defaultrouter?
В моем случае шлюз по умолчанию канал А,
прописаны статические маршруты для туннелей в каналы В и С. Также прописаны статические маршруты для бесплатных сетей провайдеров В и С.
На счет мониторить соединения - мониторьте. Не вижу для этого препятствий.
:)
набираем пинг, он идет в канал А.
Правильно?
Чтобы проверить канал В надо же соответственно сменить шлюз.
Правильно?
У каждого канала есть свой шлюз, вот и пингуйте шлюз.
т.е. при этих настройках
ping ext_gw_a
пойдет через ext_if_a
а, ping ext_gw_b
пойдет через ext_if_b?
и соответственно при
ping www.ru пойдёт через ext_if_a, если он является по умолчанию?
да
nat on $ext_if_a inet from !(self) -> $ext_if_a:0
а объясните плиз что сие значит?
нет я понимаю что нат но конкретно "!(self)" и "$ext_if_a:0"? что за обозначение такое ":0"?
"!(self)" натим все что не от себя (в смысле не от сервака)
"$ext_if_a:0" ":0" это значит не учитывать алиасы интерфейса
Когда-то очень давно я делал подобное на IPFW, только без проброса портов вовнутрь.
На pf выглядит как-то привлекателельнее, на мой первый взгляд.
А как вы сделали на ipfw возврат пакетов обратно в канал если шлюз по умолчанию смотрит в другой канал.
А как вы сделали на ipfw возврат пакетов обратно в канал если шлюз по умолчанию смотрит в другой канал.
ipfw fwd на нужный IP шлюза.
"Остальное через прокси сервер squid."
А как трафик на СКВИД заворачивал?
Никак не заворачивал, в клиентах прописан прокси :)
Народ, подскажите пожалуйста, как правильно сделать нат, если есть так же три интерфейса и проблема в том что на двух интерфейстов куча алиасов. Вот так например
xl1: flags=8843 UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST mtu 1500
options=1 RXCSUM,VLAN_MTU
inet 115.46.11.115 netmask 0xfffffff0 broadcast 115.46.11.207
inet 115.46.11.114 netmask 0xffffffff broadcast 115.46.11.114
inet 115.46.11.116 netmask 0xffffffff broadcast 115.46.11.116
inet 115.46.11.117 netmask 0xffffffff broadcast 115.46.11.117
весь трафик по умолчанию идет через 115.46.11.114, вопрос в том, как в pf сделать чтоб тот кто через нам работает ходил скажем с 115.46.11.116 ip?
Заранее спасибо!
Думаю так
nat on $ext_if_a inet from !(self) -> 115.46.11.116
А вообще вопросу прошу в форум http://admins.arg.su
Камрад, а как же обстоит дело с "дефолтным маршрутом"? Или default gateway вообще не учавствует в сетевом обмене?
И вот еще какой вопрос назрел. Что произойдет в случае отказа одного, двух каналов? Как будет вести себя маршрутизатор?
Что касается маршрута по умолчанию, у меня он в канал А. И прописаны статические маршруты к сетям в два других канала. При отказе к примеру канала А сервисы доступные снаружи останутся доступны по каналам В и С, естественно изнутри все что в дефолтовый канал А работать не будет. Нужно переключать шлюз по умолчанию в другой канал.
Возможно ли сделать чтобы любой пакет на любой порт с какого интерфейса пришел на тот и должен уйти?
Да так и есть для # Обслуживаемые TCP и UDP сервисы. tcp_svc = "22 25 21 35000:35100"
Уберите в правилах ниже tcp_svc
# Разрешить входящие 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
Вы имеете ввиду
в tcp_svc = "22 25 21 35000:35100"
увеличть диапазон
tcp_svc = "1:65000", а потом написать то-же для например для udp, icmp?
нет вот так
pass in on $ext_if_a reply-to ($ext_if_a $ext_gw_a) inet proto tcp\
to $ext_if_a:0 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 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 flags S/SA keep state
При таких правилах вроде и работает (почта и радмин ходят), а вот с пингами и трассировкой никак.
У меня сейчас используется
pass out quick route-to ($1_if $1_gw) from $1_ip to any keep state
pass out quick route-to ($2_if $2_gw) from $2_ip to any keep state
При этих правилах трассировка с внешнего хоста до второго канала доходит нормально, и пинги до второго идут через первый (дефолт. рут)
Есть варианты?
Все возможно, давайте уже в форуме пообщаемся http://admins.arg.su
Постарайтесь четко сформулировать вопрос
Вот эти правила, цитата
"У меня сейчас используется
pass out quick route-to ($1_if $1_gw) from $1_ip to any keep state
pass out quick route-to ($2_if $2_gw) from $2_ip to any keep state"
для исходящих соединений от вашего сервера
А если требуется сместить сервис на внешнем интерфейсе, на другой порт?
В ipfw делается довольно просто
redirect_port tcp 192.168.0.1:4899 4444
А в pf?
И зачем это может понадобиться?
Вопросы в форум admins.arg.su
man ping эбаут (-S)
ping -S srcip dstip
В линухе пинг умеет пинговать через указанный интерфейс.
Во фряхе можно установить hping.
Балансировка нагрузки исходящего трафика (http://www.opennet.ru/base/sec/pf_extended.txt.html#top5)
Пулы адресов могут использоваться для балансировки нагрузки между двумя и более внешними каналами с использованием опции route-to в случае невозможности организовать динамическую маршрутизацию (например, с использованием протокола BGP4). Совместное использование route-to и пула адресов round-robin исходящие соединения могут быть распределены между разными провайдерами.
В качестве дополнительной информации необходимо указать адреса маршрутизаторов для каждого Интернет-соединения. Это необходимо для опции route-to, дабы управлять исходящими пакетами.
Этот пример покажет нам балансировку нагрузки между двумя каналами:
lan_net = "192.168.0.0/24"
int_if = "dc0"
ext_if1 = "fxp0"
ext_if2 = "fxp1"
ext_gw1 = "68.146.224.1"
ext_gw2 = "142.59.76.1"
pass in on $int_if route-to \
{ ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
from $lan_net to any keep state
Опция route-to используется для приема трафика на внутреннем интерфейсе и назначения ему внешнего сетевого интерфейса и шлюза, таким образом обеспечивая балансировку. Обратите внимание, что опция route-to должна быть указана в каждом правиле, предназначенном для балансировки трафика. Ответные пакеты приходят на тот интерфейс, с которого ушел запрос и они будут перенаправлены во внутрь как обычно.
Для гарантии того, что пакеты с $ext_if1 всегда направляются к $ext_gw1 (и соответственно для $ext_if2 к $ext_gw2), в правилах можно указать следующее:
pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 \
to any
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 \
to any
В заключение хочу сказать, что NAT можно использовать на каждом из внешних интерфейсов:
nat on $ext_if1 from $lan_net to any -> ($ext_if1)
nat on $ext_if2 from $lan_net to any -> ($ext_if2)
Полный пример балансировки исходящего трафика будет выглядеть так:
lan_net = "192.168.0.0/24"
int_if = "dc0"
ext_if1 = "fxp0"
ext_if2 = "fxp1"
ext_gw1 = "68.146.224.1"
ext_gw2 = "142.59.76.1"
# nat outgoing connections on each internet interface
nat on $ext_if1 from $lan_net to any -> ($ext_if1)
nat on $ext_if2 from $lan_net to any -> ($ext_if2)
# default deny
block in from any to any
block out from any to any
# pass all outgoing packets on internal interface
pass out on $int_if from any to $lan_net
# pass in quick any packets destined for the gateway itself
pass in quick on $int_if from $lan_net to $int_if
# load balance outgoing tcp traffic from internal network.
pass in on $int_if route-to \
{ ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
proto tcp from $lan_net to any flags S/SA modulate state
# load balance outgoing udp and icmp traffic from internal network
pass in on $int_if route-to \
{ ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
proto { udp, icmp } from $lan_net to any keep state
# general "pass out" rules for external interfaces
pass out on $ext_if1 proto tcp from any to any flags S/SA modulate state
pass out on $ext_if1 proto { udp, icmp } from any to any keep state
pass out on $ext_if2 proto tcp from any to any flags S/SA modulate state
pass out on $ext_if2 proto { udp, icmp } from any to any keep state
# route packets from any IPs on $ext_if1 to $ext_gw1 and the same for
# $ext_if2 and $ext_gw2
pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any
to Рамиль
А как у тебя rc.conf настроен? Ведь на внешних интерфейсах разные сетевые настройки (шлюз, DNS).
Рамиль, а прикрутите еще один интерфейс для DMZ (10.110.1.254)
а там пусть крутится
1) отдельно майл 25, 110 (10.110.1.252)
2) веб 80 для всех, 443 только для лан (10.110.1.253)
ато запутался с tcp_svc_lan_
>А как у тебя rc.conf настроен? Ведь на >внешних интерфейсах разные сетевые >настройки (шлюз, DNS).
в rc.conf прописан шлюз в канал по-умолчанию (в основной), а DNS не там настраивается :)
>Рамиль, а прикрутите еще один интерфейс >для DMZ (10.110.1.254)
пишите в форум admins.arg.su вместе и настроим :)
Отправить комментарий