У стандартній мережевій підсистемі Linux усі мережеві інтерфейси використовують спільну глобальну таблицю маршрутизації — базу даних Forwarding Information Base (FIB). Для звичайних робочих комп'ютерів або серверів з одним підключенням ця централізована модель працює без нарікань.

Однак на шлюзах віртуальних приватних мереж (VPN), пристроях із кількома зовнішніми провайдерами (Multi-WAN) та в корпоративних середовищах із багатьма клієнтами єдина таблиця маршрутизації створює критичні загрози безпеці. Коли різні адаптери перебувають в одному домені маршрутизації, часто виникають конфлікти шлюзів за замовчуванням. У разі аварійного відключення зашифрованого тунелю система може миттєво перемкнутися на фізичний адаптер (Wi-Fi або Ethernet), відкриваючи незашифровані пакети та запити DNS стороннім спостерігачам у локальній мережі.

Раніше мережеві архітектори вирішували цю проблему за допомогою просторів імен Linux Network Namespaces (netns). Хоча netns забезпечують надійну ізоляцію через повне копіювання стека (включно із сокетами, петльовими інтерфейсами, правилами фільтрації та параметрами sysctl), вони спричиняють суттєве навантаження на систему. Пересилання трафіку між просторами імен потребує пар віртуальних інтерфейсів veth або механізмів eBPF, що призводить до зайвих витрат пам'яті для структур sk_buff і зниження швидкості на каналах 40GbE та 100GbE.

Щоб досягти надійного розмежування маршрутизації без витрат ресурсів на віртуалізацію просторів імен, у ядро Linux було інтегровано механізм Virtual Routing and Forwarding (VRF) на базі інфраструктури Layer 3 Master Device (l3mdev).

+--------------------------------------------------------------------------+
|          АРХІТЕКТУРА ІЗОЛЯЦІЇ МАРШРУТИЗАЦІЇ LINUX VRF ТА L3MDEV          |
+--------------------------------------------------------------------------+
|                                                                          |
|   +------------------------------------------------------------------+   |
|   |                   ПРИКЛАДНІ ПРОЦЕСИ USERSPACE                    |   |
|   |                                                                  |   |
|   |   +-------------------+                     +----------------+   |   |
|   |   | Захищений клієнт  |                     | Демон SSH      |   |   |
|   |   |  (ip vrf exec)    |                     | (Управління)   |   |   |
|   +---+---------+---------+---------------------+--------+-------+---+   |
|                 | SO_BINDTODEVICE                        |               |
|                 v (vrf-secure)                           v               |
|   +------------------------------------------------------------------+   |
|   |                       МЕРЕЖЕВИЙ СТЕК ЯДРА LINUX                  |   |
|   |                                                                  |   |
|   |   [ Майстер VRF: vrf-secure ]           [ Загальний стек / main ]|   |
|   |   [ Таблиця FIB: 100        ]           [ Таблиця FIB: 254      ]    |
|   |                                                                  |   |
|   |   Пошук у FIB (Ізольований):            Пошук у FIB (Глобальний):|   |
|   |   default dev riceguard0                default via 192.168.1.1  |   |
|   |   10.8.0.0/24 dev riceguard0            192.168.1.0/24 dev eth0  |   |
|   |             |                                    |               |   |
|   |             |                                    |               |   |
|   |   +---------v---------+                +---------v---------+     |   |
|   |   | Підпорядкований   |                | Фізичний адаптер: |     |   |
|   |   | адаптер riceguard0|                | eth0 (WAN / Wi-Fi)|     |   |
|   |   +---------+---------+                +---------+---------+     |   |
|   +-------------|------------------------------------|---------------+   |
|                 v                                    v                   |
|     +-----------------------+            +-----------------------+       |
|     | Зашифрований тунель   |            | Фізична зовнішня мережа|      |
|     | (Повна відсутність    |            | (Без витоків трафіку) |       |
|     |  витоків даних)       |            |                       |       |
|     +-----------------------+            +-----------------------+       |
|                                                                          |
+--------------------------------------------------------------------------+

