Что такое Policy-Based Routing и зачем он нужен
Policy-Based Routing (PBR) - это метод маршрутизации, при котором решение о пути следования пакета принимается на основе правил, заданных администратором, а не только по IP-адресу назначения. Стандартная маршрутизация всегда ищет в таблице маршрутов наиболее специфичный префикс для destination IP и отправляет пакет через соответствующий next-hop. PBR перехватывает пакет до этого этапа и проверяет его на соответствие списку условий: от IP-адреса источника и номера порта до DSCP-метки или входящего интерфейса. Если условия совпадают, трафик направляется по альтернативному пути, заданному в политике.
Этот механизм незаменим, когда нужно направить VoIP-трафик через канал с минимальной задержкой, а почтовый трафик - через более дешёвый, но менее стабильный линк. PBR решает задачи, которые невозможно реализовать средствами классической маршрутизации: балансировку нагрузки с учётом типа приложений, сегментацию доступа для разных подсетей, обход корпоративных ограничений и автоматическое переключение на резервный канал. В этом руководстве разобраны практические конфигурации для Cisco IOS, Linux и VyOS, готовые к применению в реальной сети.
Традиционная маршрутизация vs Policy-Based Routing
При традиционной маршрутизации процесс выглядит так: маршрутизатор извлекает destination IP из заголовка пакета, ищет совпадение в таблице маршрутизации и передаёт пакет на исходящий интерфейс. Все пакеты с одним и тем же адресом назначения идут по одному и тому же пути, независимо от того, кто их отправил и какое приложение их сгенерировало.
PBR встраивает дополнительный шаг перед стандартным поиском маршрута. Маршрутизатор сначала проверяет, привязана ли к входящему интерфейсу политика (route-map на Cisco или правило ip rule на Linux). Если политика есть, пакет проверяется на соответствие критериям. При совпадении применяется действие, заданное администратором: установка next-hop, выбор исходящего интерфейса или изменение DSCP-метки. Если пакет не совпал ни с одним условием, он возвращается в стандартный процесс маршрутизации. Пример: пакет от пользователя из отдела разработки уходит через быстрый оптоволоконный канал, а трафик гостевой сети - через резервный DSL-линк, хотя оба направляются в одну и ту же внешнюю сеть.
Ключевые компоненты PBR: match и set
Любая политика PBR состоит из двух частей: условия отбора трафика (match) и действия над отобранными пакетами (set). Эта логика едина для Cisco IOS, Linux и VyOS, различается только синтаксис.
Условия match определяют, какие пакеты попадают под действие политики. Можно фильтровать по IP-адресу источника или назначения, протоколу (TCP, UDP, ICMP), номерам портов, DSCP-меткам, входящему интерфейсу, размеру пакета. Набор доступных критериев зависит от платформы. Например, Linux через fwmark позволяет маркировать пакеты в iptables и затем использовать метку в ip rule, что даёт практически неограниченную гибкость.
Действия set определяют, что делать с отобранными пакетами. Основные действия: set next-hop - принудительно задать IP-адрес следующего маршрутизатора, set interface - указать исходящий интерфейс, set DSCP - изменить метку качества обслуживания. Действие выполняется немедленно, стандартная таблица маршрутизации для этого пакета игнорируется. Аналогия с файрволом здесь уместна: PBR работает как правила фильтрации, но вместо блокировки трафика он перенаправляет его по нужному пути.
Настройка PBR на Cisco IOS
На оборудовании Cisco настройка PBR выполняется в три этапа: создание access-list для классификации трафика, построение route-map с условиями и действиями, применение route-map к входящему интерфейсу. Все команды выполняются в режиме глобальной конфигурации.
Пример: разделение трафика по протоколам
Задача: HTTP и HTTPS-трафик от сети 192.168.1.0/24 направить через провайдера с шлюзом 10.0.0.1, а весь остальной трафик этой же сети - через другого провайдера с шлюзом 10.0.1.1. Сначала создаём расширенный access-list, который отбирает пакеты на порты 80 и 443:
ip access-list extended WEB-TRAFFIC
permit tcp 192.168.1.0 0.0.0.255 any eq 80
permit tcp 192.168.1.0 0.0.0.255 any eq 443
Затем создаём route-map, который при совпадении с ACL устанавливает next-hop 10.0.0.1:
route-map PBR-WEB permit 10
match ip address WEB-TRAFFIC
set ip next-hop 10.0.0.1
Добавляем второе правило в эту же route-map для всего остального трафика. Пустой оператор match означает совпадение с любым пакетом, не попавшим в предыдущие правила:
route-map PBR-WEB permit 20
set ip next-hop 10.0.1.1
Применяем route-map к интерфейсу, через который трафик поступает на маршрутизатор:
interface GigabitEthernet0/1
ip policy route-map PBR-WEB
Порядок обработки route-map - сверху вниз. Как только пакет совпадает с условием в правиле 10, к нему применяется действие и дальнейшие правила не проверяются. Пакеты, не совпавшие с ACL WEB-TRAFFIC, попадают в правило 20 и уходят через 10.0.1.1. Обратная маршрутизация для возвращающихся пакетов должна быть настроена отдельно: провайдеры должны знать маршрут к сети 192.168.1.0/24 через ваши внешние IP.
Отладка и верификация PBR на Cisco
Для проверки работы PBR используйте команду show route-map. Она выводит статистику по каждому правилу: количество совпадений и применённых действий. Если счётчик не увеличивается, трафик не попадает в политику - проверьте ACL и привязку к интерфейсу.
Router# show route-map PBR-WEB
route-map PBR-WEB, permit, sequence 10
Match clauses:
ip address (access-lists): WEB-TRAFFIC
Set clauses:
ip next-hop 10.0.0.1
Policy routing matches: 847 packets, 62341 bytes
Команда show ip policy показывает, на каких интерфейсах активирована политика маршрутизации. Для детальной диагностики используйте debug ip policy, но с осторожностью на продуктовом оборудовании - эта команда генерирует много вывода. Типичные проблемы: неправильный ACL, route-map не применён к интерфейсу, отсутствие маршрута для указанного next-hop в таблице маршрутизации. Перед активацией PBR убедитесь, что next-hop доступен через один из интерфейсов маршрутизатора.
Policy Routing в Linux: ip rule и пользовательские таблицы
В Linux механизм policy routing реализован через несколько таблиц маршрутизации и правила, определяющие, какую таблицу использовать для конкретного пакета. По умолчанию ядро использует таблицы local и main. Таблица local содержит маршруты к локальным адресам, main - все маршруты, добавленные командой ip route. PBR добавляет пользовательские таблицы и правила ip rule, которые направляют трафик в эти таблицы на основе заданных критериев.
Создадим пользовательскую таблицу. Для этого добавим запись в файл /etc/iproute2/rt_tables:
echo 200 custom >> /etc/iproute2/rt_tables
Теперь таблица с именем custom и номером 200 доступна для использования. Добавим правило: все пакеты от сети 192.168.1.0/24 должны маршрутизироваться по таблице custom:
ip rule add from 192.168.1.0/24 table custom
Добавим маршрут по умолчанию в таблицу custom, указывающий на шлюз 10.0.0.1:
ip route add default via 10.0.0.1 table custom
Пакеты от 192.168.1.0/24 теперь уходят через 10.0.0.1, а трафик от остальных сетей продолжает использовать таблицу main. Для сохранения настроек после перезагрузки правила и маршруты нужно прописать в конфигурационных файлах сетевого менеджера или в скриптах инициализации.
Балансировка нагрузки с ECMP и весами
ECMP (Equal-Cost Multi-Path) распределяет трафик между несколькими маршрутами с одинаковой метрикой. Ядро Linux использует хеш от заголовков пакета (обычно IP-адреса источника и назначения, порты и протокол) для выбора конкретного пути. Параметр weight задаёт пропорцию распределения между шлюзами.
ip route add default nexthop via 10.0.0.1 weight 2 nexthop via 10.0.1.1 weight 1
Эта команда отправляет примерно две трети новых соединений через 10.0.0.1 и одну треть через 10.0.1.1. Веса не отражают реальную загрузку канала - ядро статистически распределяет соединения согласно заданным пропорциям. Для одного и того же соединения маршрут фиксируется в conntrack-таблице, что исключает переброс пакетов между каналами в рамках одной сессии.
Приоритезация трафика с помощью fwmark
Маркировка пакетов через iptables и использование меток в ip rule даёт возможность направлять трафик конкретных приложений через выделенные каналы. Например, направим SIP-трафик (UDP, порт 5060) через канал с минимальной задержкой.
Сначала маркируем пакеты в таблице mangle:
iptables -t mangle -A OUTPUT -p udp --dport 5060 -j MARK --set-mark 1
Создаём отдельную таблицу маршрутизации для VoIP:
echo 201 voip >> /etc/iproute2/rt_tables
ip route add default via 10.0.2.1 table voip
Добавляем правило ip rule, которое направляет маркированные пакеты в таблицу voip:
ip rule add fwmark 1 table voip
Весь SIP-трафик теперь идёт через шлюз 10.0.2.1. Аналогичным образом можно разделять трафик Docker-контейнеров, VPN-туннелей или любых других сервисов. Подробнее эта тема раскрыта в нашем руководстве по source-based маршрутизации на Linux.
Настройка PBR на VyOS
VyOS использует декларативный подход к конфигурации PBR через команды set policy route. Логика та же: определяем правила с условиями отбора и действиями, создаём отдельную таблицу маршрутизации, применяем политику к интерфейсу.
Создадим политику, которая направляет трафик от сети 192.168.1.0/24 в таблицу 100:
set policy route PBR rule 10 source address 192.168.1.0/24
set policy route PBR rule 10 set table 100
Создадим таблицу маршрутизации 100 с маршрутом по умолчанию:
set protocols static table 100 route 0.0.0.0/0 next-hop 10.0.0.1
Применим политику к входящему интерфейсу:
set interfaces ethernet eth1 policy route PBR
VyOS автоматически сохраняет конфигурацию при выполнении commit. Для проверки используйте show policy route и show ip route table 100.
Пример: сегментация доступа для гостевой сети
Задача: гостевая сеть 10.10.10.0/24 должна выходить в интернет только через выделенный канал 10.0.3.1 и не иметь доступа к внутренним ресурсам компании. Создаём политику:
set policy route GUEST-ISOLATION rule 10 source address 10.10.10.0/24
set policy route GUEST-ISOLATION rule 10 set table 200
set protocols static table 200 route 0.0.0.0/0 next-hop 10.0.3.1
set interfaces ethernet eth2 policy route GUEST-ISOLATION
Для блокировки доступа к внутренним сетям добавляем правила файрвола на интерфейсе гостевой сети. PBR здесь решает задачу принудительного выбора исходящего канала, а файрвол - задачу ограничения доступа. Такое разделение ответственности упрощает конфигурацию и отладку.
Отказоустойчивость и автоматическое переключение (Failover)
Статические маршруты не отслеживают состояние канала. Если шлюз провайдера становится недоступен, а маршрут остаётся в таблице, трафик уходит в «чёрную дыру» до вмешательства администратора. Правильно настроенный failover переключает трафик на резервный канал за секунды, без ручного вмешательства.
Cisco: IP SLA и отслеживание доступности
IP SLA периодически проверяет доступность удалённого хоста и передаёт результат объекту track. Статический маршрут привязан к track-объекту и удаляется из таблицы при сбое проверки. Резервный маршрут с более высокой метрикой автоматически активируется.
ip sla 1
icmp-echo 8.8.8.8 source-interface GigabitEthernet0/0
frequency 10
ip sla schedule 1 life forever start-time now
track 1 ip sla 1 reachability
ip route 0.0.0.0 0.0.0.0 10.0.0.1 track 1
ip route 0.0.0.0 0.0.0.0 10.0.1.1 10
Пока пинги до 8.8.8.8 проходят, используется основной маршрут с административной дистанцией по умолчанию (1). При сбое track-объекта основной маршрут удаляется, и остаётся резервный с дистанцией 10. Когда доступность восстанавливается, основной маршрут возвращается в таблицу.
Linux: keepalived для мониторинга каналов
Keepalived использует VRRP-подобный механизм для отслеживания состояния интерфейсов и выполнения скриптов при смене состояния. Для failover между двумя провайдерами настраиваем отслеживание основного интерфейса и скрипт, который переключает таблицу маршрутизации.
Пример конфигурации keepalived с отслеживанием интерфейса eth0:
vrrp_instance WAN_FAILOVER {
state MASTER
interface eth1
virtual_router_id 50
priority 100
track_interface {
eth0
}
notify_master /usr/local/bin/failover-master.sh
notify_backup /usr/local/bin/failover-backup.sh
}
Скрипт failover-master.sh заменяет маршрут по умолчанию в таблице main на резервный шлюз, а failover-backup.sh возвращает основной. Этот метод надёжнее, чем самописные скрипты с пингом - keepalived отслеживает состояние интерфейса на уровне ядра и реагирует мгновенно. Схема multi-WAN с балансировкой и failover детально разобрана в нашей статье по source-based routing на Linux.
Типичные ошибки при внедрении PBR и их устранение
PBR даёт гибкость, но требует аккуратности. Ошибки в конфигурации приводят к труднодиагностируемым проблемам с connectivity. Разберём самые частые.
Асимметричная маршрутизация и как ее избежать
Асимметричная маршрутизация возникает, когда исходящие пакеты уходят через одного провайдера, а ответные приходят через другого. Stateful-файрвол и NAT на стороне провайдера или на вашем маршрутизаторе отбрасывают такие пакеты, потому что не видят начала соединения. Симптомы: часть соединений устанавливается нормально, часть зависает, особенно заметно на HTTP (долгая загрузка) и SSH (разрыв сессии).
Решение - настройка обратного PBR или привязка соединений. В Linux conntrack фиксирует маршрут для каждого соединения, и ответные пакеты автоматически идут тем же путём. На Cisco необходимо настроить симметричную политику на обоих интерфейсах или использовать BGP с атрибутами AS-path для управления входящим трафиком. Подробный разбор проблемы и готовые решения для Cisco, MikroTik и Linux вы найдёте в материале по диагностике и устранению асимметричной маршрутизации.
Взаимодействие PBR с NAT и файрволом
Порядок обработки пакетов в netfilter имеет критическое значение. Маршрутизация происходит после таблицы mangle в цепочке PREROUTING, но до NAT в цепочке POSTROUTING. Если вы маркируете пакеты в цепочке OUTPUT таблицы mangle, маршрутизация для локально сгенерированных пакетов уже учтёт эту метку. Для транзитных пакетов маркировку нужно делать в PREROUTING.
Типичная ошибка: администратор настраивает маркировку в цепочке FORWARD, но к моменту прохождения FORWARD решение о маршрутизации уже принято. Правило ip rule с fwmark должно обрабатывать пакеты до того, как ядро выберет маршрут. Всегда проверяйте порядок прохождения цепочек для вашего конкретного случая: локальные пакеты, транзитные пакеты, пакеты после DNAT.
При использовании PBR совместно с NAT убедитесь, что SNAT применяется к правильному исходящему интерфейсу. Если пакет уходит через альтернативный канал по PBR, а правило SNAT привязано только к основному интерфейсу, пакет уйдёт с неправильным source IP и ответ не вернётся. Настройте отдельные правила SNAT для каждого возможного исходящего интерфейса или используйте MASQUERADE, который автоматически подставляет IP интерфейса.