Перейти к основному содержимому

Настройка Policy Based Routing (PBR)

·1624 слов·8 минут
DevOps • Networks • Security • Infrastructure
Автор
DevOps • Networks • Security • Infrastructure
DevOps, Expert CyberSecurity, Network/Infrastructure Engineer

Как работает маршрутизатор?
#

В сетевых устройствах, таких как маршрутизаторы и L3-коммутаторы, задача всегда одна — выбрать лучший путь для передачи пакета от источника к назначению. Классическая маршрутизация принимает это решение только на основе адреса назначения — устройство смотрит на поле Destination IP в заголовке пакета и ищет подходящую запись в таблице маршрутизации по принципу «наиболее специфичной маски».

┌─────────────┐    ┌──────────────────┐    ┌─────────────────┐
│ Входящий    │───▶│ Поиск DST IP в   │───▶│ Отправка через  │
│ пакет       │    │ таблице маршрутов│    │ нужный интерфейс│
└─────────────┘    └──────────────────┘    └─────────────────┘

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

┌─────────────┐    ┌──────────────────┐    ┌─────────────────┐
│ Входящий    │───▶│ Анализ по        │───▶│ Применение      │
│ пакет       │    │ правилам PBR      │    │ заданного пути  │
└─────────────┘    └──────────────────┘    └─────────────────┘
                           │
                           ▼
              ┌────────────────────────┐
              │ Если правил нет →      │
              │ классическая маршрут-я │
              └────────────────────────┘

В повседневной практике PBR полезен, например, когда:

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

В этой статье мы рассмотрим практическую реализацию PBR на примере типовой задачи: пустить через VPN только определенный трафик, например, трафик предназначенный для удаленной сети 10.10.10.0/24

Мы разберем три подхода:

  • Классическая реализация PBR правилами маршрутизации (ip rule)
  • Продвинутая реализация с маркировкой пакетов через iptables (mangle)
  • Примеры конфигурации на Cisco и MikroTik для сравнения

Реализация Policy-based routing на Linux (iprule + tables)
#

# 1. Создаем отдельную таблицу маршрутизации (например, FW_VPN с номером 100)
echo "100 FW_VPN" >> /etc/iproute2/rt_tables

# 2. Добавляем маршрут по умолчанию через VPN-интерфейс в таблицу FW_VPN
# Весь трафик, направленный в эту таблицу, идет через tun0
ip route add default dev tun0 table FW_VPN

# 3. Правила для выбора таблицы FW_VPN на основе получателя трафика
# Если пакет пришел для сети 10.10.10.0/24, то используй таблицу FW_VPN
ip rule add to 10.10.10.0/24 lookup FW_VPN priority 100

# Правила для выбора созданной таблицы на основе отправителя и получателя трафика
# ip rule add from 192.168.1.0/24 to 10.10.10.0/24 lookup FW_VPN priority 100

# 4. (Опционально) Включаем SNAT для трафика, уходящего через tun0
# Правило iptables заменяет исходный IP (из LAN) на IP VPN-интерфейса
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
# Сохраняемся
iptables-save > /etc/iptables/rules.v4

# 5. Стандартный маршрут по умолчанию (остается в main таблице)
# Весь остальной трафик идет через основной шлюз провайдера
ip route add default via IP_GW_ISP1 dev eth0

Реализация Policy-based routing на Linux (mangle + iprule + tables)
#

# 1. Создаем отдельную таблицу маршрутизации (например, FW_VPN с номером 200)
echo "200 FW_VPN" >> /etc/iproute2/rt_tables

# 2. Добавляем маршрут по умолчанию в таблицу FW_VPN
ip route add default dev tun0 table FW_VPN

# 3. МАРКИРОВКА ПАКЕТОВ (mangle в iptables)
# Помечаем пакеты, которые должны идти через VPN (трафик к 10.10.10.0/24)
# Метка (fwmark) работает только в пределах локального сервера (внутри ядра) и не передаётся дальше по сети
iptables -t mangle -A PREROUTING -d 10.10.10.0/24 -j MARK --set-mark 1
# Сохраняемся
iptables-save > /etc/iptables/rules.v4

# Трафик к определенному порту (например, SSH)
# iptables -t mangle -A PREROUTING -p tcp --dport 22 -d 10.10.10.0/24 -j MARK --set-mark 1

# 4. ПРАВИЛА МАРШРУТИЗАЦИИ ПО МЕТКАМ (fwmark)
# Все пакеты с меткой 1 идут в таблицу FW_VPN
ip rule add fwmark 1 lookup FW_VPN priority 100

# 5. (Опционально) SNAT для VPN-трафика 
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