Функціонування Linux VRF та драйвера l3mdev

У ядрі Linux інтерфейс VRF працює як драйвер віртуальних мережевих пристроїв (drivers/net/vrf.c). На відміну від просторів імен, майстер-інтерфейс VRF не дублює мережеві структури, а лише пов'язує підпорядковані адаптери з конкретним числовим ідентифікатором таблиці маршрутизації FIB.

Фізичні або віртуальні адаптери призначаються підпорядкованими (slave) пристроями для майстра VRF. Після цього підсистема Layer 3 Master Device бере під контроль обробку пакетів:

1. Межі пошуку у вхідних та вихідних таблицях FIB

Коли IP-пакет потрапляє на підпорядкований інтерфейс, ядро активує обробник l3mdev. Цей драйвер перенаправляє стандартний пошук у FIB на ізольовану таблицю, призначену для цієї VRF (наприклад, Таблицю 100).

Оскільки маршрути всередині Таблиці 100 повністю відокремлені від глобальної таблиці 254, витік маршрутів стає неможливим:

  • Сувора зворотна фільтрація (rp_filter): перевірка адреси відправника здійснюється суто в контексті таблиці VRF, унеможливлюючи приймання підроблених пакетів.
  • Обмеження вихідного трафіку: процеси, закріплені за VRF, не можуть скористатися маршрутами за замовчуванням з основної таблиці системи.

2. Прив'язка сокетів до домену VRF

Програми можуть зв'язувати свій мережевий трафік із доменом VRF за допомогою трьох перевірених підходів:

  1. Опція сокета SO_BINDTODEVICE: процес прив'язує дескриптор сокета безпосередньо до імені майстра VRF (наприклад, vrf-secure). Усі операції читання та запису виконуються через таблицю цього VRF.
  2. Cgroups v2 та команда ip vrf exec: за допомогою механізму BPF cgroup (cgroup/sock_create) системні адміністратори можуть запустити групу процесів у домені VRF без зміни вихідного коду програм.
  3. Опція сокета SO_BINDTOIFINDEX: високоефективний варіант закріплення сокетів за індексом мережевого пристрою без блокування пам'яті.
+--------------------------------------------------------------------------+
|            ПОРІВНЯННЯ ТЕХНОЛОГІЙ: VRF ПРОТИ ПРОСТОРІВ ІМЕН (NETNS)       |
+--------------------------------------------------------------------------+
| Архітектурна ознака    | VRF (l3mdev)            | Простори імен (netns) |
+------------------------+-------------------------+-----------------------+
| Розподіл маршрутів     | Окрема таблиця FIB      | Повна копія стека     |
| Використання пам'яті   | Мінімальне (<10 КБ)     | Відчутне (>1 МБ/netns)|
| Міждоменне пересилання | Zero-copy в ядрі        | Затримки veth та BPF  |
| Простір сокетів        | Спільний для всієї ОС   | Повністю розділений   |
| Керування параметрами  | Централізоване          | Потребує дублювання   |
| Пропускна здатність    | Повна швидкість лінії   | Падає під навантаженням|
+--------------------------------------------------------------------------+

Підтримка мережевих служб за допомогою tcp_l3mdev_accept

Поширеним завданням під час сегментації мереж є робота демонів, що очікують на вхідні підключення. За звичайних умов, якщо локальний DNS-резолвер (як-от Unbound) або служба SSH прив'язані до адреси 0.0.0.0:53, вони приймають запити лише з глобального домену. Інтерфейси з інших VRF не можуть встановити зв'язок через ізоляцію таблиць FIB.

Для вирішення цієї проблеми без запуску додаткових процесів під кожного клієнта ядро Linux містить системні параметри sysctl:

# Дозволити TCP-демонам глобального домену приймати запити з усіх VRF
sysctl -w net.ipv4.tcp_l3mdev_accept=1

# Дозволити UDP-демонам глобального домену приймати пакети з усіх VRF
sysctl -w net.ipv4.udp_l3mdev_accept=1

