linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Сеть: L2 / L3/policy-routing

kb/network-l2-l3 ── Сеть: L2 / L3 ── advanced

Policy routing - rule-based маршрутизация

Policy routing - выбор routing-таблицы по src-IP, fwmark, iif, tos. ip rule + ip route table N. Multi-uplink, source-based routing, VRF, split-tunnel VPN. RPDB - Routing Policy Database.

view as markdownaka: policy-routing, ip-rule, rule-based-routing, source-routing, policy-based-routing

Зачем policy routing

Стандартная [[routing-table|routing-таблица]] выбирает next-hop по destination-IP: longest-prefix-match. Этого мало когда:

  • Два uplink-провайдера - трафик источника A в Telecom, источника B в Cogent
  • Source-based routing - "из 10.0.1.0/24 - через провайдера X"
  • Per-tenant routing в multitenant-системе ([[cni-plugins|CNI]], OpenStack)
  • NAT split - пакет с fwmark=0x100 идёт через NAT-машину, остальные напрямую
  • Транзитный трафик через VPN для одного namespace, локально для остального
  • VRF-like изоляция на роутере

Решение: множественные routing-таблицы + правила выбора. Это и есть policy routing.

RPDB - Routing Policy Database

Linux держит набор rules (ip rule list), которые выполняются последовательно по приоритету. Каждое правило говорит "если match - применить эту routing-таблицу". Первое match'и выигрывает.

По умолчанию:

$ ip rule list
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

Три предопределённых таблицы:

  • local (255) - адреса самого хоста, broadcast'ы. Заполняется ядром автоматически
  • main (254) - всё что ты добавляешь через обычный ip route add
  • default (253) - редко используется, для "fallback"

Можно добавлять свои таблицы. Имена/номера таблиц - в /etc/iproute2/rt_tables:

# echo "100 isp_a" >> /etc/iproute2/rt_tables
# echo "200 isp_b" >> /etc/iproute2/rt_tables

Имена - удобство, ядро работает с номерами 0-255 (с lwt-расширением - больше).

Множественные таблицы - пример с двумя uplink

Две внешних линии: eth0 (10.0.1.1 → ISP A) и eth1 (10.0.2.1 → ISP B). Хочешь: трафик из 192.168.10.0/24 идёт через A, из 192.168.20.0/24 - через B.

Шаг 1: добавить таблицы:

ip route add default via 10.0.1.254 dev eth0 table isp_a
ip route add 10.0.1.0/24 dev eth0 src 10.0.1.1 table isp_a
ip route add default via 10.0.2.254 dev eth1 table isp_b
ip route add 10.0.2.0/24 dev eth1 src 10.0.2.1 table isp_b

Шаг 2: правила:

ip rule add from 192.168.10.0/24 table isp_a priority 1000
ip rule add from 192.168.20.0/24 table isp_b priority 1001

Теперь ядро при пересылке смотрит: пакет с src 192.168.10.5 → правило на priority 1000 - использовать isp_a - дефолт через 10.0.1.254 на eth0.

Селекторы правил

ip rule add принимает много селекторов:

СелекторЧто matches
from <prefix>source IP попадает в prefix
to <prefix>destination IP попадает в prefix
iif <name>пришёл на этот интерфейс
oif <name>уходит через этот интерфейс
tos <value>DSCP/TOS-байт
fwmark <mark>netfilter mark на пакете
uidrange <a-b>UID процесса (для local-генерируемого трафика)
l3mdevl3-master (для VRF)
ipproto <proto>IP protocol (TCP/UDP/...)

Действия:

  • lookup <table> - использовать routing-таблицу N
  • goto <priority> - перепрыгнуть к правилу
  • nop - ничего, продолжить дальше
  • blackhole, unreachable, prohibit - дропнуть

fwmark + policy routing - типичный паттерн

Хочешь: HTTP-трафик идёт через VPN, остальное - напрямую. Связка iptables/[[nat|netfilter]] + policy routing:

# mark HTTP-трафик
iptables -t mangle -A OUTPUT -p tcp --dport 80 -j MARK --set-mark 0x100
iptables -t mangle -A OUTPUT -p tcp --dport 443 -j MARK --set-mark 0x100
# routing для marked трафика
ip route add default dev wg0 table 100
ip rule add fwmark 0x100 table 100 priority 500
# marked HTTP/HTTPS теперь идёт в wg0 (WireGuard tunnel)

Этот паттерн используется в:

  • Split-tunnel VPN (только конкретный трафик через VPN)
  • Transparent proxy (mark → routing в локальный proxy)
  • DDoS scrubbing (mark подозрительный трафик → отдельный path)
  • Container networking ([[cni-plugins|CNI]]: mark per namespace → отдельная таблица)

reverse path filter и policy routing

При policy routing часто асимметричный routing - входящий пакет на eth0, ответ через eth1. Стандартный rp_filter=1 (strict mode) сравнивает source с reverse-маршрутом - не сходится - дроп.

Решение - loose mode:

sysctl -w net.ipv4.conf.all.rp_filter=2
sysctl -w net.ipv4.conf.eth0.rp_filter=2
sysctl -w net.ipv4.conf.eth1.rp_filter=2

В loose mode принимается любой src если он reachable through any iface. Иначе ассиметричное routing просто не работает.

VRF - Virtual Routing and Forwarding

Linux 4.3+ имеет VRF-lite - виртуальные routing-instance'ы. Каждый VRF - свой набор интерфейсов и своя таблица routing'а, изолированы друг от друга.

