Настройка Policy-Based Routing (PBR) в Linux: распределение трафика, VPN, отказоустойчивость | Руководство для DevOps | AdminWiki
Timeweb Cloud — сервера, Kubernetes, S3, Terraform. Лучшие цены IaaS.
Попробовать

Настройка Policy-Based Routing (PBR) в Linux: распределение трафика, VPN, отказоустойчивость | Руководство для DevOps

11 июня 2026 11 мин. чтения

Policy-Based Routing (PBR) дает полный контроль над маршрутизацией трафика в Linux, выходя за рамки простого выбора пути по адресу назначения. С помощью PBR вы направляете пакеты через разные сетевые интерфейсы или VPN-туннели в зависимости от исходного IP-адреса, порта или других критериев. Это решает задачи распределения нагрузки между несколькими провайдерами, приоритизации критического трафика и создания отказоустойчивых архитектур.

Что такое Policy-Based Routing и когда он нужен в реальных проектах

Policy-Based Routing это механизм маршрутизации, при котором решение о пути пакета принимается на основе настраиваемых правил, а не только таблицы маршрутизации по умолчанию. В отличие от обычной маршрутизации, где ключевым критерием выступает адрес назначения, PBR позволяет учитывать источник трафика, метку пакета (fwmark) или другие атрибуты.

Типичные сценарии применения в инфраструктуре DevOps:

  • Мультихоминг: трафик из разных подсетей серверов направляется через разные интернет-каналы для балансировки нагрузки или соблюдения политик провайдеров.
  • Приоритизация VPN: весь трафик определенных приложений или контейнеров принудительно идет через VPN-туннель (например, WireGuard или OpenVPN) для обеспечения безопасности или обхода географических ограничений.
  • Отказоустойчивость (Failover): автоматическое переключение трафика на резервный канал связи при падении основного.
  • Изоляция трафика: разделение служебного, пользовательского и backup-трафика по разным физическим или логическим каналам.

PBR становится оптимальным решением, когда простого добавления маршрутов в основную таблицу недостаточно, и требуется гибкость, основанная на логике, а не только на топологии сети.

Как работает PBR: таблицы маршрутизации и правила ip rule

Ядро Linux использует несколько таблиц маршрутизации. По умолчанию все работает с таблицей main (ID 254). PBR вводит дополнительные таблицы (например, 100, 200), каждая со своим набором маршрутов. Утилита ip rule управляет правилами, которые определяют, какую таблицу использовать для принятия решения о маршрутизации конкретного пакета.

Алгоритм выбора маршрута ядром:

  1. Пакет поступает в сетевой стек.
  2. Ядро последовательно проверяет правила из списка ip rule, начиная с наименьшего приоритета (числовое значение).
  3. Если критерий правила (например, from 10.0.1.0/24) совпадает с пакетом, ядро выполняет операцию lookup в указанной таблице маршрутизации.
  4. В найденной таблице ищется подходящий маршрут для адреса назначения пакета.
  5. Если совпадение найдено, пакет направляется согласно этому маршруту. Если нет, проверяется следующее правило.

Ключевые команды для работы с механизмом:

  • ip rule add from 10.0.1.0/24 lookup 100 – создать правило: для трафика из подсети 10.0.1.0/24 использовать таблицу 100.
  • ip route add default via 192.168.1.1 dev eth0 table 100 – добавить маршрут по умолчанию в таблицу 100.
  • ip rule list – показать все активные правила.

Почему PBR, а не маршрутизация по умолчанию или ECMP?

Выбор инструмента зависит от задачи. Одна таблица маршрутизации (main) проста, но негибка. ECMP (Equal-Cost Multi-Path) эффективно балансирует нагрузку между несколькими равнозначными путями, но не умеет выбирать путь на основе источника или типа трафика.

PBR незаменим, когда:

  • Трафик с разных исходных адресов должен покидать сервер через разные интерфейсы (например, сервера веб-приложений и сервера баз данных используют разные каналы для выхода в интернет).
  • Требуется маршрутизировать трафик на основе не сетевых (L3), а транспортных (L4) атрибутов, таких как порт назначения, что достигается комбинацией PBR и маркировки пакетов iptables/nftables.
  • Необходимо обеспечить детальный контроль для compliance или безопасности, например, весь трафик от определенного Docker-контейнера строго через VPN.

