Как использовать полученный посредством OSPF gateway для BGP маршрутов?
Добрый день.
Дано - маленькая SOHO-сеть из 6 площадок (дом, офис, другой дом, сервер в датацентре...) Роутеры на них - или обычные Debian-серверы, или Mikrotik. За каждым из роутеров 1-3 локальных подсетей. Нужна связность всех со всеми. Раньше это решалось единой Wireguard сетью, где все были в пирах у всех. Но в связи с блокировками VPN пришлось заморочиться, разбить единый Wireguard на отдельные тоннели точка-точка, и добавить к этим основным VPN-тоннелям резервные (Amnezia-WG, WG over Cloak). Выживаемость сети в случае пропадания отдельных тоннелей обеспечивает OSPF, через который анонсируются маршруты к локальным подсетям каждой площадки. Если между площадками отвалился приоритетный тоннель (простой Wireguard, ибо он быстрый и стабильный), маршрутизация перекидывается на менее приоритетный (те самые Amnezia-WG или Cloak), если не осталось ни одного прямого тоннеля - то ходим через другую площадку, с которой у обеих сторон связь ещё есть. В общем, тоннелей пришлось завести вагон, но выживаемость сети максимальная. Всё отлично работает.
Дальше больше. Поскольку площадки в разных странах, логично использовать всю эту систему и для обхода географических ограничений (как блокировок, так и установленных самими сайтами). Для этого поднят свой BGP-сервер (bird), который регулярно обновляет списки подсетей из GeoIP-баз и реестра блокировок и раздаёт их роутерам в составе разных BGP communities. BGP используется тупо как способ быстро передавать и вставлять в таблицы маршрутизации сотни тысяч префиксов. Таким образом, роутер в России, например, получает в одном community набор подсетей, заблокированных РКН, и маршрутизирует их через Голландию, в другом - набор турецких подсетей и маршрутизирует их через Турцию. А роутер в Турции получает российские подсети и маршрутизирует их через российский сервер. На роутерах, получающих маршруты по BGP (Mikrotik или тот же Bird), указан filter, который в зависимости от BGP community подставляет gateway.
И вот тут внимательный читатель уже понял проблему :) Пока не было отваливающихся тоннелей и резервных маршрутов, gateway до того самого голландского или российского сервера, турецкого роутера для каждой площадки был всегда один и тот же. Сейчас же в зависимости от того, что отвалится и как отработает OSPF, путь к целевой точке может меняться. Соответственно, надо менять и gateway, который мы указываем в фильтре для входящих BGP маршрутов.
Решение в лоб - написать скрипт, который раз в минуту проверяет состояние линков и соответственно переписывает тот самый BGP фильтр. Но что-то мне подсказывает, что это костыль и должен быть какой-то штатный способ реализовать искомое средствами протокола. Поскольку BGP я использую как тот самый микроскоп для забивания гвоздей :) , то не знаю и 10% его фич.
Подскажите, плиз, в какую сторону можно подумать. В идеале вообще от двух протоколов маршрутизации отказаться бы и использовать или BGP, или OSPF, а не оба, - но насколько я понимаю, BGP не очень подходит для первой задачи (выживаемость сети с множеством дублирующих линков), а OSPF совсем не подходит для второй (распространять толстые пачки внешних маршрутов). В любом случае, благодарю за любые идеи.
P.S. Наверное, ещё забыл упомянуть важный момент. Почему я не анонсирую маршруты по OSPF с того самого хоста, через который они должны маршрутизироваться в итоге? Ну т.е. почему бы голландскому серверу не анонсировать все заблокированные РКН префиксы? Вроде бы, это решило бы проблему.
Но:
а) Во-первых, эти префиксы (которых МНОГО) прилетят и к тем роутерам, которым они вообще не нужны (какое дело турецкому роутеру или другому зарубежному серверу до блокировок РКН)?
б) Во-вторых, даже если оверхед от п. "а" окажется приемлемым, не всем роутерам нужны все префиксы. Сейчас каждый роутер в фильтре принимает те BGP comminities, которые ему актуальны (российский - списки РКН и турецкий GeoIP, турецкий - российский GeoIP и т.п.), а остальные игнорирует. Ну и шлюз тот или иной подставляет, в зависимости от community. В OSPF, вроде бы, есть аналог communities - теги, но работать на Микротике я их не смог заставить. На одном роутере указываешь тег, на другом он его не видит... и судя по гуглению, это by design, а не у меня руки кривые...
Спасибо за ответ, но ничего не понял :)
Мне default route как раз никуда дистрибьютить не надо, он у каждого роутера свой. Надо указать конкретный gateway (тот, который из всех возможных вариантов, ведущих к целевому хосту, сейчас доступен и выбран OSPF), чтобы к отдельным подсетям (полученным по BGP) ходить через него.
с терминологией определитесь )
gateway - шлюз. Обычно понимается как шлюз по умолчанию.
Вы хотите маршрут на какую то сеть из оспф в бгп перенести? Ну так пишите фильтр.
Это делается через redistribute команду. Она позволяет из одного протокола маршрутизации в другой скопировать...
Руслан Федосеев, gateway - это шлюз, конечно, но почему только по умолчанию-то? :)
Я не хочу перенести маршруты из OSPF в BGP. Я хочу использовать для полученных по BGP маршрутов выбранный OSPF шлюз.
Конкретный упрощённый пример я в комментарии к первому ответу привёл.
Если совсем грубо, то хочется следующего:
- роутер получил по BGP пачку подсетей с номером community 100
- роутер знает, что к этим подсетям надо ходить через хост 10.0.0.1
- но к хосту 10.0.0.1 есть много потенциальных маршрутов, конкретный из которых выбирается OSPF
- надо указать шлюзом для этих подсетей тот, через который мы сейчас ходим к 10.0.0.1
Ну или если это невозможно - то достичь того же результата путём пересмотра схемы вообще.
-
- роутер знает, что к этим подсетям надо ходить через хост 10.0.0.1
- но к хосту 10.0.0.1 есть много потенциальных маршрутов, конкретный из которых выбирается OSPF
- надо указать шлюзом для этих подсетей тот, через который мы сейчас ходим к 10.0.0.1
Это всё так и работает по дефолту. Если у вас не работает, значит что-то намудрили :)
Strabbo, как оно работает?
У меня есть маршрут к 10.0.0.1 через 10.0.1.1 и маршрут к 10.0.0.1 через 10.0.2.1. В фильтре BGP я не могу указать или один, или другой. Допустим, я указал 10.0.1.1. А потом этот тоннель отваливается, OSPF меняет маршрут к 10.0.0.1 на 10.0.2.1. А фильтр BGP пытается установить маршрут через уже недоступный шлюз 10.0.1.1.
В фильтре BGP я не могу указать или один, или другой.
не надо ничего указывать. BGP посылает префикс с атрибутом next-hop. В вашем случае насколько я понял next-hop адресса маршрутизируются по OSPF и по дефолут next-hop IP и IP BGP Peer-а будут маршрутизироваться через один и тот же оспф линк.
Strabbo, так, либо я очень туплю (бывает), либо всё ещё не до конца описал задачу.
Попробую ещё раз по порядку на упрощённом примере. Как оно сейчас:
- есть зарубежный сервер 10.0.0.1 (допустим, это адрес его loopback-интерфейса, который анонсируется по OSPF);
- есть российский роутер 10.1.1.1, который очень хочет ходить через 10.0.0.1 на неугодные РКН сайты;
- есть два VPN-тоннеля между 10.0.0.1 и 10.1.1.1, в первом из которых у них адреса 10.0.1.1 и 10.0.1.2, а во втором - 10.0.2.1 и 10.0.2.2 соответственно;
- на VPN-интерфейсах настроен OSPF, так что в зав-ти от того, какой из них поднят, маршрут от 10.1.1.1 до 10.0.0.1 строится или через 10.0.1.1, или через 10.0.2.1;
- есть BGP-сервер (его адрес вообще не важен, ну пусть будет 10.2.2.2), который собирает и парсит реестр РКН и отдаёт его роутеру 10.1.1.1 (и не только ему) по BGP с номером AS 64999 и community 100; каждая строчка с подсетью в конфиге bird выглядит как "route X.X.X.X/X via 10.0.0.1" (но на самом деле пофиг, какое там "via", т.к. мы его меняем на следующем шаге, и для каждого роутера будет свой шлюз);
- 10.1.1.1, получая по BGP маршруты от 10.2.2.2, прогняет их через фильтр "if (bgp-communities includes 64999:100) {set gw 10.0.1.1; accept} reject".
Что конкретно надо поменять в этой системе, чтобы когда тоннель 10.0.1.2->10.0.1.1 отвалится и маршрут до 10.0.0.1 на 10.1.1.1 будет построен OSPF через 10.0.2.1, полученные по BGP маршруты продолжали работать?
Спасибо за уделённое время заранее :)
P.S. Кажется, я понял, что Вы имели в виду (рисовать схемки полезно, наступает просветление :) Если по BGP маршруты будет отдавать не сторонний сервер (10.2.2.2), а сам тот сервер, через который и надо строить маршрут (10.0.0.1) - то он может указать next-hop self, и вместо этого self подставится тот адрес, который сейчас выбран OSPF. Так?
Это надо протестировать и если это работает - это решает одну половину проблемы (хоть и не без сложностей в реализации), спасибо! Но это не решает другую половину проблемы. На самом деле у нас не два роутера в сети, а изрядно больше. И может так получиться, что прямых тоннелей между 10.0.0.1 и 10.1.1.1 не останется живых, но останутся тоннели от каждого из них до какого-нибудь 10.3.3.3, и OSPF построит маршрут именно через этот 10.3.3.3... примерно вот так:
VPN1 отвалился, маршрут до 10.0.0.1 строится через два VPN и промежуточный узел 10.3.3.3. Как рассказать нашему 10.1.1.1, что полученные по BGP маршруты должны теперь идти через шлюз 10.0.2.1?
P.S. Кажется, я понял, что Вы имели в виду (рисовать схемки полезно, наступает просветление :) Если по BGP маршруты будет отдавать не сторонний сервер (10.2.2.2), а сам тот сервер, через который и надо строить маршрут (10.0.0.1) - то он может указать next-hop self, и вместо этого self подставится тот адрес, который сейчас выбран OSPF. Так?
Да, именно так и есть. ну почти :) смотря как построен BGP, Если на лупбеках, то подставится адрес лупбека, который должен знать каждый роутеро отовсюду по оспф. это можно провернуть и со сторонним сервером тоже.
Тут еще есть пару моментов:
1. Если делать EBGP то там next hop self по дефолт указывается IP соседа. в таком случае вам ниче менять не надо, всё само поменяется.
2.в IBGP next hop self сам не меняется. вам надо делать это в фильтре или полисе, когда будуте передавать IBGP IBGP.
3. Ну и последний вариант, не знаю как у вас сделанно в данный момент. но когда вы используете IGP underlay для BGP, то BGP надо строить на loopback(этот интерфейс всегда в UP и его статус не зависит от падения интерфейся/туннеля). Так мы получим топологию OSPF, где мы будем знать все линки до lookback-ов, дальше работает SPF алгоритм и он сам найдет самый короткий путь до loopback-а. Если линк, который используется в данный момент упадет, то оспф сам перестроит маршрут до лупбека и вам ничего нигде не надо менять. Таким образом если хоть один линк(даже если он идет через 10 роутеров) жив и по нему мы знаем лупбек, то траффик от BGP сам будет переключаться автоматически. Если построить BGP на лупбеках и указать next-hop-self, то думаю это то что вам надо.
VPN1 отвалился, маршрут до 10.0.0.1 строится через два VPN и промежуточный узел 10.3.3.3. Как рассказать нашему 10.1.1.1, что полученные по BGP маршруты должны теперь идти через шлюз 10.0.2.1?
Если использовать 3 вариант, то OSPF и BGP сами всё сделают.
10.0.0.1 будет next-hop для BGP роутов. когда отвалится VPN-1, то дорогу до 10.0.0.1 мы узнаем от оспф от соседа VPN-2.
P.S.
Не зная всех деталей, всё-таки думаю что вам надо построить OSPF на всех роутерах и анонсировать в нем лупбеки, а на лупбеках строить bgp, не знаю как в bird/mikrotik но например когда на лупбеках строите в cisco надо указать update source и next-hop self. строите Full mesh ibgp если роутеров мало, если много то смотрите в сторону Route reflector. BGP тема большая, так сразу всё и не подскажешь
Strabbo, вот спасибо за развёрнутый ответ, есть что почитать и в чём дальше разбираться! OSPF уже сейчас на лупбеках, как минимальными силами с BGP извернуться (не становясь экспертом по всем его нюансам :) - буду экспериментировать!
Много воды, пока читаешь - забываешь суть вопроса.
Получить список сетей, затем отдать его в отдельном ospf инстансе, где применить фильтр для подмены шлюза в маршрутах.
Спасибо за ответ. Сорри за "воду", я из того вымирающего поколения, которое ещё умеет читать и писать тексты длиннее 140 символов :)
Предлагаемый вариант не до конца понятен. Сейчас и без отдельного OSPF-инстанса всё работает примерно так же - получаем маршруты по BGP, применяем фильтр для подмены шлюза. Вопрос только в том, что этот шлюз в разные моменты разный, а написать прямо в фильтре "подставь тот шлюз, через который мы в данный момент времени ходим вот до этого хоста" не получится.
Можно вот прямо на пальцах на упрощённом примере?
Скажем, у нас роутер, который должен ходить к заблокированным сайтам через зарубежный сервер 10.0.0.1. К этому серверу у нас два VPN-тоннеля, в первом из них у него адрес 10.0.1.1, во втором - 10.0.2.1. По BGP мы получили 200 тысяч префиксов, которым надо шлюз указать или 10.0.1.1, или 10.0.2.1, смотря через какой из них у нас OSPF сейчас маршрут до 10.0.0.1 строит.
Что конкретно сделать на роутере, чтобы этого достичь? Заранее благодарю.
Вижу, как минимум два варианта решения такой проблемы:
1. С помощью скрипта, отслеживающего изменение текущего GW, и подставляющего измененный в конфиг.
2. Строить eBGP мультихоп, т.е. в качестве GW будет выступать адрес лупбека, а за маршрут до этого лупбека будет отвечать OSPF. Т.о. маршрут до лупбека может динамически меняться в зависимости от ваших реалий, а роутинг с точки зрения BGP меняться не будет.