Как работает маршрутизатор? #
В сетевых устройствах, таких как маршрутизаторы и 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
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) │ │
│ │ (активные маршруты из всех таблиц) │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