# 6. ОСНОВНОЙ МАРШРУТ (для всего остального трафика)
ip route add default via IP_GW_ISP1 dev eth0

Проверка

# Базовая диагностика сети
ip -br a    
ip r        # таблица маршрутизации
ip n        # таблица arp

ping -I 172.29.172.1 8.8.8.8        # нельзя указать mark
traceroute -s 172.29.172.1 8.8.8.8  # нельзя указать mark

# Ключевые route lookup тесты
# Проверка через какой шлюз (маршрут), интерфейс, таблицу и src IP уйдет пакет
ip r g 8.8.8.8 m 1
ip route get 8.8.8.8
ip route get 8.8.8.8 from 172.29.172.1
ip route get 8.8.8.8 from 172.29.172.1 mark 1
ip route get 8.8.8.8 from 172.29.172.1 iif eth0
# Проверка по uid, корректно ли маршрутизируется трафик разных пользователей/приложений
ip route get 8.8.8.8 from 172.29.172.1 uid 1000

# Policy Routing
ip route show table FW_VPN
ip route show table 100
ip route show table all
ip rule show
ip route flush table 100            # очистка таблицы 100
ip rule del priority 50             # очистка с приоритетом 50
ip rule del from 172.29.172.0/24    # очистка с полем откуда

# iptables / marks / nat
iptables -t filter -L -n -v --line-numbers  # таблица filter (default)
iptables -t mangle -L -n -v         # таблица mangle
iptables -t nat -L -n -v            # таблица nat
iptables -t filter -S               # командный вывод правил таблицы filter
iptables-save                       # отобразить все правила, которые можно сохранить
iptables -t mangle -F               # очистка таблицы mangle                   

# Forwarding
sysctl net.ipv4.ip_forward

# TCPDump
tcpdump -nn -i any not port 22      # дампим все, кроме ssh
tcpdump -nn -i any icmp             # дампим только icmp

# Conntrack
conntrack -L --mark 1
conntrack -E --mark 1   
conntrack -D --mark 1               # очистка только с mark 1
conntrack -F                        # очистка полностью

Реализация Policy-based routing на оборудовании Cisco (route-map без VRF)
#

# 1. Интерфейс VPN
interface Tunnel0
 description VPN tunnel to remote network
 ip address 172.16.100.1 255.255.255.252

# 2. ACL для определения трафика через VPN
ip access-list extended VPN-TRAFFIC
 permit ip any 10.10.10.0 0.0.0.255

# 3. Route-map для PBR
route-map VPN-PBR permit 10
 match ip address VPN-TRAFFIC
 set interface Tunnel0 # Отправляем трафик на интерфейс Tunnel0, используя глобальную таблицу маршрутизации

# 4. NAT для VPN-трафика
interface Tunnel0
 ip nat outside

ip nat inside source list VPN-TRAFFIC interface Tunnel0 overload

# 5. Применяем PBR на интерфейсе входящего трафика (LAN)
interface GigabitEthernet0/0
 description LAN interface
 ip address 192.168.1.1 255.255.255.0
 ip policy route-map VPN-PBR
 ip nat inside

# 6. Стандартный маршрут по умолчанию в Интернет
ip route 0.0.0.0 0.0.0.0 IP_GW_ISP1

⚠️ Важные моменты:

  • PBR не меняет существующие маршруты, оно работает поверх стандартного маршрута.
  • Если VPN-туннель интерфейса Tunnel0 не поднят, трафик не пройдёт.
  • Можно добавлять несколько правил с разными route-map sequence numbers для разных сетей.
  • PBR применяется к трафику, входящему на интерфейс (LAN), а не исходящему от маршрутизатора.

Реализация Policy-based routing на оборудовании MikroTik (routing rule + tables)
#

Terminal

# Создаём отдельную таблицу маршрутизации с именем FW_VPN
/routing table add fib name=FW_VPN

# Создаём маршрут по умолчанию в таблице FW_VPN через интерфейс l2tp-out1
/ip route add dst-address=0.0.0.0/0 gateway=l2tp-out1 routing-table=FW_VPN distance=10

# Создаём правило: весь трафик с Destination IP = 10.10.10.0/24 смотрит в таблицу FW_VPN
/routing rule add dst-address=10.10.10.0/24 action=lookup table=FW_VPN

# Опционально. NAT для трафика, уходящего через интерфейс l2tp-out1
/ip firewall nat add chain=srcnat out-interface=l2tp-out1 action=masquerade

Реализация Policy-based routing на оборудовании MikroTik (mangle + routing marks + tables)
#

WinBox