Для задач простого резервирования каналов иногда достаточно маршрутов с разными метриками, но для сложного распределения PBR предлагает точность.

Базовые команды и инструменты: ip rule, ip route и таблицы маршрутизации Linux

Работа с PBR строится вокруг набора утилит пакета iproute2. Вот основные команды, которые вам понадобятся для всех последующих примеров.

Просмотр текущей конфигурации:

# Показать все правила маршрутизации
ip rule list
# Показать маршруты в основной таблице
ip route show
# Показать маршруты в конкретной таблице (например, с ID 100)
ip route show table 100

Создание правила с приоритетом 1000 для трафика из подсети 192.168.10.0/24 с использованием таблицы 200:

ip rule add priority 1000 from 192.168.10.0/24 lookup 200

Добавление маршрута по умолчанию в таблицу 200 через шлюз 10.0.0.1 на интерфейсе eth1:

ip route add default via 10.0.0.1 dev eth1 table 200

Важно помнить о порядке приоритетов. Правило с меньшим числом в поле priority выполняется раньше. После всех пользовательских правил выполняются системные: local (0), main (32766), default (32767).

Создание и управление таблицами маршрутизации

Для удобства таблицам присваивают имена. Для этого редактируют файл /etc/iproute2/rt_tables. Добавьте строки:

# /etc/iproute2/rt_tables
...
100    wan1
101    wan2
200    vpn

Теперь можно ссылаться на таблицы по имени:

ip route add default via 192.168.1.1 dev eth0 table wan1
ip rule add from 10.0.1.0/24 lookup wan1

Просмотр содержимого именованной таблицы:

ip route show table wan1

Диагностика: как проверить, по какому пути идет ваш трафик

После настройки PBR критически важно убедиться, что трафик идет ожидаемым путем. Основная команда для этого ip route get.

Чтобы узнать, какой маршрут будет использован для пакета с исходным адресом 10.0.1.5 и адресом назначения 8.8.8.8:

ip route get from 10.0.1.5 to 8.8.8.8

Команда покажет итоговый интерфейс, шлюз и таблицу, которая была использована для поиска маршрута.

Для практического тестирования исходящего соединения используйте curl с указанием исходного интерфейса или адреса:

curl --interface eth0 ifconfig.me  # Узнать свой публичный IP, выходя через eth0
curl --interface eth1 ifconfig.me  # Узнать свой публичный IP, выходя через eth1

Для низкоуровневой проверки поможет tcpdump. Запустите его на интерфейсе, через который, как вы ожидаете, должен идти трафик:

tcpdump -ni eth0 icmp  # Прослушивать ICMP-пакеты (пинги) на интерфейсе eth0

Затем с другого хоста в тестируемой подсети отправьте ping на внешний адрес. Если пакеты появляются в выводе tcpdump, PBR работает корректно.

Практические примеры настройки PBR для продакшен-сред

Приведенные ниже конфигурации проверены на ядрах Linux 5.x и новее в дистрибутивах Ubuntu 20.04/22.04 и RHEL/CentOS 8/9. Перед применением в production обязательно протестируйте в изолированном окружении.

Кейс 1: Распределение трафика по двум интернет-каналам (мультихоминг)

Задача: Сервер имеет два сетевых интерфейса с подключением к разным провайдерам. Трафик из подсети серверов приложений (10.0.1.0/24) должен выходить в интернет через eth0 (шлюз 192.168.1.1). Трафик из подсети серверов баз данных (10.0.2.0/24) – через eth1 (шлюз 10.0.0.1).

Решение:

1. Добавляем имена таблиц в /etc/iproute2/rt_tables:

100    wan1
101    wan2

2. Настраиваем маршруты по умолчанию в каждой таблице:

ip route add default via 192.168.1.1 dev eth0 table wan1
ip route add default via 10.0.0.1 dev eth1 table wan2

3. Создаем правила PBR для исходных подсетей. Указываем высокий приоритет (например, 1000), чтобы эти правила выполнялись до правила для таблицы main:

ip rule add priority 1000 from 10.0.1.0/24 lookup wan1
ip rule add priority 1001 from 10.0.2.0/24 lookup wan2

