- PVSM.RU - https://www.pvsm.ru -
Обычно VRF (Virtual Routing and Forwarding, VPN Routing and Forwarding) используется совместно с MPLS, но без оной в терминологии Cisco называется VRF-Lite. Суть этой технологии в том, что маршрутная информация, принадлежащая различным классам (например, маршруты одного клиента) изолируется друг от друга. Считается, что такие возможности есть только у «взрослых» железных решений, но это не совсем так. Благодаря наличию множественных таблиц маршрутизации, гибких политик маршрутизации всё это можно сделать и в Linux. Кому интересно, добро пожаловать под кат.
Прежде чем понять суть происходящего, познакомимся с некоторыми отличительными чертами сетевого стека Linux.
Первый отличительный момент — это специальные типы маршрутов. Когда ip-пакет приходит с какого-нибудь интерфейса, надо определить, адресован ли он этому хосту, или другому. Определяется это довольно элегантно — просто для адреса назначения ищется нужный маршрут в таблицах маршрутизации. Если пакет попадает на маршрут типа «local», значит он адресован непосредственно хосту, если нет, то значит его надо маршрутизировать дальше (при этом дальнейший маршрут уже известен) или сделать что-то ещё, в зависимости от типа маршрутов.
На данный момент поддерживается несколько типов маршрутов (подробнее о них можно посмотреть в мане ip-route, если пишет, что такого мана нет, то обновите пакет iproute на более свежий). Нас в данный момент интересуют только маршруты следующих типов:
Таким образом, для маршрутизации транзитных пакетов нам достаточно наличия маршрута типа unicast, а для того, чтобы хост мог отвечать на пакеты, нужны ещё маршруты типов local и, опционально, broadcast. Ещё следует учесть то, что нам также нужны маршруты direct-connected сетей для того, чтобы обеспечить связность с соседними маршрутизаторами.
Маршруты сгруппированы в таблицы маршрутизации. По-умолчанию изначально в системе присутствуют три таблицы:
Имена таблиц хранятся в файле /etc/iproute2/rt_tables. Под номер таблицы отдано 32 бита, но максимальное количество таблиц в данный момент жёстко ограничено числом 256. Как добавлять/удалять/редактировать маршруты можно почитать в мане к ip-route.
Таблица, в которой надо искать маршруты, определяется политиками маршрутизации. Эта технология называется Policy Based Routing — маршрутизация на основе политик. Суть её в том, что основываясь на каких-либо критериях сетевого пакета мы либо выбираем таблицу, в которой надо искать маршрут, либо определяем действие, которое надо выполнить над пакетом. Каждая политика имеет номер (он может быть даже не уникальным), он же определяем приоритет. Просмотр политик осуществляется в порядке возрастания их приоритетов. Новые политики добавляются перед существующими.
На данный момент «критериями» политики являются
Каждая политика имеет тип, который определяет действие над пакетом, если он под неё попадает:
Теперь небольшой практический пример после скучного введения. Для начала, мы реализуем схему с vrf-lite вручную, а затем уже усложним пример динамической маршрутизацией.
Допустим, у нас есть вот такая схема:
Задача состоит в том, чтобы изолировать трафик различного «цвета» друг от друга. При этом адресные пространства цветов могут пересекаться, что делает задачу ещё более интересной. Неформально сформулируем цель: сделать так, чтобы пакеты каждого цвета не уходили за пределы своей таблицы маршрутизации и передавались только по интерфейсам своего цвета.
Для этого для каждого цвета создадим свою таблицу маршрутизации, и для удобства дадим им имя. Затем, добавим в таблицы direct-connected маршруты принадлежащих цвету интерфейсов. И в конце, добавим политики маршрутизации, чтобы пакеты использовали только свою таблицу.
Сначала назначаем интерфейсам адреса. При этом подключенные маршруты будут попадать в таблицу main, а локальные и широковещательные — в таблицу local.
ip address add 192.168.0.1/24 dev eth0
ip address add 192.168.1.1/24 dev eth1
ip address add 192.168.2.1/24 dev eth2
ip address add 192.168.3.1/24 dev eth3
Добавляем для удобства имена таблиц маршрутизации.
echo "1 RED" >> /etc/iproute2/rt_tables
echo "2 GREEN" >> /etc/iproute2/rt_tables
Добавляем прямые маршруты в соответствующие таблицы. Нужны это для того, чтобы нам были доступны соседние маршрутизаторы.
ip route add 192.168.0.0/24 dev eth0 proto static scope link table RED
ip route add 192.168.1.0/24 dev eth1 proto static scope link table GREEN
ip route add 192.168.2.0/24 dev eth2 proto static scope link table GREEN
ip route add 192.168.3.0/24 dev eth3 proto static scope link table RED
Добавляем остальные маршруты.
ip route add 10.0.0.0/24 via 192.168.2.10 dev eth2 proto static table GREEN
Добавляем политики.
ip rule add iif eth0 pref 10 lookup RED
ip rule add iif eth3 pref 10 lookup RED
ip rule add iif eth1 pref 20 lookup GREEN
ip rule add iif eth2 pref 20 lookup GREEN
Есть один нюанс: что будет, если пакет одного цвета не находит маршрута в своей таблице? Значит, будет продолжен поиск маршрута в других таблицах, что для нас не очень хорошо. Чтобы «запереть» пакет в пределах своего цвета, мы можем в каждую изолированную таблицу добавить маршрут по-умолчанию (либо юникастовый, либо запрещающий), либо после каждой политики поиска маршрута в пределах цвета добавить запрещающую политику. Сделаем для одного цвета первый вариант, а для другого — второй.
ip route add unreachable default proto static table RED
ip rule add unreachable iif eth1 pref 21
ip rule add unreachable iif eth2 pref 21
Так же, желательно перенести все маршруты local и broadcast из таблицы local в таблицы соответствующих цветов, чтобы невозможно было обращаться к локальным интерфейсам маршрутизатора из «чужого» цвета. Для этого лучше всего написать какой-нибудь скрипт, чтобы было не так утомительно.
В итоге, наши таблицы маршрутизации и политики будут выглядеть примерно так:
unreachable default proto static
broadcast 192.168.0.0 dev eth0 proto static scope link
192.168.0.0/24 dev eth0 proto static scope link
local 192.168.0.1 dev eth0 proto static scope host src 192.168.0.1
broadcast 192.168.0.255 dev eth0 proto static scope link
broadcast 192.168.3.0 dev eth3 proto static scope link
192.168.3.0/24 dev eth3 proto static scope link
local 192.168.3.1 dev eth3 proto static scope host src 192.168.3.1
broadcast 192.168.3.255 dev eth3 proto static scope link
ip route list table GREEN
10.0.0.0/8 via 192.168.2.10 dev eth2 proto static
broadcast 192.168.1.0 dev eth1 proto static scope link
192.168.1.0/24 dev eth1 proto static scope link
local 192.168.1.1 dev eth1 proto static scope host src 192.168.1.1
broadcast 192.168.1.255 dev eth1 proto static scope link
broadcast 192.168.2.0 dev eth2 proto static scope link
192.168.2.0/24 dev eth2 proto static scope link
local 192.168.2.1 dev eth2 proto static scope host src 192.168.2.1
broadcast 192.168.2.255 dev eth2 proto static scope link
ip rule list
0: from all lookup local
10: from all iif eth0 lookup 10
10: from all iif eth3 lookup 10
20: from all iif eth1 lookup 20
20: from all iif eth2 lookup 20
21: from all iif eth1 unreachable
21: from all iif eth2 unreachable
32766: from all lookup main
32767: from all lookup default
Собранный в GNS3 стенд показал правильность работы схемы. При обращении к чужому цвету, отправитель получает сообщение о недоступности точки назначения, как и было задумано.
На этом пока всё, но продолжение следует. В нём постараюсь рассказать про динамическую маршрутизацию применительно к vrf с помощью демона маршрутизации bird, и обмен маршрутами между таблицами (vrf leaking).
Автор: EvilMan
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/linux/6582
Нажмите здесь для печати.