# создать VRF "tenant-a" с table 100
ip link add vrf-a type vrf table 100
ip link set vrf-a up
# добавить интерфейс в VRF
ip link set eth1 master vrf-a
# маршруты добавляются в table 100
ip route add default via 10.0.1.1 dev eth1 table 100

Процесс может быть привязан к VRF (ip vrf exec tenant-a curl ...). Используется в:

  • Multitenant routing на одном Linux-роутере
  • Management plane separation (управление через mgmt-vrf)
  • Cumulus Linux, SONiC, FRR-based маршрутизаторы

Источник пакета: src-routing для исходящего трафика

Если у хоста несколько IP, ядро выбирает src согласно routing'у. Чтобы заставить использовать конкретный src:

ip route add 8.8.8.8 via 10.0.1.254 src 10.0.1.99

Или явно при отправке:

curl --interface 10.0.1.99 https://example.com
ping -I 10.0.1.99 8.8.8.8

Это важно для multi-IP хостов где разные сервисы binding на разные адреса (mail с одного, web с другого).

Очерёдность обработки пакета (упрощённо)

Для исходящего пакета:

  1. Process socket → OUTPUT (mangle, nat, filter chains)
  2. Routing decision: ip rule list → таблица → ip route show table N
  3. POSTROUTING (mangle, nat)
  4. Отправка на link

Для forwarded пакета:

  1. PREROUTING (mangle, nat, conntrack)
  2. Routing decision (forwarding)
  3. FORWARD chain
  4. POSTROUTING

Mangling fwmark в PREROUTING/OUTPUT работает с policy routing'ом (rule с fwmark), потому что mark выставляется до routing decision.

Когда что-то пошло не так

  • Правило добавлено, но не работает - проверь priority. Меньше = выше приоритет. Если from all lookup main (32766) match'ится раньше твоего - перенеси своё правило с priority < 32766.
  • Маршрут добавлен в таблицу, но трафик идёт мимо - убедись правило указывает на эту таблицу: ip rule list | grep <table>.
  • Ассиметричный routing → drop - rp_filter=1. Поставь 2 (loose).
  • ip route get <dst> показывает не то - используй ip route get <dst> from <src> mark <mark> чтобы симулировать твой кейс с RPDB.
  • Правила пропадают после ребута - не сохраняются автоматически. Через NetworkManager dispatcher script, systemd-networkd, либо собственный скрипт в /etc/network/if-up.d/.
  • VRF + сервисы: процесс не видит VRF, пока не запущен через ip vrf exec <name> или socket option SO_BINDTODEVICE.

Полезное

  • ip route flush cache - сбросить routing cache (старая практика, в Linux 3.6+ кэш дезактивирован, но команда осталась)
  • ip rule list table <name> - какие правила указывают на эту таблицу
  • ip route show table all - все маршруты во всех таблицах
  • suppress_prefixlength: правило, которое match только если routing-decision дал prefix короче N - используется в L3 VPN'ах, чтобы default не "перехватывал" специфические маршруты

§ команды

bash
ip rule list

Все правила RPDB в порядке приоритета - кто что lookup'ит

bash
ip route show table 100

Маршруты в конкретной таблице (по номеру или имени из rt_tables)

bash
ip rule add from 192.168.10.0/24 table isp_a priority 1000

Source-based: пакеты из этой подсети используют таблицу isp_a

bash
ip rule add fwmark 0x100 table 100

Пакеты с fwmark 0x100 (выставленным в iptables mangle) идут через таблицу 100

bash
ip route add default via 10.0.2.254 dev eth1 table isp_b

Дефолтный маршрут в кастомной таблице isp_b

bash
ip route get 8.8.8.8 from 10.0.1.99

Симулировать routing decision для конкретной (src,dst) пары

bash
sysctl -w net.ipv4.conf.all.rp_filter=2

Loose RPF - обязательно при policy routing с асимметричным трафиком

bash
ip vrf exec mgmt-vrf curl https://api.internal

Запустить процесс в контексте VRF - его трафик пойдёт через VRF-таблицу

§ см. также

  • routing-tableRouting tableТаблица маршрутизации - список «куда направлять пакеты с таким destination». Самая длинная (longest-prefix) подходящая запись выигрывает.
  • default-gatewayDefault gateway - выход из своей сетиIP-адрес роутера в твоей подсети, куда стек шлёт пакеты для всех адресов, которые **не лежат локально**. Один gateway на хост - но в multi-homed сетапах их может быть несколько.
  • cmd-ipip - швейцарский нож сетевой настройки`ip` - фронт-энд iproute2, заменяет старые ifconfig/route/arp. Подкоманды: `ip addr` (адреса), `ip link` (интерфейсы), `ip route` (маршруты), `ip neigh` (ARP).
  • natNAT и masqueradeNAT - переписывание src/dst адресов пакета на роутере. Masquerade - частный случай: src-IP заменяется на свой исходящий, для исходящих из приватной сети в публичную.
  • cni-pluginsCNI plugins - сеть Kubernetes (calico, cilium, flannel)CNI - спека плагина: дай pod IP и сеть. Реализации: flannel (VXLAN L2-overlay), calico (BGP routing), cilium (eBPF в kernel). Каждая даёт NetworkPolicy для firewall'а между подами. IPAM - часть CNI, выделяет адреса.
  • ip-forwardingIP forwarding - превратить хост в роутерLinux по умолчанию НЕ пересылает пакеты между интерфейсами. Включается через `sysctl net.ipv4.ip_forward=1`. Без этого не работают NAT, VPN-роутер, любой forwarding.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки