OpenBSD PF - Пулы адресов и балансировка нагрузки [FAQ PF - На главную]



Введение

Адресный пул представляет собой два или более адресов, которые используются совместно группой пользователей. Адресный пул может быть указан в качестве параметра целевого адреса в директивах фильтра nat-to, rdr-to, route-to, reply-to и dup-to.

Существуют четыре метода использования адресного пула:

За исключением циклического метода round-robin, адресный пул должен быть описан как сетевой блок CIDR (Classless Inter-Domain Routing). Циклический round-robin метод допускает использование множества отдельных адресов, определенных при помощи списка или таблицы.

Параметр sticky-address может быть использован с пулами типа random и round-robin для обеспечения того условия, что адрес источника всегда будет соотнесен тому же адресу перенаправления.

Пул адресов NAT

Адресный пул может быть использован в качестве адреса для преобразования в правилах nat-to. Соединения будут получать свой source address путем преобразования его в адреса из пула, указанным способом. Это может быть полезным в ситуации, когда PF обслуживает при помощи NAT очень большую сеть. Так как число соединений, преобразованных при помощи NAT, ограниченно, добавление дополнительных адресов позволяет шлюзу масштабироваться и обслуживать большее количество клиентов.

В этом примере пул из двух адресов используется для преобразования исходящих пакетов. Для каждого исходящего соединения PF будет циклически выбирать адрес способом round-robin.

match out on egress inet nat-to { 192.0.2.5, 192.0.2.10 }
Одним из недостатков этого метода является то, что соединения с одного внутреннего адреса не могут быть всегда преобразованы в тот же конечный адрес. Это может препятствовать, например, просмотру сайтов, которые отслеживают доступ пользователей, основываясь на его IP-адрес. Альтернативный способ - использовать метод source-hash. Тогда каждый внутренний адрес всегда будет преобразован в один и тот же конечный адрес. Для этого адресный пул должен быть описан при помощи сетевого блока CIDR.
match out on egress inet nat-to 192.0.2.4/31 source-hash
Это правило использует пул адресов 192.0.2.4/31 (192.0.2.4 — 192.0.2.5) для преобразования адреса исходящих пакетов. Каждый внутренний адрес будет всегда преобразован в один и тот же адрес благодаря ключевому слову source-hash.

Балансировка нагрузки входящих соединений

Адресный пул также может быть использован для балансировки нагрузки входящих соединений. Например, входящие соединения к web серверу могут быть распределены между web серверами в ферме:
web_servers = "{ 10.0.0.10, 10.0.0.11, 10.0.0.13 }"

match in on egress proto tcp to port 80 rdr-to $web_servers \
    round-robin sticky-address
Последовательные соединения будут перенаправлены на web серверы циклическим методом. Причем соединения с одних и тех же адресов будут перенаправлены на одни и те же web серверы. "Липкие связи" ("sticky connection") будут существовать до тех пор пока они будут привязаны к своим соединениям. Как только соединения закрываются, исчезает и липкая связь. Последующие соединения с этого адреса будут перенаправлены к следующему web серверу в циклическом порядке.

Балансировка нагрузки исходящих соединений

Пул адресов может быть использован в комбинации с опцией фильтра route-to для балансировки двух или более Internet соединений, когда невозможно использовать правильный протокол multipath-маршрутизации (например BGP4). При использовании route-to с адресным пулом round-robin исходящие соединения могут быть равномернораспределены между несколькими исходящими маршрутами.

Еще одна дополнительная порция информации, необходимая для этого - это IP-адрес соседнего рутера на каждом Internet соединении. Она необходима опции route-to для управления полем "приемник" (destination) исходящих пакетов.

Приведенный пример демонстрирует возможность балансировки исходящего трафика через два Internet соединения:

lan_net = "192.168.0.0/24"
int_if  = "dc0"
ext_if1 = "fxp0"
ext_if2 = "fxp1"
ext_gw1 = "198.51.100.100"
ext_gw2 = "203.0.113.200"

pass in on $int_if from $lan_net route-to \
   { $ext_gw1 $ext_gw2 } round-robin
Параметр route-to применяется к входящему трафику на внутреннем интерфейсе, чтобы указать исходящий (outgoing) сетевой шлюз (gateway), трафик которого будет балансироваться. Заметьте, что опция route-to может присутствовать в каждом правиле фильтра, которое предназначено для балансировки трафика (она не может быть использованая с правилом match).

Чтобы быть уверенным, что source address пакеты, принадлежащие $ext_if1, всегда перенаправляются на $ext_gw1 (и аналогично для $ext_if2 и $ext_gw2), в правила необходимо добавить следующие две строки:

pass out on $ext_if1 from $ext_if2 route-to $ext_gw2
pass out on $ext_if2 from $ext_if1 route-to $ext_gw1
И наконец, NAT может быть использован на каждом исходящем интерфейсе:
match out on $ext_if1 from $lan_net nat-to ($ext_if1)
match out on $ext_if2 from $lan_net nat-to ($ext_if2)

Полный пример балансировки исходящего трафика может выглядеть так:

lan_net = "192.168.0.0/24"
int_if  = "dc0"
ext_if1 = "fxp0"
ext_if2 = "fxp1"
ext_gw1 = "198.51.100.100"
ext_gw2 = "203.0.113.200"

# nat outgoing connections on each internet interface
match out on $ext_if1 from $lan_net nat-to ($ext_if1)
match out on $ext_if2 from $lan_net nat-to ($ext_if2)

# default deny
block in
block out

# pass all outgoing packets on internal interface
pass out on $int_if 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 traffic from internal network.
pass in on $int_if from $lan_net \
    route-to { $ext_gw1 $ext_gw2 } round-robin
# keep https traffic on a single connection; some web applications,
# especially "secure" ones, don't allow it to change mid-session
pass in on $int_if proto tcp from $lan_net to port https \
    route-to $ext_gw1

# general "pass out" rules for external interfaces
pass out on $ext_if1
pass out on $ext_if2

# 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 from $ext_if2 route-to $ext_gw2
pass out on $ext_if2 from $ext_if1 route-to $ext_gw1