4. Убеждаемся, что для всего остального трафика (не из этих подсетей) работает стандартный маршрут из таблицы main:

ip route add default via 192.168.1.1 dev eth0  # Это маршрут в таблице main

Проверка:

# С хоста 10.0.1.5
ip route get from 10.0.1.5 to 8.8.8.8
# Должен показать dev eth0 и table wan1

# С хоста 10.0.2.10
ip route get from 10.0.2.10 to 8.8.8.8
# Должен показать dev eth1 и table wan2

Кейс 2: Приоритизация трафика VPN (WireGuard/OpenVPN) над основным каналом

Задача: Весь трафик, предназначенный для удаленной сети 172.16.0.0/16, должен идти через VPN-туннель WireGuard (интерфейс wg0), даже если для этих адресов существует маршрут в основной таблице через физический интерфейс.

Решение: Используем маркировку пакетов (fwmark).

1. Создаем таблицу для VPN (например, vpn с ID 200) и добавляем в нее маршрут к целевой сети через туннельный интерфейс:

ip route add 172.16.0.0/16 dev wg0 table vpn

2. Помечаем пакеты, направленные в сеть 172.16.0.0/16, с помощью iptables или nftables. Пример для iptables:

iptables -t mangle -A OUTPUT -d 172.16.0.0/16 -j MARK --set-mark 1

3. Создаем правило PBR, которое для помеченных пакетов (fwmark 1) будет использовать таблицу vpn. Устанавливаем высокий приоритет (500), чтобы это правило сработало до любых других:

ip rule add priority 500 fwmark 1 lookup vpn

Теперь любой исходящий пакет в сеть 172.16.0.0/16 получит метку 1 и будет направлен согласно маршруту в таблице vpn (то есть через wg0), игнорируя маршруты из таблицы main.

Этот подход можно расширить для изоляции трафика конкретных приложений или Docker-контейнеров. Подробнее о сложных сценариях изоляции читайте в нашем руководстве по настройке изоляции трафика Docker и приложений через VPN.

Кейс 3: Отказоустойчивая схема (Failover) с резервным каналом

Задача: Основной интернет-канал (eth0, шлюз 192.168.1.1) должен использоваться по умолчанию. При его недоступности весь трафик автоматически переключается на резервный канал (eth1, шлюз 10.0.0.1).

Решение: Используем PBR с правилами разного приоритета и динамическим обновлением маршрутов.

1. Создаем две таблицы: primary и backup.

2. Настраиваем в них маршруты по умолчанию:

ip route add default via 192.168.1.1 dev eth0 metric 100 table primary
ip route add default via 10.0.0.1 dev eth1 metric 200 table backup

Обратите внимание на метрики (metric). Внутри одной таблицы маршрут с меньшей метрикой будет предпочтительнее. Это полезно, если в таблице несколько маршрутов до одной сети.

3. Создаем правила. Правило для основной таблицы имеет более высокий приоритет (меньшее число):

ip rule add priority 1000 table primary
ip rule add priority 2000 table backup

4. Для автоматического переключения необходимо отслеживать доступность шлюза. Простой способ – использовать параметр proto kernel совместно с демоном, проверяющим связность. Более надежный вариант – скрипт, который периодически пингует шлюз и обновляет маршруты командой ip route replace.

Пример скрипта (упрощенно):

#!/bin/bash
if ! ping -c 2 -W 1 192.168.1.1 &> /dev/null; then
  # Основной шлюз недоступен, удаляем правило для primary
  ip rule del priority 1000
  # Теперь активно только правило priority 2000 (backup)
else
  # Восстанавливаем правило, если оно отсутствует
  ip rule show | grep "priority 1000" || ip rule add priority 1000 table primary
fi

Это базовая схема. В реальных проектах часто используют динамические протоколы маршрутизации (например, BGP) или комплексные решения для мониторинга линков.

Для понимания основ маршрутизации, без которых сложно строить отказоустойчивые схемы, рекомендуем ознакомиться с полным руководством по настройке маршрутизации в Linux.

Как сделать настройки постоянными и избежать проблем

Настройки, выполненные командами ip rule и ip route, сбрасываются после перезагрузки системы. Для production-сред это недопустимо.

