Динамическая маршрутизация на основе FRRouting
Меня зовут Евгений, я занимаюсь развитием сетевой инфраструктуры в Домклик. Сегодняшняя статья будет охватывать только применение динамической маршрутизации на основе FRRouting (FRR), но, возможно, в будущем я напишу продолжение о том, как конфигурировать другое оборудование, которое вы встретите в тексте.
Задача
Понадобилось мне создать сетевую связность между двумя локациями, но так вышло, что по техническим причинам использовать для этого протоколы семейства IGP (например, всеми любимый OSPF) не представлялось возможным, а вот применить BGP оказалось вполне реально. Из вводных у меня на одной локации имеется два маршрутизатора Juniper MX204, а на второй — среда виртуализации.
Выбор решения
Начал я с изучения интернета и некоторой документации, что, в итоге, привело меня к решению использовать связку из двух виртуальных машин OPNsense с пакетом FRR на борту. Выбор был обусловлен тем, что я получаю знакомый мне межсетевой экран на границе периметра, с которым у меня уже сложились отношения, и возможность в один клик получить динамическую маршрутизацию благодаря простой установке плагина. Ещё одним преимуществом решения послужила отличная возможность поближе познакомиться с FRR на реальной задаче.
OPNsense — это open-source дистрибутив на основе FreeBSD, который из коробки имеет всё необходимое, чтобы стать защитником вашего периметра, включая механизм репликации тех кусков конфигурации, что вы сами выберите. Также он имеет удобный механизм установки дополнительных плагинов (коих много), включая FRR, Bind, Proxy, WireGuard и т.д.
FRRouting — это программный пакет, который на текущий момент позволяет реализовать работу таких протоколов, как OSPF, IS-IS, EIGRP, RIP, PBR, VRRP и т.д. на всех современных *NIX-системах, включая Linux и BSD. Для конфигурирования используется набор Cisco-like команд, что удобно специалистам вроде меня. Иными словами, это очень мощный инструмент с большим набором возможностей, но, конечно, есть и различные ограничения, которые зависят от операционной системы и используемого ею ядра. Исходя из этого рекомендую перед применением погрузиться в документацию. Для примера могу сказать, что мои эксперименты с VRRP на Centos 7 с FRR не принесли ожидаемых результатов, и в этом случае пакет keepalived даёт больше гибкости.
Архитектура
Архитектура решения.
В локации №1 расположены два Juniper MX204, и мы будем считать, что у них уже настроено по одной eBGP-сессии до транспортного уровня и одна iBGP-сессия между ними. Такая конфигурация обеспечивает мне отказоустойчивость.
В локации №2 расположена среда виртуализации, в которой поднято две виртуальные машины с OPNsense на борту. У каждой из них будет по две eBGP-сессии до транспортной инфраструктуры и вообще не будет iBGP. Такое решение связано с моим желанием использовать классическую для межсетевых экранов схему работы кластера: active-passive. Я не планирую прокачивать через эти виртуальные машины большое количество данных, и схема active-active мне тут попросту не нужна.
Локации будут обмениваться трафиком через транспортную инфраструктуру, маршрутизаторы которой просто пересылают между собой анонсы, полученные по BGP от локаций.
Я знаю, что есть много разных способов организовать сетевую связность, например можно было поднять VPN и гонять какой-нибудь OSPF внутри него, но в моём случае выбранная архитектура обусловлена причинами, выходящими за рамки статьи.
Реализация
Берём за основу, что у нас уже установлено две виртуальные машины с OPNSense и настроены базовые параметры, такие как интерфейсы, статическая маршрутизация, правила Firewall, доступы, репликация конфигурации на резервную машину посредством HA и т.д.
На время отладки маршрутизации можно вовсе отключить функционал межсетевого экрана, чтобы ничего не препятствовало движению трафика, правда, вместе с этим отключится и NAT. Для этого надо в Firewall → Settings → Advanced поставить галочку «Disable all packet filtering».
Начнём с установки плагина FRR на наши OPNSense, для этого перейдём в System → Firmware → Plugins и в строке поиска напишем frr.
Чтобы после установки плагина его можно было начать конфигурировать, необходимо разлогиниться из системы и залогиниться обратно.
После успешной установки плагина переходим в Routing → General и включаем FRR, здесь же включаем «Enable CARP Failover». Эта функция позволяет на основании состояния виртуального IP-адреса выключать сервис FRR на резервной машине. Для этого необходимо создать конфигурацию виртуального IP-адреса. Перейдём в Interfaces → Virtual IPs → Settings и создадим новый виртуальный IP-адрес через значок плюсика.
Страница конфигурации Virtual IP.
Думаю, что описывать каждое поле смысла нет, но хочу заострить внимание на паре моментов:
Mode: нужен CARP.
Advertising Frequency состоит из двух значений: Base и Skew. Первое отвечает за частоту обновлений в секунду, а второе — за приоритет, при этом меньшее значение приоритетнее большего, что противоположно VRRP.
После сохранения конфигурации её можно реплицировать на резервную машину по HA, и на ней значение Skew будет автоматически больше, то есть менее приоритетным.
Возвращаемся в Routing и приступаем к настройке протокола BGP. Первым делом включим протокол и зададим базовые значения:
BGP AS Number: номер нашей автономной системы.
Network: список подсетей, которые мы хотим анонсировать.
Базовая конфигурация BGP.
Во вкладке Neighbors настраиваются параметры установления соседства с другим маршрутизатором, в моём случае это eBGP-соседи, расположенные на границе транспортной инфраструктуры. Из обязательного тут нужно настроить IP-адреса соседей и их AS-номера, всё остальное по желанию и зависит от конкретных условий и потребностей.
Базовая конфигурация соседства.
Например, может понадобиться параметр Multi-Hop, когда сосед находится не в одной с вами подсети, или параметр Next-Hop-Self, когда вы хотите в передаваемых анонсах по iBGP менять значение next-hop на адрес локального маршрутизатора (в eBGP этот параметр работает по умолчанию).
Базовая конфигурация меня не устраивает и я хочу её изменить. Первым делом мне нужно выставлять собственный Local preference для получаемых по BGP префиксов. Для настройки этого параметра переходим во вкладку Route Maps и нажимаем плюсик рядом с кнопкой Reload Service. В открывшемся окне задаём уникальное название в поле Name, пусть будет RM-local-pref-150, уникальный номер в ID, выполняемое действие при срабатывании в Action, и вводим команду local-preference 150
в поле Set. Таким образом я буду указывать своему OPNSense, в какой из двух каналов отправлять трафик: чем выше значение, тем приоритетнее.
Local preference 150.
Значение по умолчанию у Local preference зачастую равно 100, но в FRR оно равно 0.
Вторая кастомизация — это сообщить маршрутизатору в транспортной инфраструктуре увеличенный атрибут AS-Path
, чтобы он понимал, какой канал я считаю приоритетным для приёма от него трафика. Для этого создадим ещё один Route map с названием RM-as-path
и другим ID, а в поле Set укажем as-path prepend 65010 65010
. Атрибут AS-Path указывает на количество автономных систем, которые придётся пройти трафику, соответственно, чем он короче, тем приоритетнее.
AS-Path prepend.
Конечно, этот атрибут будет иметь значение только в том случае, если соседский маршрутизатор не выставил у себя локально значения Weight или Local preference таким образом, чтобы канал, в котором мы увеличили путь, всё равно для него являлся приоритетным, так как при выборе лучшего пути атрибут AS-Path учитывается не в первую очередь.
Последнее изменение — установка списка префиксов, которые я буду принимать по BGP, чтобы только они могли попасть в таблицу маршрутизации. Для этого перейдём во вкладку Prefix Lists и создадим новый с названием PF-IN.
Prefix list.
Если требуется описать несколько подсетей для одного списка префиксов, то для каждой настройки должно быть неизменно поле Name, а значение в Number должно быть уникальным, оно выступает тут в роли порядкового номера. Ниже представлен пример, как описать несколько подсетей в рамках одно списка префиксов.
Пример нескольких записей.
Все изменения готовы и теперь их надо добавить в настройки соседства. Для этого вернёмся на вкладку Neighbors и сделаем так:
В Route Map inbound добавляем
RM-local-pref-150
, так как мы регулируем входящие анонсы.В Route Map outbound добавляем
RM-as-path
для того канала, который хотим сделать резервным, эту информацию получит маршрутизатор на границе транспортной инфраструктуры.В Prefix List inbound добавляем
PF-IN
, так как мы фильтруем входящие из анонсов префиксы.
Итоговая конфигурация для eBGP-соседств будет выглядеть так:
Итоговая конфигурация соседств.
По завершении настройки в любой из вкладок находим Reload Service и тем самым перезапускаем сервис FRR, чтобы наша конфигурация применилась и начала работать. Есть возможность увидеть итоговую конфигурацию в формате набора Cisco-like команд, для этого переходим в Routing → Diagnostics → General и идём во вкладку Running Configuration. В ходе экспериментов мне это помогло понять, как применяется та или иная настройка.
Консольная конфигурация FRR.
Результат
Если перейти в Routing → Diagnostics → BGP и выбрать вкладку IPv4 Routing Table, то можно посмотреть, какие подсети мы получили и добавили в таблицу маршрутизации.
Полученные по BGP маршруты.
В других вкладках можно найти массу полезной информации о всём, что связано работой BGP.
В рамках этой статьи я не описывал конфигурацию Juniper, возможно, сделаю по этой теме отдельную статью, а пока предлагаю убедиться, что передаваемые подсети в анонсах FRR успешно достигают Juniper.
Полученные Juniper маршруты.
За сим откланиваюсь и желаю тебе, дорогой читатель, хорошего настроения!