Настраиваем клиента L2TP VPN
Опционально. Настраиваем NAT через туннельный интерфейс L2TP VPN
Отдельная таблица маршрутизации ‘VPN’ для PBR c маршрутом по умолчанию на интерфейс клиента L2TP VPN
Определяем трафик, который нужно направлять в VPN через добавление в список ForwardToVPN
Маркировка пакетов через mangle для списка ForwardToVPN, чтобы они ходили через таблицу маршрутизации ‘VPN’

Terminal

# Добавляем сеть 10.10.10.0/24 в список ForwardToVPN
/ip firewall address-list add address=10.10.10.0/24 list=ForwardToVPN

# Создаём отдельную таблицу маршрутизации с именем FW_VPN
/routing table add fib name=FW_VPN

# Создаём маршрут по умолчанию в таблице FW_VPN через интерфейс l2tp-out1
/ip route add dst-address=0.0.0.0/0 gateway=l2tp-out1 routing-table=FW_VPN distance=10

# Трафик для адресов из списка ForwardToVPN маркируем меткой FW_VPN (mark-routing->new-routing-mark=FW_VPN)
# Далее все пакеты с меткой routing-mark=FW_VPN будут использовать таблицу FW_VPN
/ip firewall mangle 
add action=mark-routing chain=prerouting dst-address-list=ForwardToVPN new-routing-mark=FW_VPN

# Опционально. NAT для трафика, уходящего через интерфейс l2tp-out1
/ip firewall nat add chain=srcnat out-interface=l2tp-out1 action=masquerade

Когда вы в mangle пишете new-routing-mark=FW_VPN, RouterOS автоматически создаёт неявную связь: “пакеты с меткой X смотрят в таблицу с именем X”. Вам не нужно писать ip rule add fwmark FW_VPN lookup FW_VPN, как в Linux. RouterOS делает это автоматически через механизм policy routing.

Как это описано в официальной документации: “Policy routing is implemented as a list of policy routing rules, that select different routing table based on … routing mark (can be changed by firewall mangle rules) of the packet.”

То есть routing-mark — это не просто “наклейка на пакет”, а ключ, который напрямую указывает FIB, какую таблицу использовать.

В MikroTik все маршруты (из всех таблиц) хранятся в едином RIB, но сгруппированы по меткам.
RIB — это центральное хранилище, из которого потом строится FIB для быстрого forwarding’а.

┌─────────────────────────────────────────────────────────────────┐
│                         RIB (Routing Information Base)            │
│                                                                   │
│  ┌─────────────────────┐   ┌─────────────────────┐              │
│  │ Таблица "main"       │   │ Таблица "FW_VPN"    │              │
│  │ (без routing-mark)   │   │ (routing-mark=FW_VPN)│              │
│  ├─────────────────────┤   ├─────────────────────┤              │
│  │ 0.0.0.0/0 via ISP1  │   │ 0.0.0.0/0 via l2tp1 │              │
│  │ 10.0.0.0/8 via ISP2 │   │ 192.168.100.0/24    │              │
│  │ connected routes    │   │     via tun0        │              │
│  │ OSPF routes...      │   │                     │              │
│  └─────────────────────┘   └─────────────────────┘              │
│                                                                   │
│  ┌─────────────────────┐   ┌─────────────────────┐              │
│  │ Таблица "GUEST"      │   │ Таблица "VOIP"       │              │
│  │ (routing-mark=GUEST) │   │ (routing-mark=VOIP)  │              │
│  ├─────────────────────┤   ├─────────────────────┤              │
│  │ 0.0.0.0/0 via ISP3  │   │ 0.0.0.0/0 via       │              │
│  │ ...                 │   │   voip-gateway      │              │
│  └─────────────────────┘   └─────────────────────┘              │
│                                                                   │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│                      MikroTik RouterOS                        │
├─────────────────────────────────────────────────────────────┤
│  ┌───────────────────────────────────────────────────────┐ │
│  │  RIB (Routing Information Base)                        │ │
│  │  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐      │ │
│  │  │ table=main  │ │table=FW_VPN │ │ table=GUEST │      │ │
│  │  │ маршруты    │ │ маршруты    │ │ маршруты    │      │ │
│  │  └─────────────┘ └─────────────┘ └─────────────┘      │ │
│  └───────────────────────────────────────────────────────┘ │
│                              │                               │
│                              ▼                               │
│  ┌───────────────────────────────────────────────────────┐ │
│  │  FIB (Forwarding Information Base)                     │ │
│  │  (активные маршруты из всех таблиц)                    │ │
│  └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

Related

Настройка GRE over IPSec
·1120 слов·6 минут
Как обновить прошивку на MikroTik
·425 слов·2 минут
Подключение через MAC Telnet к MikroTik
·184 слов·1 минута