Linux VRF and Namespaces: различия между версиями
Sirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) |
||
| Строка 251: | Строка 251: | ||
<big>'''Добавить маршрут через Route Leaking ведуший в другой VRF (глобальный!)'''</big> |
<big>'''Добавить маршрут через Route Leaking ведуший в другой VRF (глобальный!)'''</big> |
||
<BR> |
<BR> |
||
| − | Это не совсем обычнй маршрут по-тому что указывается <code>dev external</code>, |
+ | Это не совсем обычнй маршрут по-тому что указывается <code>dev external</code>, при этом интерфейс с именем <code>external</code> находится в глобальном VRF |
<PRE> |
<PRE> |
||
ip route add 0.0.0.0/0 via 192.168.22.254 vrf vrf-Red dev external |
ip route add 0.0.0.0/0 via 192.168.22.254 vrf vrf-Red dev external |
||
| + | </PRE> |
||
| + | |||
| + | <code>dev external</code> это не "магическое" слово, просто так переименован один из физических интерфейсов. |
||
| + | <PRE> |
||
| + | ip -d link show dev external |
||
| + | 4: external: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 |
||
| + | link/ether 00:99:00:00:00:03 brd ff:ff:ff:ff:ff:ff promiscuity 0 allmulti 0 minmtu 68 maxmtu 65535 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 parentbus virtio parentdev virtio2 |
||
| + | altname enp0s5 |
||
</PRE> |
</PRE> |
||
Версия 17:33, 30 апреля 2025
Network Namespaces или VRF
Эта статья задумывается как полуперевод-полукомпиляция и возможно с добавлением собственного опыта
Зачем нужен VRF
VRF это способ "виртуализировать" сеть, и иметь несколько полностью или частично независимых экземпляров сетевого стека.
Пример для банального небольшого провайдера на картинке:
Что тут нарисовано
- Есть 2 группу клиентов
- Беспроводные (картинка с 2 антенами это точка доступа). Им нужно строго ограничивать скорость - гонять через выделенный роутер который делает шейпинг. Если их не шейпить, то один клиент сможет занять всю полосу в эфире, остальные на той же базовой станции работать не смогут.
- Проводные, включены на скорости порта. Гонять их трафик через шейпер не только безсмысленно но и вредно - шейпер плохо работает на скоростях выше 50Мбит
|
Вместо шейпера тут может быть например файрволл для гостевой сети, суть от этого не меняется |
- Роутер/L3 свитч куда включены эти клиенты
- Шейпер, пограничный роутер и "интернет" добавлены для наглядности
(тут я не касаюсь L3VPN и вообще VPN ни в каком виде)
Задача описанная выше решается просто на любом более-менее современном L3 коммутаторе
- Для каждой группы клиентов создается свой VRF, своя таблица маршрутизации со своим шлюзом
- Так как шлюзы в разных VRF разные то часть клиентов можно направить через шейпер а другую часть мимо
- На Cisco при желании можно сделать маршрутизацию между VRF - Route Leaking что б клиенты из разных VRF могли общаться друг с другом (в случае интернет-провайдера это сделать можно, в случае с гостевой сетью конечно не желательно)
Это все было банально и все это все и так знают (VRF без MPLS в Cisco называют VRF-Lite)
Вопрос как это все сделать используя Linux
VRF в Linux
Прежде чем говорить о VRF перечислим проблемы которые решает VRF
- Изоляция на уровне L3 - разные VRF имеют независимые таблицы маршрутизации
|
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)
На ней есть
- 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
Route Leaking
Пока все идет по плану, но в vrf-Red есть только один маршрут, и нет маршрута по-умолчанию:
ip ro show vrf vrf-Red 192.168.98.0/24 dev pe1 proto kernel scope link src 192.168.98.101
Добавить маршрут через Route Leaking ведуший в другой VRF (глобальный!)
Это не совсем обычнй маршрут по-тому что указывается dev external, при этом интерфейс с именем external находится в глобальном VRF
ip route add 0.0.0.0/0 via 192.168.22.254 vrf vrf-Red dev external
dev external это не "магическое" слово, просто так переименован один из физических интерфейсов.
ip -d link show dev external
4: external: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 00:99:00:00:00:03 brd ff:ff:ff:ff:ff:ff promiscuity 0 allmulti 0 minmtu 68 maxmtu 65535 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 parentbus virtio parentdev virtio2
altname enp0s5