Після активації tcp_l3mdev_accept вхідний пакет TCP SYN на інтерфейсі VRF зіставляється з глобальним слухаючим сокетом. Під час створення дочірнього сокета ядро автоматично зв'язує його з майстром VRF відповідного інтерфейсу. Усі пакети-відповіді прямують виключно через початкову таблицю маршрутизації.

Практична інструкція: побудова герметичного шлюзу VPN

Налаштування VRF у середовищі Linux здійснюється за допомогою стандартних інструментів iproute2:

Крок 1: Створення майстер-інтерфейсу VRF

Створюємо віртуальний пристрій vrf-vpn, призначений для роботи з таблицею 100:

# Створення інтерфейсу VRF для таблиці 100
ip link add dev vrf-vpn type vrf table 100

# Активація інтерфейсу
ip link set dev vrf-vpn up

Крок 2: Прив'язка інтерфейсів тунелю та клієнтської мережі

Включаємо адаптер тунелю (riceguard0) та локальний клієнтський сегмент (vlan20) до складу vrf-vpn:

# Додавання інтерфейсів до vrf-vpn
ip link set dev riceguard0 master vrf-vpn
ip link set dev vlan20 master vrf-vpn

# Переведення інтерфейсів у робочий стан
ip link set dev riceguard0 up
ip link set dev vlan20 up

Крок 3: Заповнення таблиці маршрутизації VRF

Формуємо правила маршрутизації суто в межах таблиці 100:

# Маршрут до підмережі VPN-тунелю
ip route add 10.8.0.0/24 dev riceguard0 table 100

# Маршрут до локальної клієнтської мережі
ip route add 192.168.20.0/24 dev vlan20 table 100

# Маршрут за замовчуванням виключно через зашифрований тунель
ip route add default dev riceguard0 table 100

Крок 4: Перевірка ізоляції та тестування

Діагностика з'єднання в межах виділеного домену:

# Перегляд маршрутів у таблиці 100
ip route show table 100

# Перевірка зв'язку в межах домену VRF
ip vrf exec vrf-vpn ping -c 3 10.8.0.1

# Контроль головної таблиці системи
ip route show table main

Якщо з'єднання riceguard0 переривається, трафік у Таблиці 100 втрачає шлюз і скидається ядром на рівні маршрутизації. Оскільки фізичний порт eth0 знаходиться в основній таблиці, дані користувачів не потрапляють у незахищену зовнішню мережу.

Архітектурна взаємодія з RiceGuard та VPNRice

В інфраструктурі VPNRice ядровий рушій тунелювання RiceGuard взаємодіє з Linux VRF та l3mdev для досягнення найвищих показників безпеки:

  1. Гарантоване запобігання витокам DNS: клієнтські операційні системи часто надсилають паралельні запити DNS через усі знайдені адаптери. Ізоляція адаптера RiceGuard і резолвера у виділеній VRF блокує вихід запитів у відкриту мережу Wi-Fi.
  2. Маршрутизація Multi-WAN на повній швидкості: шлюзи обслуговують ізольовані сегменти тисяч клієнтів без втрати продуктивності обробки пакетів.
  3. Ізоляція контуру управління: службові порти (SSH, моніторинг) виносяться в окрему управлінську VRF, недоступну для користувацьких тунелів.

Експлуатаційні поради

Під час розгортання систем на базі VRF слід дотримуватися таких правил:

  • Сувора фільтрація адрес (rp_filter): параметр net.ipv4.conf.all.rp_filter=1 блокує спроби підміни адрес між доменами.
  • Єдині правила фаєрвола: використання критеріїв iifname або oifname для майстра VRF у nftables спрощує фільтрацію трафіку.
  • Контроль таблиці conntrack: оскільки VRF використовують спільну таблицю відстеження з'єднань, необхідно заздалегідь збільшити ліміт nf_conntrack_max.

Комбінація Linux VRF та інфраструктури l3mdev надає надійне розмежування трафіку без втрати швидкості, формуючи зразковий стандарт побудови сучасних захищених шлюзів VPN.