Linux VRF and Namespaces: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
Строка 203: Строка 203:
 
На этом настройка CE1 завершена
 
На этом настройка CE1 завершена
   
===111===
+
===vrf-Red===
  +
Создать vrf, назначить идентификатор таблицы маршрутизации (1001 в примере)
 
<PRE>
 
<PRE>
  +
ip link add vrf-Red type vrf table 1001
 
</PRE>
 
</PRE>
  +
Если проверить то сразу после создания можно увидеть интерфейс особого типа - vrf
 
 
<PRE>
 
<PRE>
  +
ip link show vrf-Red
 
</PRE>
 
</PRE>
 
 
<PRE>
 
<PRE>
  +
9: vrf-Red: <NOARP,MASTER,UP,LOWER_UP> mtu 65575 qdisc noqueue state UP mode DEFAULT group default qlen 1000
  +
link/ether ce:f3:16:b7:a0:34 brd ff:ff:ff:ff:ff:ff promiscuity 0 allmulti 0 minmtu 1280 maxmtu 65575
  +
vrf table 1001 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536
 
</PRE>
 
</PRE>
   
  +
Добавить интерфейс pe1 к vrf-Red
 
<PRE>
 
<PRE>
  +
ip link set dev pe1 master vrf-Red
 
</PRE>
 
</PRE>
   
  +
"Поднять" оба интерфейса
 
<PRE>
 
<PRE>
  +
ip link set up dev pe1
 
</PRE>
 
</PRE>
   
 
<PRE>
 
<PRE>
  +
ip link set up dev vrf-Red
 
</PRE>
 
</PRE>
  +
Назначить адрес на интерфейс "в сторону клиента" - pe1
 
 
<PRE>
 
<PRE>
  +
ip addr add 192.168.98.101/24 dev pe1
 
</PRE>
 
</PRE>
   
  +
После выполнения этих команд, можно проверить ping из виртуального клиентского роутера СЕ1 на его шлюз:
 
<PRE>
 
<PRE>
  +
ip netns exec ce1 ping 192.168.98.101
  +
PING 192.168.98.101 (192.168.98.101) 56(84) bytes of data.
  +
64 bytes from 192.168.98.101: icmp_seq=1 ttl=64 time=0.036 ms
 
</PRE>
 
</PRE>
   

Версия 17:27, 30 апреля 2025

Network Namespaces или VRF

Эта статья задумывается как полуперевод-полукомпиляция и возможно с добавлением собственного опыта

Зачем нужен VRF

VRF это способ "виртуализировать" сеть, и иметь несколько полностью или частично независимых экземпляров сетевого стека.
Пример для банального небольшого провайдера на картинке:
VRF 1.png
Что тут нарисовано

  • Есть 2 группу клиентов
    • Беспроводные (картинка с 2 антенами это точка доступа). Им нужно строго ограничивать скорость - гонять через выделенный роутер который делает шейпинг. Если их не шейпить, то один клиент сможет занять всю полосу в эфире, остальные на той же базовой станции работать не смогут.
    • Проводные, включены на скорости порта. Гонять их трафик через шейпер не только безсмысленно но и вредно - шейпер плохо работает на скоростях выше 50Мбит

Icon-caution.gif

Вместо шейпера тут может быть например файрволл для гостевой сети, суть от этого не меняется

  • Роутер/L3 свитч куда включены эти клиенты
  • Шейпер, пограничный роутер и "интернет" добавлены для наглядности


(тут я не касаюсь L3VPN и вообще VPN ни в каком виде)

Задача описанная выше решается просто на любом более-менее современном L3 коммутаторе

  • Для каждой группы клиентов создается свой VRF, своя таблица маршрутизации со своим шлюзом
  • Так как шлюзы в разных VRF разные то часть клиентов можно направить через шейпер а другую часть мимо
  • На Cisco при желании можно сделать маршрутизацию между VRF - Route Leaking что б клиенты из разных VRF могли общаться друг с другом (в случае интернет-провайдера это сделать можно, в случае с гостевой сетью конечно не желательно)

Это все было банально и все это все и так знают (VRF без MPLS в Cisco называют VRF-Lite)

Вопрос как это все сделать используя Linux

VRF в Linux

Прежде чем говорить о VRF перечислим проблемы которые решает VRF

  • Изоляция на уровне L3 - разные VRF имеют независимые таблицы маршрутизации

Icon-caution.gif

C некоторой натяжкой можно считать VRF реализацией Policy Routing

В Linux есть три способа получить разные таблицы маршрутизации для разных групп source адресов

ip rule

Первый, самый старый способ - использовать несколько таблиц маршрутизации
Насколько я помню он был "всегда" :) (пишут что с 99 года, те раньше чем я познакомился с Linux)
Для этого требуется создать табличку маршрутизации (прописывать в /etc/iproute2/rt_tables ну или зависит от дистрибутива если хочется именования)

echo «123 testtable» >> /etc/iproute2/rt_tables
ip route add default via 192.168.22.254 table testtable

Создаем правило, отправляющее нужные пакеты в нужную таблицу:

ip rule add from 192.168.1.20 table testtable 

Или даже вот так

ip rule add iif eth1 table testtable

Недостатки ip rule

Это самый неудобный способ, и он не решает следующие проблемы

  • Пересечение диапазонов IP адресов. Этой проблемы нет в примере, так как адреса клиентов одинаковые, но при желании делать L3VPN она обязательно возникнет
  • Сложность управление и нагромождение ip rule и как следствие линейный поиск по списку с соответвующим падением производительности
  • Проблемы с выбором исходящего интерфейса для локального софта

В целом для относительно небольших и не сложных конфигураций это решение можно применять и оно работает.

ip netns

Примерно с 2009 года для изоляции сети в Linux используют Network Namespaces

  • Полная изоляция (в том числе можно иметь дублирование адресов в разных VRF)
  • Гироко применяется, и более-менее документировано
  • Используют всякие Докеры, Кубернетесы и прочие контейнеры


Подробно описывать я это все конечно не буду (документации просто полно), остановлючь не недостатках

Недостатки ip netns

Я просто оставлю цитаты со своими комментариями: Network Namespace as a VRF? Just say No

  • Сложно делать Route Leaking (когда нужно часть или весь трафик пускать между VRF). Понадобится "виртуальный патчкорд" veth между VRF. Сделать конечно можно, масштабируемость только очень сомнительная.
  • Слишком полная изоляция
  • VRF решает задачу изоляции FIB (при этом не стоит путать FIB и таблицу маршрутизации, FIB содержит лучшие маршруты, тогда как таблица маршрутизации - все маршруты, в том числе полученные от протоколов динамической маршрутизации но не используемые прямо в данный момент как неоптимальные)
  • Неудобно работать - такая простая задача как просмотр всех интерфейсов требует сначала ip netns а потом смотреть отдельно по каждому неймспейсу
  • В целом - управление сетью с netns вместо vrf становится слишком сложный - тот же процесс lldp должен будет запустить столько своих экземпляров сколько есть VRF и это же касается BGPв, и (кроме того что нужно будет написать сои расширения для всех демонов) еще и требует "пропихивания"в апстрим.

ip link add vrf-1

Тут все относительно несложно

Приведу тестовую схему:

VRF 2.drawio.png
(Файл:VRF 2.drawio)

На ней есть

  • CE1 - роутер, имитирующий клиента ( реализован с помощью network namespace)
  • PE1 - виртуальный интерфейс, соединенный с CE1 и добавленный к vrf-Red
  • Глобальная таблица маршрутизации (в общем случае это еще один VRF, просто в него добавлены все интерфейсы по-умолчанию)
  • внешний интерфейс

Настройка

CE1 - "виртуальный клиентский роутер"

В реальной жизни вместо интерфейса veth был бы физический интерфейс, но для тестирования сойдет и так. А вместо CE1 было б отдельное устройство Создать network namespace ce1

ip netns add ce1


Добавить в него интерфейс ce1

ip link set ce1 netns ce1

Интерфес типа veth должен быть предварительно создан, например используя netplan

network:
    version: 2
    virtual-ethernets:
        pe1:
            peer: ce1
        ce1:
            peer: pe1
            dhcp4: false
            dhcp6: false
            addresses: ["192.168.98.1/24"]

Дальнейшие шаги уже требуется выполнять внутри network namespace ce1
"Поднять" интерфейсы lo и ce1

ip netns exec ce1 ip link set up dev lo
ip netns exec ce1 ip link set up dev ce1
<PRE>
Назначить адрес на интерфейс ce1
<PRE>
ip netns exec ce1 ip addr add 192.168.98.1/24 dev ce1

Добавить на виртуальном "клиентском роутере" шлюз "в провайдера"

ip netns exec ce1 ip ro add 0.0.0.0/0 via 192.168.98.101

На этом настройка CE1 завершена

vrf-Red

Создать vrf, назначить идентификатор таблицы маршрутизации (1001 в примере)

ip link add vrf-Red type vrf table 1001

Если проверить то сразу после создания можно увидеть интерфейс особого типа - vrf

ip link show vrf-Red
9: vrf-Red: <NOARP,MASTER,UP,LOWER_UP> mtu 65575 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether ce:f3:16:b7:a0:34 brd ff:ff:ff:ff:ff:ff promiscuity 0  allmulti 0 minmtu 1280 maxmtu 65575
    vrf table 1001 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536

Добавить интерфейс pe1 к vrf-Red

ip link set dev pe1 master vrf-Red

"Поднять" оба интерфейса

ip link set up dev pe1
ip link set up dev vrf-Red

Назначить адрес на интерфейс "в сторону клиента" - pe1

ip addr add 192.168.98.101/24 dev pe1

После выполнения этих команд, можно проверить ping из виртуального клиентского роутера СЕ1 на его шлюз:

ip netns exec ce1 ping 192.168.98.101
PING 192.168.98.101 (192.168.98.101) 56(84) bytes of data.
64 bytes from 192.168.98.101: icmp_seq=1 ttl=64 time=0.036 ms

Ссылки