Персистентная конфигурация через systemd-networkd и файлы конфигурации

Для современных дистрибутивов, использующих systemd (Ubuntu 22.04, RHEL 9), оптимальный метод – конфигурационные файлы systemd-networkd.

Пример файла /etc/systemd/network/80-pbr-primary.network для интерфейса eth0:

[Match]
Name=eth0

[Network]
Address=192.168.1.10/24
Gateway=192.168.1.1

[Route]
Gateway=192.168.1.1
Table=primary

[RoutingPolicyRule]
Priority=1000
Table=primary

Аналогичный файл для eth1 (80-pbr-backup.network) будет содержать Table=backup и Priority=2000.

После создания файлов выполните:

systemctl restart systemd-networkd
networkctl reload

Для систем, где systemd-networkd не используется (например, старые CentOS 7), можно добавить команды в скрипт инициализации сети (/etc/rc.local или /etc/sysconfig/network-scripts/route-<interface> и rule-<interface>).

Независимо от выбранного метода, всегда имейте под рукой план отката, особенно при работе над удаленным сервером.

Что делать, если вы потеряли доступ после настройки PBR

Самая частая ошибка – создание правила, которое перехватывает весь трафик (включая SSH-сессию) и направляет его через неправильный или недоступный маршрут.

План экстренного восстановления доступа:

  1. Локальный доступ: Если возможно, получите физический или консольный доступ к серверу (через KVM, IPMI, гипервизор).
  2. Удаление всех добавленных правил: В консоли выполните команду для удаления правил по диапазону приоритетов или конкретным условиям.
    # Удалить правило с приоритетом 1000
    ip rule del priority 1000
    # Удалить все правила, кроме системных (local, main, default)
    for i in $(ip rule list | grep -v "local\|main\|default" | awk '{print $1}' | sed 's/://'); do ip rule del pref $i; done
  3. Восстановление маршрута по умолчанию: Убедитесь, что в таблице main есть корректный default route.
    ip route add default via <корректный_шлюз> dev <интерфейс>
  4. Проверка связи: Попробуйте пропинговать шлюз и внешний хост.

Чтобы минимизировать риски, всегда сначала тестируйте конфигурацию PBR в не-продакшен окружении или на виртуальной машине. Также сохраняйте резервные копии сетевых конфигурационных файлов.

Если вы только начинаете работать с Linux-серверами, фундаментальные знания по их настройке и администрированию вы найдете в практическом руководстве по Linux для IT-специалистов.

Дальнейшие шаги и расширение возможностей PBR

Освоив базовые сценарии, вы можете применять PBR для решения более сложных задач сетевой инженерии.

  • Маршрутизация на основе портов (L4): Комбинируя iptables/nftables для маркировки пакетов по порту назначения (--dport) и PBR, можно направлять, например, весь SSH-трафик через один канал, а HTTP – через другой.
  • Интеграция с BGP: В крупных дата-центрах PBR можно использовать совместно с BGP для реализации сложных политик маршрутизации на основе атрибутов сообществ (BGP communities).
  • Контейнерные среды: В Docker или Kubernetes сетевые пространства имен (network namespaces) создают изолированные сетевые стеки. PBR можно настраивать внутри этих пространств для управления трафиком отдельных подов или сервисов.
  • Решение проблем асимметричной маршрутизации: Когда входящий и исходящий трафик для одной сессии идут разными путями, это ломает stateful-файрволы и NAT. PBR помогает обеспечить симметричность, направив ответный трафик через тот же интерфейс, что и исходный запрос. Подробные методы диагностики и решения этой проблемы описаны в статье об асимметричной маршрутизации.

Policy-Based Routing – мощный и точный инструмент в арсенале DevOps-инженера и системного администратора. Он требует понимания принципов работы сетевого стека Linux, но взамен дает детальный контроль над поведением трафика в сложных инфраструктурах. Для углубленного изучения обратитесь к официальной документации пакета iproute2 и man-страницам (man ip-rule, man ip-route).

Для автоматизации сложных ИТ-задач, включая интеграцию с современными API, может пригодиться сервис AiTunnel, который агрегирует доступ к более чем 200 моделям нейросетей через единый интерфейс с оплатой в рублях.

Поделиться:
Сохранить гайд? В закладки браузера