Алгоритм выбора лучшего пути BGP: порядок сравнения атрибутов и практика назначения политик через route-map.
Что особенного в атрибуте Weight в BGP?
Что означает Hot Potato Routing в контексте BGP?
Гарантирует ли AS Path prepending результат на соседней AS?
Как распространяется Local Preference внутри AS?
Что означает мнемоника NWLLA OMNI в алгоритме выбора пути BGP?
Практика работы с атрибутами BGP: route-map и политики в обоих курсах
bgp-attribute-cisco в cisco-route-2-1 разбирает настройку BGP-атрибутов на Cisco IOS, включая AS-path prepend — практическая реализация теории из bps-as-prepend
Продолжение следует... Есть возможность передавать эти маршруты с определенными атрибутами. Мы с вами посмотрели, какие из атрибутов поддерживаются по стандарту. Это, в частности, NextHop. Это код происхождения Origin. Это Local Preference, который поддерживается только внутри автономной системы. Это Med, который нужен для того, чтобы соседу в другой автономной системе показать два экземпляра одной и той же сетки и сказать, что один из этих маршрутов будет более приоритетный. Это AS Path, который используется для защиты от петель между автономными системами.
И, соответственно... Что, всё, что ли? Вроде всё. Давайте поговорим про то, как с этими атрибутами можно работать в Cisco. Здесь нас ждет ещё один нюанс, который заключается в том, что Cisco IOS работает с атрибутами BGP немножечко необычно. Во-первых, она расширяет атрибуты, которые есть у маршрутов, добавляет к ним некоторые свои проприетарные вендорские атрибуты и тем самым немножко изменяет процедуру выбора лучшего маршрута по сравнению со стандартом. Во-вторых, она поведение даже стандартных некоторых атрибутов будет менять, и поэтому вы должны будете такие вещи знать, если вдруг вы с BGP будете плотно работать. Если вы даже не будете плотно работать, то вы, конечно, можете сказать, что Cisco она и в Африке Cisco, и поведение у неё не то чтобы прямо сильно отличалось от стандартного. Если вы знаете, как работает всё по стандарту, то и в Cisco вы тоже разберётесь. Но всё-таки есть определённая специфика, и на экзамене нужно будет рассказывать про то, как роутер работает именно применительно к этой самой Cisco-специфике.
Давайте разбираться. Первая аббревиатура, которую надо будет запомнить при работе с BGP в оборудовании Cisco, будет называться N-W-L-L-O-M-N-I. Или если вы знаете немножко латынь, то это будет похоже на два латинских слова. Nulla — это немножко похоже на слово nulla, что намекает на ничего, на пустоту. А Omni — это, соответственно, каждый, или всё. Либо ничего, либо всё. Почему эти два слова выбраны? Потому что каждая из этих букв будет означать порядок конкретного атрибута, который будет влиять на выбор лучшего маршрута в алгоритме Best Path Selection. Когда у нас есть несколько маршрутов, которые могут указывать в разные стороны до одного и того же префикса, BGP, как вы помните, должен будет сделать максимальное количество действий для того, чтобы определить один лучший маршрут. Даже если эти маршруты будут идентичны практически, будут похожи друг на друга, как близнецы-братья, всё равно нужно будет из них какой-то один выбрать.
Стандартный алгоритм я вам показывал. Я говорил, что запоминать его на экзамен не обязательно. А вот эту штуку надо будет запомнить. И прямо запомнить с точностью до каждого атрибута, какой атрибут будет в каком порядке проверяться. Естественно, название этих атрибутов вы тоже должны будете запомнить. Просто так запомнить список из достаточно большого количества атрибутов будет тяжело. Поэтому для того, чтобы это упростить, есть мнемоническое правило. Nulla и Omni. Так. Самый первый пункт, который у нас здесь будет, это атрибут NextHop. Для того, чтобы маршрут мог установиться в таблицу маршрутизации и мог считаться лучшим, потому что только лучшие маршруты мы ставим в таблицу маршрутизации, мы должны будем убедиться, что маршрут имеет валидный NextHop. И атрибут NextHop начинается на буковку N, поэтому первую букву будем называть N. Это намекает на NextHop. Это правило отсекает заведомо кривые маршруты. Если BGP получает какие-то маршруты от одного нейбора и от другого нейбора, и у одного NextHop кривой, а у другого NextHop нормальный, соответственно, мы выберем маршрут с нормальным NextHop.
Не то чтобы прямо это был best path selection, это отбор маршрутов, которые заведомо кривые. Поэтому мы здесь отделяем атрибут NextHop чертой, чтобы показать, что это не про выбор лучшего маршрута, это про то, чтобы плохие, заведомо не лучшие маршруты дальше всерьёз не воспринимать. Иногда эти буковки N, W, L, L, O, M, N, I будут пронумерованы, каждый шаг имеет свой собственный номер. Атрибут NextHop это номер 0, потому что он проверяется до того, как мы приступаем к сравнению нормальных живых маршрутов. Дальше первый шаг — это атрибут вес. Фирменный цисковский атрибут, Weight, соответственно, буковка W, будет указывать на то, что вы на своём локальном роутере можете сказать, что один маршрут вам больше нравится, чем другой. Этот атрибут фирменный цисковский, мы его не рассматривали на предыдущих модулях, потому что это проприетарное расширение BGP. Он не передаётся в пакетах BGP, он исключительно в воображении роутера существует.
Роутер получает несколько маршрутов с одной стороны, с другой стороны, и на каждый маршрут он назначает какой-то вес. Вес на один маршрут, вес на другой маршрут. И если приходят два маршрута до одной и той же сети, и роутер в своём воображении на один маршрут назначил вес какой-нибудь 100, а на другой вес 200, то он будет предпочитать тот маршрут, у которого вес будет больше. Автоматически вес никоим образом не расставляется, вы должны будете это руками сделать. Вы должны будете сказать, что конкретно этот маршрут вас интересует больше, чем другой по какому-то правилу. Как вы понимаете, когда у вас есть какой-то интерес, какое-то желание назначить что-то кастомное, то это всегда означает, что у нас есть какая-то политика. А политики у нас реализуются route-map'ами. Чаще всего действительно route-map'ами вы веса будете раздавать. Однако бывают случаи, когда вы хотите просто сказать, что у вас есть сосед, и все маршруты от этого соседа безусловно будут интереснее, чем от любого другого соседа. Поэтому вы на соседа просто говорите: все маршруты от этого соседа будут иметь определённый вес.
Атрибут фирменный, цисковский и очень опасный, потому что он очень мощный. Он самый первый в списке выбора лучших маршрутов, поэтому, если вы его начинаете трогать, то вы очень грубо вмешиваетесь в процесс выбора маршрутов. Если вы используете вес, то вы должны на всех роутерах вес использовать. Фактически вы должны будете на всех роутерах всем маршрутам в одинаковой логике раздавать веса и убедиться, что нигде у вас ваши правила использования маршрутов не будут конфликтовать друг с другом. Атрибут очень мощный, атрибут самый первый в списке, и поэтому если где-то вы ошибётесь, то это будет ваша вина как администратора, что вы раздали противоречивые правила на роутеры. Я вам не рекомендую использовать вес, но на экзамене вопросы про него, конечно же, будут. Второй атрибут называется Local Preference. С ним мы уже знакомы. Это чуть менее мощный атрибут по сравнению с весом, но он стандартный.
И вы можете сказать, что если к вам приходит маршрут до какой-то сети, и у него Local Preference будет больше, чем у маршрута до такой же сети, но полученного от другого соседа, то вы будете предпочитать тот маршрут, у которого Local Preference больше. Эта штука уже передаётся в апдейтах, но только внутри автономной системы. И очень хорошей идеей будет, если у вас есть несколько вариантов, как выйти из вашей автономной системы до какого-то префикса, который к вам прибегает снаружи, вы просто на нужном соседе, с которого вы хотите выходить наружу, проставляете Local Preference на входящие маршруты, и дальше это уже разбегается по всем роутерам в вашей автономной системе. И, как следствие, весь трафик у вас начинает ходить до указанного префикса через выбранную вами точку выхода. Local Preference — самый мощный атрибут среди всех, которые мы с вами изучили, но только после веса, естественно. Поэтому вы, как администратор, можете его переназначить. Сломать что-то с помощью Local Preference очень сложно, поэтому как раз его имеет смысл использовать, если вы хотите сказать, что вам нужно выйти из вашей автономки до какой-то сети, которую присылают вам внешние соседи.
Это шаг номер два. Дальше. Ещё одна буковка L — это Local Origin. Способ происхождения маршрута. Если у вас локально зародившиеся маршруты на вашем роутере будут, они вброшены в ваш BGP локально, при прочих равных, если у вас есть роутер, и у вас есть сосед, который присылает по BGP какой-то маршрут, и у вас есть сосед, который присылает по OSPF какой-то маршрут, условно говоря, и вы этот OSPF выбрасываете в BGP, редистрибутите, вы сами порождаете эту сетку в BGP, сами являетесь автором такой сети, и говорите, что вот я знаю, как добраться до этой сети через OSPF. Это означает, что если у вас есть маршрут, полученный по OSPF, и вы сами придумываете в BGP этот маршрут, то в вашей автономке этот маршрут зарождается. И если вам кто-то говорит по BGP, что я знаю, как добраться до этой сети, но на самом деле он говорит про маршрут, который зародился в вашей автономке, это значит, что BGP для определения лучшего пути до этой автономки использовать не надо.
Это значит, что вы получаете этот маршрут по OSPF, а OSPF учитывает свойства маршрута внутри вашей автономки, он учитывает физические свойства интерфейсов. Поэтому OSPF в этой ситуации лучше будет доверять. Это не про административное расстояние, это про то, что BGP, когда сталкивается с ситуацией, когда у него есть собственный придуманный BGP-шный маршрут и маршрут, полученный по BGP про нашу собственную автономку от кого-то ещё. В этом случае мы говорим: мы придумали сами этот маршрут, потому что у нас есть другой не BGP-шный способ доставить трафик в эту сеть. И мы должны будем руководствоваться требованиями не BGP-шного протокола для доставки трафика. Поэтому мы не верим приходящим BGP-шным маршрутам, мы верим своему собственному маршруту и пытаемся поставить его в таблицу маршрутизации, но там уже, скорее всего, будет всё занято, потому что у нас там есть OSPF, и мы свои собственные придуманные маршруты будем пытаться вбросить с административным расстоянием 200, а OSPF будет там с административным расстоянием 110.
Поэтому мы скажем, что наш собственный BGP-шный маршрут лучше, постараемся его впихнуть в таблицу, там будет уже занято, и мы просто получим вполне ожидаемое поведение, что трафик будет ходить по OSPF. У таких маршрутов, которые мы сами вбросили в BGP, будет нулевой NextHop, и плюс у них будет вес 32 768. На самом деле те маршруты, которые вы будете вбрасывать, они будут сравниваться с чужими маршрутами только при условии, что вы вес им поменяете. Либо вес приходящим маршрутам проставите 32 768, либо вы обнулите вес тому маршруту, который вы сами придумываете. Но по умолчанию те маршруты, которые вы сами вбрасываете, у них и NextHop будет нулевой, и вес будет проставлен в такое значение, которое, как правило, будет больше, чем у любых других маршрутов. Поэтому по факту маршруты, которые вы сами придумываете, по этому правилу не будут предпочитаться.
Они будут предпочитаться по правилу веса. Опять же, вы можете посмотреть show ip bgp в таблицу маршрутизации роутеров и увидеть, что те маршруты, которые вы сами придумываете, у них действительно вес будет кастомный. Дальше сравнивается AS Path. Первый, второй, третий, четвёртый шаг. AS Path указывает, что если у нас есть какие-то маршруты, которые смотрят в две разные стороны до одной и той же сети, то тот маршрут, который проходит через меньшее количество автономных систем, он будет более приоритетный. Этот механизм с AS Path просто руководствуется тем предположением, что все автономки в AS Path могут быть плюс-минус одинаковые. В реальности это, конечно, не так. Если вы видите маршрут, который идёт через одну автономку, и видите маршрут, который идёт через 10 автономок, это не значит, что маршрут через одну автономку будет короче, с меньшим джиттером, с меньшей латенцией, с большим bandwidth.
Это совершенно не так, потому что одна автономка может быть какая-то огромная, а 10 автономок могут быть крошечные, каждая по одному роутеру. И трафик через одну автономку может идти дольше с меньшим bandwidth, с большей задержкой, чем через 10 других мелких автономок. Но BGP говорит, что при прочих равных он не может ориентироваться на физические свойства маршрутов, потому что он их просто не знает, и он будет ориентироваться на AS Path. У кого короче, тот лучший. У кого длиннее, тот лох. Дальше идёт опять черта. И она опять не случайная, потому что эти 4 атрибута используются для выбора исходящего маршрута. Когда у нас есть роутер, к нам приходит входящий маршрут от соседа. Один маршрут, второй маршрут. Мы говорим, какой же из них лучше. Давайте вот этот выберем, поставим его лучшим и будем направлять трафик по нему. И этими атрибутами рулите вы. Когда мы проставляем вес, мы говорим: один маршрут лучше, чем другой.
Это моя администраторская воля. Я говорю, что трафик надо направлять по нему. Local Preference. Та же самая история. Я говорю, что я администратор, я рулю в своей сети. И я говорю: трафик до сети YouTube надо направлять через аплинк Мегафона. Трафик до сети ВКонтакте надо направлять через аплинк условного Ростелекома. Local Origin — он не сильный атрибут в том смысле, что пользоваться им приходится крайне редко. AS Path. То же самое. Вы можете повлиять на AS Path. Вы можете сказать, что если вы видите какой-то маршрут, который приходит из автономки условного того же Мегафона, то вы говорите: мегафоновские маршруты всегда хорошие. Но вы с этими атрибутами реально работаете как администратор. Вы на них смотрите, вы их проставляете и бурно радуетесь жизни. И трафик до внешних сетей по этим атрибутам по факту будет выбирать лучший маршрут в соответствии с вашей волей. Следующие атрибуты будут использоваться пассивно.
Вы как администратор сети не назначаете эти атрибуты. Они сами каким-то образом назначаются, или администраторы чужих сетей назначают их для того, чтобы в вашей сети, в вашей автономке, при прочих равных роутеры выбрали бы правильный маршрут. Первый из этих атрибутов, или пятый в общем списке, будет код происхождения Origin. Это как раз то, что у нас есть маршруты, которые либо взялись в BGP нативно, либо взялись в BGP из EGP, из древнего протокола-предшественника BGP, который был классовый, который был дурацкий. И сегодня мы уже его не встретим. EGP в реальном мире вы не увидите. Incomplete — это чёрт знает откуда пришло. IGP — это нативный BGP-маршрут. Вот лучшая практика: все маршруты, которые в BGP есть, у вас должны быть с кодом IGP, с кодом 0. Фактически вы можете увидеть маршруты, либо которые нативные BGP, либо которые чёрт знает откуда взялись. На самом деле они тоже BGP.
Тут вариантов нету, никакого EGP в 2018 году уже нет. Поэтому в этой логике рекомендуется назначать везде всегда всем отправляемым маршрутам IGP. И в ситуации, когда у вас есть маршруты, у которых код происхождения проставлен, и у которых код происхождения не проставлен, то есть стоит двоечка, в этом случае будут выбираться маршруты с кодом происхождения 0, то есть нативные BGP-маршруты. Дальше. Шестой пункт. Это MED. Тот самый Multi-Exit Discriminator. Тот маршрут, у которого MED лучше, будет, соответственно, лучше. MED проставляет администратор в соседней автономке. Он присылает нам два разных маршрута через два разных аплинка в нашу автономку, и мы трафик по этим двум маршрутам будем отправлять в сторону того маршрута, который администратор соседней автономки попросил нас выбрать. При этом мы знаем, что у этих маршрутов одинаковый вес, потому что иначе до этого пункта просто бы не дошла процедура выбора маршрута, она бы отвалилась на первом пункте.
Мы не проставляли Local Preference, мы не сравнивали AS Path, то есть сравнили и убедились, что они одинаковые. У этих маршрутов одинаковый код происхождения. Эти маршруты — близнецы-братья. Для нас, в принципе, всё равно, как отправлять трафик в сторону нашего партнёра. По оптике ли, по радиорелейке ли, нам всё равно. Но он говорит: я бы хотел, чтобы ты отправлял трафик по оптике, а не по радиорелейке. И он нам проставляет MED на оптике получше, а на радиорелейке похуже. Мы говорим: окей, ладно, если тебе так комфортнее, нам-то всё равно, а тебе комфортнее так — окей, мы будем отправлять так. Мы этот MED не назначаем. Мы согласны по нему работать. Мы не против того, чтобы сосед проставил эти MED'ы. И мы при прочих равных согласны отправлять трафик по тому MED'у, который лучше. Все предыдущие пункты, которые были у нас — вес, Local Preference — числовые пункты, они были, соответственно, чем больше, тем лучше. В случае с MED'ом он чем меньше, тем лучше, потому что это фактически метрика.
И вы можете это запомнить, как то, что в OSPF метрика чем меньше, тем лучше. В EIGRP метрика чем меньше, тем лучше. И в BGP метрика чем меньше, тем лучше. Самого такого атрибута «метрика» нет, но есть MED, который ведёт себя почти как метрика. Дальше пункт 7. N в слове Omni. Это тип соседа, Neighbor. Маршруты, которые получены от EBGP, лучше, чем от IBGP. Если у нас есть маршруты, которые получены от EBGP из чужой автономки, и маршруты, которые получены от IBGP, от своей автономки, соответственно, у них одинаковый AS Path, то эти маршруты пришли на соседний роутер IBGP откуда-то снаружи. Нет смысла занимать свой внутренний канал перед тем, как этот соседний роутер отправит пакет наружу. Потому что этот маршрут до него дошёл всё равно откуда-то снаружи. Мы точно это знаем, потому что AS Path у EBGP-шного маршрута как минимум не нулевой.
А если у IBGP-шного соседа AS Path такой же длины, как у нас, то это значит, что у него он тоже не нулевой. Поэтому этот маршрут у IBGP-шного соседа зародился не в нашей автономке, и нет смысла занимать внутренний канал для того, чтобы потом отправить трафик наружу, если мы сразу можем отправить трафик наружу. У нас нет никаких предпочтений на то, чтобы отправлять трафик через другого соседа, потому что Local Preference не назначен. Нам все равно, через какой линк отправлять, и в этой ситуации лучше отправить сразу наружу, чем кидать картофель из руки в руку. Hot Potato Routing – это как раз то, что чем быстрее отправим соседу, тем лучше. Чем быстрее отправим соседней автономке, тем лучше. Дальше I – IGP-метрика. При прочих равных у нас есть два маршрута, у которых одинаковый AS Path, у которых одинаковый Local Preference, у которых одинаковое практически все. У обоих соседей, которые присылают нам такие маршруты,
это маршруты IBGP-шные, потому что если у нас есть два маршрута, полученных от EBGP-шных соседей, то мы в этом случае постараемся отправить пакет наружу по EBGP. Но если у нас есть два IBGP-шных маршрута, то мы посчитаем, какие NextHop-ы там пришли и отправим пакет по тому маршруту, у которого NextHop к нам будет ближе. Это уже, понятное дело, очень слабый атрибут, мы на него вообще никак повлиять не можем. Мы говорим, что у нас есть наша автономка, в этой автономке несколько роутеров IBGP-шных нам присылают свои маршруты, говорят, у нас тут есть EBGP-шные соседи, которые нам присылают такие маршруты и нам их пересылают. И мы считаем, как можно добраться до NextHop. До одного NextHop можно добраться за 20 копеек, до другого за 200. Тот NextHop, который за 20 копеек в условном SPF будет доступен, до него мы будем посылать трафик. Дальше свойства маршрутов заканчиваются.
Те атрибуты, которые мы видели в EBGP, они все перебрались. Если у нас вдруг осталось больше одного маршрута, который может вести в удаленную сеть, нам нужно уже начинать подбрасывать монетку и каким-то предсказуемым образом выделять лучший маршрут из двух. И дальше у нас срабатывают следующие правила. Если есть два EBGP-шных маршрута, то мы стараемся выбрать тот маршрут, который более стабилен, то есть тот, который был получен и установлен в таблицу маршрутизации первым. Если у нас есть два маршрута, которые получены буквально одновременно, или они оба EBGP-шные и у них одинаковые NextHop по длине, то в этом случае мы будем предпочитать маршруты, полученные от соседа с большим Router ID. Если Router ID у двух маршрутов одинаковый, мы получили один и тот же фактически маршрут от одного и того же соседа по двум разным сессиям, то мы принимаем маршрут, который будет с большим IP-шником соседа.
Последние три шага нужны просто для того, чтобы отказаться от сценария вида: у нас есть два абсолютно идентичных маршрута, и мы могли бы сказать, а давайте сделаем балансировку. Условный OSPF сказал бы, они же прекрасные маршруты, они же абсолютно одинаковые, давайте балансировать трафик. Но BGP не может балансировать трафик. BGP должен выбрать один лучший маршрут. Поэтому он, для того чтобы предотвратить Equal Cost Multipath, говорит: я буду подбрасывать монетку, я буду гадать на кофейной гуще, но я определю один самый лучший маршрут. Даже если лучшим будет маршрут, который получен от соседа с большим IP-шником. Мы на некоторые атрибуты можем повлиять для того, чтобы трафик по маршрутам шел в соответствии с нашими хотелками. Если у нас есть несколько маршрутов, которые мы получаем в таблицу BGP, то мы можем, проставляя определенные атрибуты, добиться того, чтобы наш роутер по процедуре Best Path Selection
выбирал тот маршрут, который будет нам выгоден. И мы можем с определенными политиками, расставив соответствующие атрибуты, заставить наш роутер с помощью этого алгоритма, который я вам рассказал, выбрать маршрут, который нам интересен. Если мы хотим повлиять на исходящий трафик, то есть сказать, что у нас есть несколько маршрутов, которые приходят к нам снаружи, про то, что есть какая-то внешняя сеть, до которой мы можем добраться, и мы можем сказать, что нам больше нравится один маршрут, чем другой, для того чтобы отправлять по нему наши исходящие пакеты. В этой ситуации мы можем повлиять на наши роутеры и заставить их отправлять трафик по более интересному маршруту с помощью двух атрибутов. Либо Weight, либо Local Preference. Local Preference — атрибут стандартный, и он, главное, реплицируется между роутерами. Поэтому, если вы его проставляете, его достаточно проставить в одной точке, и все остальные роутеры поймут, что вы имеете в виду. Атрибут очень сильный, и его удобно использовать.
В подавляющем большинстве случаев рекомендуется использовать для контроля исходящего трафика именно его. Если вдруг вас кто-нибудь когда-нибудь спросит, как в BGP сделать так, чтобы трафик отправлялся по одному маршруту, а не по другому, вы можете смело говорить: надо использовать Local Preference. Cisco говорит: ну конечно же, надо использовать Weight. Вес, фирменный цисковский атрибут, что может быть лучше фирменного проприетарного атрибута. Но Weight плохо использовать, потому что он локальный для роутера, он не передается по сети. Для того чтобы все роутеры в одной логике работали, вы этот Weight должны расставлять везде, на всех роутерах в пределах вашей автономки. И если вы где-то ошибетесь, то накосячить можно очень легко. С помощью Weight вполне можно устроить какую-то нехорошую вещь. Можно будет даже петлю устроить, в принципе. Так. Если мы хотим контролировать входящий трафик, то есть мы про свои сетки или про какие-то сетки, которые транзитные для нас,
рассказываем своему партнеру. И мы хотим, чтобы партнер в нашу сторону трафик направлял по каким-то конкретным маршрутам. Или мы просто говорим: мы отправляем маршруты в интернет, и мы хотим, чтобы интернет к нам присылал трафик по нашим маршрутам, которые мы анонсируем. Если вы покупаете провайдеронезависимые адреса и автономку, вы пиритесь с одним, или с двумя, или с тремя, или с 10, или с 20 провайдерами, и вы анонсируете свои айпишники всем или части из этих пиров, и вы хотите сказать, что вам хочется, чтобы пиры все-все-все использовали бы только один аплинк, один линк в сторону вас. Например, вы компания, у вас есть роутер, у вас есть два канала в сторону двух разных провайдеров, ASP1 и ASP2. Они соединены со всем остальным интернетом. Вы можете, как компания, как роутер компании,
сказать, что трафик, который отправляется в сторону интернета, всегда идет через провайдер 1. Никаких проблем нет. Можно для всего трафика, можно на уровне отдельных префиксов такие штуки сделать. Но все равно это будет именно исходящий трафик. Вы можете контролировать исходящий трафик. Вы можете выбрать из нескольких входящих для вас маршрутов тот один, который вас больше интересует. И вы это делаете локально. Это находится все в вашей зоне ответственности. Но если вы говорите: у меня здесь есть какая-то сетка, вы ее анонсируете, говорите одному роутеру и другому роутеру, что у вас такая сетка есть. Дальше они, в свою очередь, рассказывают про то, как можно добраться до этой сети, отправляют ваши анонсы в интернет. И какой-то узел в интернете говорит: я вижу, что у меня есть сетка А. Он отправляет пакеты в вашу сторону, и никоим образом вы контролировать, именно контролировать, гарантировать определенный способ доставки трафика не можете. Вы можете сказать, что вам больше нравится, например, провайдер 1, и вы все пакеты в сторону внешнего мира отправляете через провайдер 1.
А этот узел, который находится где-то в интернете, может вполне сказать: а мне больше нравится путь 2. И весь трафик, который будет возвратный до ваших айпишников, он пойдет через другого провайдера. Контролировать этот процесс вы не можете. Невозможно сделать так, чтобы гарантированно трафик, входящий в вашу сторону, то есть трафик, противоположный исходящим от вас маршрутам, шел бы по какой-то определенной трассе. Единственное, что вы можете сделать, это не анонсировать определенные айпишники. Если вы скажете, что провайдеру 2 мы нашу сетку не анонсируем, тогда трафик до этой сети через провайдера 2 до вас не пойдет. Но сделать так, чтобы в сторону провайдера айпишники анонсировались, а трафик по ним не шел, такое сделать не получится. Вы можете с использованием очень слабых техник, слабых атрибутов попытаться что-то с этим сделать, но гарантии никто не дает на то, что соседи по проставленным вами свойствам маршрутов будут предпочитать те или иные маршруты. У них в любом случае Local Preference будет намного мощнее, чем то, что вы проставите.
Так, что можно сделать, если у нас есть входящий трафик, и у нас есть два линка до двух провайдеров, и часть трафика валится с одного провайдера, часть с другого, и вы хотите сказать, что мы хотим, чтобы у нас трафик шел через кого-то одного. Если у нас есть один партнер, с которым мы пиримся двумя или больше способами, мы можем использовать MED. Атрибут стандартный, но ненадежный, неудобный, и сфера применимости у него очень ограничена. Это обязательно один сосед, одна соседняя автономная система, в которую мы смотрим двумя разными способами. И только в этой ситуации MED-ом можно сказать: посылай по одному шнурку, но не посылай по другому. Если у нас два разных соседа, то MED использовать не получится. Что можно сделать? Можно использовать технику AS-prepending. Вы, отправляя маршруты, рассказываете, что у вас AS Path будет длиннее, чем он на самом деле. В одну сторону вы говорите, что у нас своя автономка сотая в AS Path,
а в другую сторону вы говорите, что у меня своя автономка сотая, повторенная 5 раз подряд. И длина AS Path в этом случае будет играть роль, потому что один маршрут, который у нас будет получаться через верхнего провайдера, будет с AS Path коротким, а другой маршрут через ASP2 будет AS Path иметь длинный. Например, эта автономная система — у нее в одном направлении AS Path будет иметь длину 2, а в другом AS Path будет иметь длину 5. Естественно, что эта автономка при прочих равных трафик направит через более выгодный в кавычках маршрут, через тот маршрут, у которого AS Path короче. Но эту технику очень не любят провайдеры. Они зачастую фильтруют такие апдейты, которые содержат препенднутые AS Path. Поэтому гарантировать, что у вас эта штука получится, вы не можете. Плюс там есть еще ряд ограничений, которые тоже не дают всерьез рассчитывать на этот атрибут. Иногда он сработает, иногда нет. Что можно еще сделать, если у вас есть два аплинка,
два провайдера, и вы хотите, чтобы трафик в вашу сторону шел по какому-то конкретному маршруту, не по остальным, которые вы анонсируете. Можно попытаться использовать Community. Community – это способ раскрасить трафик. Вы можете сказать, что некоторые маршруты отправляются соседу. И если сосед согласен эти Community использовать каким-то образом для того, чтобы как-то повлиять на ваши маршруты, то вы можете воспользоваться этой техникой. Опять же, все по согласованию, по договоренности с провайдером. Например, провайдер может сказать: я тебе запрещаю использовать prepending в AS Path, ты не можешь взять и проставить много раз номер своей автономки в исходящих маршрутах, если ты не хочешь ходить через меня. Но то, что ты можешь сделать, это ты можешь проставить Community через меня. И тогда я внутри своей автономки буду использовать твой маршрут все равно. А наружу я за тебя препендну эти маршруты.
И все остальные провайдеры будут ходить через другие линки. А я сам, ваш провайдер, все равно буду ходить через тот линк, который смотрит на тебя. Другим при этом анонсирую prepending. Вы можете, если у вас провайдер такие штуки поддерживает, если у вас есть договоренности с ними, таким образом раскрасить трафик, чтобы он что-то подобное сделал. В любом случае, вы с использованием либо prepending AS Path, либо раскрашивания трафика по Community, чтобы провайдер за вас использовал AS Path prepending, либо с помощью MED можете каким-то образом повлиять на чужие роутеры, которые вам не подконтрольны, которые при прочих равных согласны рассматривать то, что вы там проставите в маршруте для того, чтобы выбрать лучший маршрут. Еще раз подчеркну, что гарантировать то, что у вас это получится, здесь нельзя. Это неподконтрольные и очень слабые атрибуты. Давайте разбираться подробнее, какие у нас там атрибуты есть. Самый первый атрибут, который у нас будет в рамках нашего выбора лучшего маршрута,
тот, который Weight. С NextHop все понятно, повлиять на него особо нельзя. Можно, конечно, увидеть, что у вас есть некоторые маршруты с заведомо плохим NextHop, но это само собой разумеется, что вы его должны будете проставить правильно. Поэтому первый атрибут, который у нас есть в списке, это Weight, вес. Фирменный проприетарный атрибут Cisco, не передается в апдейтах, локально значимый для роутера. 16-битное значение, чем больше, тем лучше. Если говорить про маршруты, которые появляются в таблице BGP по умолчанию, там будет вес 0 для маршрутов, которые вы изучаете, и 32768 для тех маршрутов, которые вы генерируете сами. Поэтому если у вас есть какой-то маршрут, который вы сами придумали, как ни странно, по умолчанию этот маршрут будет предпочитаться над всеми остальными именно по атрибуту Weight. Если вы Weight ему проставите 0, то тогда он все равно будет предпочитаться над всеми остальными, но он гипотетически может тогда не быть выбранным лучшим
из-за Local Preference, который кто-то другой вам пришлет и скажет: я знаю лучший способ добраться. По умолчанию для локальных маршрутов, всех, которые в BGP придуманы именно нашим роутером, Weight проставляется 32768, и это очень неплохое значение. Никаких стандартных значений для проставляемых кастомных весов нет. Если вы хотите, вы можете проставить единичку, можете двойку. В любом случае все остальные маршруты имеют вес 0, и поэтому даже если вы единичку проставите на какой-то маршрут, оно уже выиграет по сравнению со всеми остальными. Типичный пример, где можно использовать Weight. Сразу замечу, что если у вас роутеров много, например, 3 или 4, или 5, или 10, Weight использовать становится катастрофически неудобно, потому что вы их должны проставлять ручками, эти веса, и на каждом роутере вы это должны делать согласованно со всеми остальными. Если вы добавляете какие-то новые маршруты, то веса у вас должны будут использоваться опять же в общей логике.
Поэтому, если маршрутизаторов 3, 4, 5 или больше, то Weight противопоказано использовать. Но если у вас всего два роутера, и достаточно часто эта картинка, когда у вас есть своя автономная система, есть здесь какие-то дистрибьюшн-блоки, есть у вас edge-блок, который смотрит наружу, Есть ядро, которое связывает между собой эти блоки, соответственно, они такими треугольниками все соединены друг с другом. Классическая схема, которую мы на самых первых слайдах проходили, как строится сеть предприятия. И среди блоков есть ещё один блок, который называется edge-блок. У нас два пограничных маршрутизатора будут смотреть в весь остальной мир. И вы можете сказать, что да, у нас есть два пограничных маршрутизатора, да, они дружат между собой, да, у нас всего эти два маршрутизатора с BGP работают, больше никто с BGP не работает, они вбрасывают условно дефолтный маршрут, и дальше задача всех остальных маршрутизаторов топологии — догнать трафик до любого живого пограничного маршрутизатора,
а дальше они уже этот трафик направят наружу. В этой ситуации вы можете сказать: если у вас всего два маршрутизатора в BGP, они между собой дружат по IBGP, и дальше у каждого из них есть, например, два или один или два выхода в интернет, EBGP-шных, то вы можете сказать, что те маршруты, которые приходят на один роутер от другого, IBGP-шные, они получают вес, например, 10. Например, на R2 мы говорим: маршруты, полученные от R1, будут иметь вес 10, а маршруты, получаемые от, скажем, запасного провайдера, будут иметь вес 0, штатный вес по умолчанию. И в этой ситуации R1 работал, как будет работать. Для него возникает вариант, какими маршрутами пользоваться. У него некоторые маршруты будут EBGP-шные, некоторые маршруты будут IBGP-шные. Но он говорит: в этой ситуации я буду, конечно же, трафик направлять по EBGP-шным маршрутам. Если вдруг какой-то маршрут есть, который пришёл на R2
и дальше оттуда на R1, либо трафик пришёл на провайдер 1 напрямую на R1, в этой ситуации EBGP-шные маршруты будут интереснее и приоритетнее. В случае же на R2, когда у нас есть вариант, как можно добраться до внешнего мира, можно пустить трафик напрямую на SP2 или можно пойти на R1. В этой ситуации у него получается, что выбор идёт между маршрутами с разными весами. И он говорит: я буду трафик направлять не на EBGP-шного соседа, который там по процедуре NWELA-LOM где-то далеко в списке, давайте точно скажу, где он у нас есть. Вот он, седьмой по счёту. Я буду пользоваться самым первым путём — весом. И соответственно, трафик от R2 до внешнего мира, до каких-то внешних сетей, будет идти через R1 и дальше наружу. В этой ситуации мы можем сказать, что трафик на R2 должен ходить не напрямую в интернет через запасной линк,
а на R1, чтобы он выпустил этот трафик в интернет через основной линк. Это такой классический пример, как можно использовать вес. И если у вас всего два роутера, в принципе, это не самая плохая идея. Это достаточно просто делается. Очень просто вешать на нейбера этот самый вес. Вы можете просто сказать, что всё, что приходит от R1, всё получает вес 10. И вы таким образом очень простым действием добиваетесь того, что трафик у вас весь ходит через основной маршрут, а если только он дохнет, то тогда начинает ходить через запасной. В ситуации, когда у вас роутеров больше, чем два, или когда вам нужно гибко назначать эти веса, сказать, что некоторые маршруты должны ходить через один аплинк, некоторые через другой, вес вам противопоказан. Используйте Local Preference. Как назначать вес? Самый простой способ — это назначить вес просто на нейбера. Мы заходим в настройку нейбера и говорим: нейбер такой-то, вес такой-то. И здесь показывается,
что у нас есть некоторые маршруты. Например, маршрут вот такой. Вот он. Сетка 198, 51, 100, 0. Она доступна через двух соседей с двумя next-hop'ами. 1, 10, 1, 1, 1 — это, судя по всему, next-hop провайдер 1. Другой 10, 2, 2, 2 — это, судя по всему, next-hop провайдер SP2. И у этих маршрутов на R2, соответственно, разные веса. У одного вес 10, потому что мы сказали, что всё, что получено от соседа 101 с 2, 168, 1, 1 — всё должно получить вес 10. На другой мы вес не назначали, у него вес 0. И получается, что в таком раскладе выбирается лучшим и ставится в таблицу маршрутизации тот самый маршрут, у которого вес больше. Если бы мы вес не назначали, в такой ситуации сравнивались бы веса, они были бы нулевые, соответственно, эта процедура не дала бы лучший маршрут. Дальше сравнивались бы Local Preference.
От IBGP-шного соседа был получен в явном виде Local Preference 100, от EBGP-шного соседа был не получен Local Preference, потому что он по EBGP-шной связи не передаётся, но он неявно подразумевается 100. Это значение по умолчанию. Здесь не показывается, что в апдейте его не было, но предполагается, что вы знаете, что дефолтный Local Preference — 100. Local Preference тоже не дал бы результата. Дальше мы бы смотрели, не придумали ли мы сами этот маршрут, какой-нибудь из них. Мы посмотрели, что один next-hop не нулевой, второй next-hop не нулевой. Это не локальные маршруты, не local origin, соответственно, здесь у нас нет. Сравниваем AS Path. Здесь две автономки, здесь две автономки. Тоже не даёт результата. Давайте. N, V, L, L, A, OVNI. Вот, мы находимся здесь. Next-hop одинаковый. Next-hop — оба доступны. Вес одинаковый, если бы мы не проставляли вес.
Local Preference одинаковый. Local origin не применяется. AS Path одинаковой длины. Код происхождения. Это вот эта самая последняя буковка I. В конце списка AS Path — код происхождения. I означает, что это нативный BGP-шный маршрут, или IGP, что это из таблицы маршрутизации маршрут попал напрямую в BGP. Соответственно, у нас код происхождения и там, и там одинаковый. Тоже не даёт нам лучший результат. MED'ы. Опять же, в IBGP-шной связи мы получаем MED'ы. Там проставлен 0. В EBGP-шной связи мы не получили MED. И мы предполагаем, что если мы не получаем MED, то он тоже считается 0 — наименьшее возможное. Поэтому MED нам тоже не даёт сравнения. И вот только в этой ситуации мы говорим: дошли до нейбора, типа нейбора. И в одном случае у нас есть EBGP-шная связь, а в другом случае IBGP-шная связь. Вот эта маленькая буковка I в начале строки означает, откуда пришёл маршрут, по какому соседству, EBGP-шный или IBGP-шный.
Поэтому если бы мы веса не проставили, в этой ситуации лучшим был бы выбран EBGP-шный маршрут по технике Hot Potato Routing. Но поскольку вес мы назначили, то на самом первом шаге мы определили, что надо кидать трафик на соседа IBGP-шного, а он уже дальше разберётся. Такая же история и здесь. Мы на все-все-все маршруты, полученные от IBGP-шного соседа, навесили вес 10, и поэтому все IBGP-шные маршруты на R2 от R1 становятся более приоритетными. Трафик направляется на R1, а он уже отправляет его на EBGP-шного соседа. С помощью только атрибута вес, без помощи других атрибутов, нельзя устроить петлю маршрутизации. Даже если вы скажете, что маршруты, которые приходят от соседа, вы проставляете на них какие-то веса, не получится сделать так, что R1 говорит: я смотрю на R2 и весом считаю,
что его маршрут будет лучше, а R2 говорит: я смотрю на R1 и считаю, что его вес будет лучше. Сделать так не получится по одной очень простой причине. Дело в том, что тот маршрут, который от R1 пришёл на R2, R2 обратно никогда не анонсирует тому же самому соседу R1. У нас IBGP-шное взаимодействие запрещает рефлексить маршруты в сторону того, кто нам их прислал. Поэтому маршрут до R1 лучшим может быть только в той ситуации, если нам R1 его прислал. И R1 не может прислать нам маршрут через самого соседа R2. И он не может сказать, что я вижу лучший маршрут, который до R2, и я его присылаю обратно на R2. Такой просто работать не будет. Если он присылает какой-то маршрут, он смотрит куда-то ещё, и R2 говорит: окей, я вижу, что маршрут есть куда-то ещё, я его могу приоритизировать по сравнению с другими маршрутами, не от R1.
Вы можете назначать вес через route-map, но это надо быть действительно таким упёртым человеком, потому что вес — атрибут грубый. И если вы используете route-map, то есть инструмент тонкой настройки, то просто логически будет, наверное, ошибкой использовать вес там, где вы можете использовать атрибут, который называется Local Preference. Local Preference у нас будет на следующем слайде, и он позволяет достаточно красиво, гибко, и главное, вендоронезависимо настраивать выбор лучшего маршрута. При прочих равных он будет работать лучше, чем вес. Но тем не менее, если захотите, вес можно настроить через route-map, и вот здесь на слайде показано как. У нас есть один префикс-лист, который называется ASP1 Roots. Мы хотим на некоторые внешние сети, приходящие от провайдера ESP1, сделать так, чтобы трафик ходил через них.
ESP1 присылает нам сетки 198, 51, 100, 0 и 203, 0 и 113, 0 по /24 маскам. Мы хотим, чтобы эти и только эти сети всегда ходили через основной аплинк. Соответственно, все остальные сети — не важно, как ходили. В этом случае мы можем на маршруты, полученные на R2 от R1 до этих сетей, вес назначить, а на все остальные маршруты не назначать. Таким образом, мы должны будем сделать route-map, который будет как-то называться, и который будет пермитить всё, но будет пермитить всё по-разному. Некоторые маршруты он будет пермитить с set'ами, а некоторые маршруты он будет пермитить без set'ов. И мы говорим: у нас первое правило route-map'а будет матчить определённые маршруты по префикс-листу и назначать им вес — set weight 10. А второе правило route-map'а будет матчить все маршруты и ничего с ними не делать, он будет просто пермитить. Поэтому какие бы маршруты от R1 ни пришли, они в любом случае будут приняты в таблицу BGP,
мы ничего не дискардим, но некоторым маршрутам мы проставляем вес 10, а некоторым оставляем вес 0. И в этой ситуации роутер R2 действительно будет выбирать между маршрутами хорошими с точки зрения веса и плохими, только если у них будут правильные IP-адреса. И правильные IP-адреса получат вес 10, трафик до этих сетей будет ходить через SP1. Все остальные сети будут направляться напрямую в сторону провайдера 2, потому что мы им веса не проставили, и EBGP-шные соседи будут выигрывать у IBGP-шных. Если мы хотим сделать то же самое, но стандартным образом, мы можем проставить Local Preference. Это стандартный атрибут, он передаётся в апдейтах, он поддерживается обязательно любыми реализациями BGP. Если вдруг у вас есть два роутера и один из них Cisco, а второй не Cisco, то они оба в любом случае Local Preference будут поддерживать. И вы проставляете Local Preference в точке получения маршрутов из внешней автономной системы, то есть на
вашем бордере, и дальше эти маршруты передаются на все остальные роутеры с проставленным Local Preference таким, который вы хотите. По умолчанию 100 для всех маршрутов, которые вы получаете. Если вы сами генерите какие-то маршруты или если вы получаете маршруты от соседа IBGP-шного, то у них Local Preference будет как раз 100. Если вы дружите с соседом по EBGP и сосед не присылает вам Local Preference — он не присылает, — то и show ip bgp не показывает вам значение Local Preference, но оно будет значением по умолчанию. Дальше, если вы дружите с соседом по IBGP и вы чем-то, например route-map'ом, этот самый Local Preference проставляете, то в show ip bgp будет показан Local Preference для конкретно этого маршрута. Это 32-битное число, не 16-битное как вес, 32-битное. Больше — лучше. Значение по умолчанию — 100. В IBGP-шных
апдейтах она обязательно передаётся, в EBGP-шных апдейтах она никогда не передаётся, её запрещено передавать через EBGP-шную связь. Она передаётся на все роутеры в своей локальной автономной системе, но не передаётся соседям в EBGP, в другие автономные системы. Именно поэтому называется атрибут Local Preference. Вот пример: у нас есть провайдер один и Провайдер 2 — маршруты, приходящие от провайдера 2, получают дефолтный local preference 100. Это значение в скобках намекает на то, что она не передается по сети. Но R2 говорит: я не буду модифицировать значение по умолчанию, и маршруты, полученные через SP2, будут иметь local preference 100. Маршруты, полученные на R1 от провайдера 1, тоже будут без local preference атрибута, но R1 будет говорить: я переназначаю значение по умолчанию на 100, я хочу переназначить local preference, сделать его 150. И на R1 эти маршруты будут иметь local preference 150. В исходящих апдейтах от R1 до R2 local preference
проставляется в явном виде всегда, и там тоже 150 будет стоять. И R2 в этой ситуации говорит: у меня есть маршрут от провайдера 2 с дефолтным local preference, у меня есть маршрут через R1 с большим local preference, чем у SP2. И в этой ситуации R2 тоже посылает трафик через R1, но в этом случае он уже верит тому атрибуту, который приходит в апдейте. По сравнению с весом, в этой ситуации будет отличаться то, что если вы играете весом, то вы это делаете на каждом отдельном роутере. В частности, в нашей ситуации нужно было играть весом на R2. В случае если вы играете local preference, то играть local preference надо на бордере, который смотрит наружу — в нашем случае на R1. Поведение вроде бы одно и то же, но в случае с весом ответственным за правильность реализации будет каждый роутер топологии, который выбирает лучшие маршруты. В нашей ситуации это будет R2. Если будет какой-то
еще роутер вот здесь, R3, на нем тоже надо было бы играть весом. На каждом роутере мы бы должны были правильно расставить веса, чтобы трафик отпустить в нужную нам сторону. В случае с local preference вы только на одном роутере, который поставляет этот local preference, на пограничном роутере, проставляете его, и дальше все роутеры понимают, что надо пускать трафик через вас. Ситуация, когда у вас хотя бы три роутера есть, уже имеет смысл использовать local preference и не использовать вес. Как проставлять этот самый local preference? Если у вас есть бордер, который заведомо лучше, чем любой другой бордер топологии, вы можете сказать, что на одном из роутеров все маршруты, которые зарождаются в нашей автономке на этом роутере или получаются от EBGP-шных соседей на этом роутере, мы придумываем local preference какой-то нестандартный — по умолчанию 100,
мы придумаем какой-то не по умолчанию, например 150. И эта команда будет bgp default local-preference и дальше число. Не часто такая штука используется, но ситуация, когда у вас есть два бордера и один из них заведомо лучше, чем другой, вы можете использовать — она достаточно неплохая. Альтернативный вариант — использовать route-map. Это чаще всего как раз у вас и будет, когда вы route-map на некоторые маршруты говорите set local-preference при приеме маршрутов от соседа. И вы на этого соседа вешаете route-map. В нашем случае — neighbor чего-то там route-map rem-set-lp in. Все маршруты, которые приходят от этого соседа, мы проверяем route-map, мы их матчим и соответственно над ними как-то издеваемся. Здесь вы видите, что у нас правило route-map состоит всего из одного блока, и
в этом блоке мы матчим все — у нас нет команды match, поэтому матчится все, она все пермитится, и всему local preference 150 будет присваиваться. Это делается на R1, на том бордере, который принимает маршруты. Все маршруты от EBGP-шного соседа мы пробиваем local preference 150 и дальше анонсируем всем остальным нашим внутренним роутерам LP 150. Все маршруты, которые будут иметь LP 150, будут выигрывать у других маршрутов от других внешних роутеров, у которых local preference будет 100. Поэтому трафик будет направляться через нас во внешние миры. Опять же, есть у нас команда show ip bgp, и у нас маршрут выбирался лучший из двух вариантов, как можно выйти во внешний мир. Сетка 198.50.11.0/0 на R2 — на нижнем роутере. R2 думает, как бы мне пойти во внешний мир. Он смотрит: next hop — вроде одинаковые, хорошие,
оба доступны, и мы можем их использовать. Вес не проставлен — и тут и тут нули. Дальше сравниваем local preference, и local preference вот здесь 150, потому что R2 получает local preference 150 в явном виде от IBGP-шного соседа. А здесь он не проставлен, и это будет local preference 100, потому что маршруты по EBGP приходящие получают local preference по умолчанию. Если бы мы на R2 вбили команду bgp default local-preference с каким-то другим числом, то был бы шанс получить там другое значение, не 100. Но по умолчанию local preference получается для EBGP-шных маршрутов со значением 100. Поэтому 150 выигрывает у сотки, которая здесь не показана, но неявно подразумевается. И лучшим маршрутом выбирается через R1. Если бы local preference был бы дефолтный, дальше мы бы сравнили, что next hop ненулевые в обоих случаях, длина AS path одинаковая — и тут и тут две автономки, origin code нативные, BGP-шные маршруты, MED не проставлены или
проставлены нулями. И дальше тип маршрута — IBGP-шный или EBGP-шный. Вот только в этой ситуации hot potato routing сказал бы: отправляем по EBGP сразу напрямую на выход из нашей автономки пакеты по этому маршруту. Но за счет того, что мы local preference пробили, до этого пункта сравнение не дошло, и лучший маршрут был выбран IBGP-шный, потому что local preference у него больше. С AS path манипулировать — AS path имеет смысл только если вы хотите сделать prepending. С ним больше ничего особо не сделаешь. Длина его сравнивается автоматически, добавляется один раз номер своей автономки в исходящие sequence тоже автоматически на EBGP-шных соседствах. Но мы можем дополнительно к тому, что мы при выходе из нашей автономки добавляем один раз свой номер автономки, дополнительно сделать prepending — сказать, что в исходящих маршрутах у нас
будет искусственно длина AS path испорчена. Вы не можете проставлять что попало в исходящих этих самых анонсах, потому что если вы будете писать что-то отличное от номера своей автономки, то вы тем самым будете проставлять там какие-то другие номера автономных систем. И в этом случае, если вы проставите, например, номер автономной системы какой-нибудь, не знаю, 123, то маршрут от вас в автономку 123 уже больше никогда не сможет войти, поскольку AS path используется для защиты от петель. Правило: если мы получаем маршрут и мы видим номер своей автономки в AS path, то такой маршрут отбрасывается. Это правило будет указывать на то, что если вдруг мы в prepending указываем какие-то левые номера автономных систем, то тем самым мы запрещаем нашим маршрутам распространяться в эти автономные системы. Но если мы несколько раз свой номер
автономки подряд пишем, то мы никому не вредим, мы нашим маршрутам разрешаем распространяться где попало и просто несколько раз повторяя свой собственный номер автономной системы, искусственно завышаем длину AS path. Настраивается через route-map. Чаще всего вы хотите AS prepending использовать на EBGP-шных соседствах, чтобы у вас внутри автономки все распространялось как полагается, а в точке выхода маршрутов из вашей автономной системы вы бы маршрут немножко испортили. Выглядеть это будет следующим образом. У нас есть наш какой-то роутер, у него есть способ добраться до сети A. Он про эту сетку рассказывает своим внутренним IBGP-шным соседям, те рассказывают про эту сетку EBGP-шным соседям. Поскольку маршрут зародился внутри нашей автономной системы, он изначально имел AS path пустой. Сейчас к нему добавился номер
своей автономки. Здесь добавили просто 10, а здесь мы добавили просто 10 и еще три раза дополнительно 10 — сделали тот самый AS prepending. В этом случае через R1 маршрут ушел с длиной AS path единичка, а через R2 маршрут ушел с длиной AS path четверка. Дальше маршрут верхний через R1 получил провайдер 1, дальше передал его какому-то другому провайдеру третьему, добавил свой номер автономки 11, и то, что там раньше было, 10. Провайдер 3 получил такой маршрут, сказал: я знаю, как добраться до 10-й автономки, маршрут должен пройти через 13-ю, мою автономку, через 11-ю, моего соседа, и дальше попадет в 10-ю. И провайдер 2 получает два анонса: один напрямую из нашей автономки с четырьмя элементами в AS sequence и другой маршрут с тремя элементами в AS sequence. И несмотря на то, что 12-я автономка подключена напрямую к нашей 10-й, именно маршрут до сети A становится выгоднее
вот так в обход. И если вдруг какой-то пакет придет на провайдера 2, он будет идти по такой кривой трассе. Если у нас есть запасной канал, как раз это поведение будет предпочтительным — этот маршрут он используется только в одной единственной ситуации, когда основной маршрут совсем сдох. В этой ситуации даже испорченный префикс с помощью AS prepending все равно становится выгодным, потому что он единственный доступный. И какая разница, какая там длина AS path — все равно только один, он уже никак ни у кого не получится проиграть, потому что более выгодных кандидатов просто не будет. Далее, как настраивается AS prepending. Вы должны понимать, что в любом случае, если вы настроили prepending или не настроили prepending, когда вы отправляете маршрут по EBGP-шному соседству, вы в абсолютно любом случае добавляете
свой номер автономки. Поэтому если у вас есть на текущем вашем роутере-бордере маршрут и у него сейчас длина AS path 3, то, отправив маршрут по EBGP-шному соседству соседу, вы обязательно добавите туда свой номер автономки, и у вас получится длина AS path 4 на соседнем роутере. Это не сосед добавит, это именно вы добавите. Но вы можете дополнительно к тому сделать prepending и добавить кроме одного раза этого самого номера своей автономки еще какие-то дополнительные разы с помощью prepending. И делается это на исходящих маршрутах от вас в сторону вашего соседа через route-map. Опять же, мы говорим, что у нас есть route-map, который называется setAspath. Пермитим все, что есть. Можно слово permit не писать, номер пункта тоже можно не писать, просто route-map setAspath. И указываем set as-path, дальше ключевое слово prepend, и все, что вы хотите написать в AS path дополнительного, вы добиваете туда.
В нашем случае, если наш номер автономки 65500, то вы несколько раз пишете свой номер автономки 65500. Это именно дополнительно к тому, в кавычках, бесплатному номеру своей автономки, который вы в любом случае пошлете. Вы гипотетически можете вписать здесь все, что угодно, но практически ничего, кроме своего номера автономки, тут писать не стоит. Это прямо нехорошо. И в некоторых реализациях вам это просто не позволят сделать. Дальше. Вешаем на neighbor. Neighbor 10.2.2.2. Route-map setAspath out. И мы тем самым говорим, что все маршруты, которые мы отправляем в сторону этого neighbor, они должны пройти через route-map. Что-то route-map дропнет, скажет deny. Мы тогда, если route-map на конкретный маршрут сказал deny, его просто не отправляем соседу. Что-то route-map пермитнет. Но пермитнет он не просто так, а с какими-то set-ами.
И мы на выход в сторону соседа будем отправлять маршруты, немножко модифицированные, в нашем случае как раз с помощью AS path. И таким образом мы можем добиться того, чтобы определенные маршруты, которые мы по route-map будем портить, соседу по EBGP отправлялись испорченными. И в результате у нас есть провайдер 2. Напомню топологию: у нас есть наш роутер R1, наш роутер R2, провайдер SP1, провайдер SP2 и здесь какой-то провайдер SP3. Здесь у нас вот такие связи. И на R2 мы отправляем маршруты, испорченные с помощью prepending. В результате провайдер 2 ходит на нашу сетку через транзитный путь, который более длинный, не напрямую, а в обход через провайдер 3, провайдер 1. Мы видим, что у нас есть какая-то сетка, которую мы в интернет заанонсили. Не часто такое случается, что анонсируется частная сеть, как 192.168.11.0 или 12.0.
В нашем случае мы видим, она действительно якобы показывается. На самом деле, как вы понимаете, она могла бы быть и не частная, она могла бы быть публичной, просто почему бы и нет. Обратите внимание, кстати, на команду show ip bgp. Если вдруг у вас в таблице реально много префиксов, то вы не хотите просто show ip bgp делать. Вы хотите посмотреть только определенные маршруты, которые вас интересуют. И можно заказать IP-шник той сети, которая у вас есть. А можно сказать, что вас интересуют все маршруты, которые входят в какую-то большую сеть. В нашем случае мы, например, хотим посмотреть все маршруты, которые будут 192.168 по 16-й маске или мельче. И тогда мы указываем IP-шник с маской и добавляем ключевое слово longer-prefixes. Очень удобная вещь, которой можно отобрать все маршруты, являющиеся частью какой-то сети. И мы видим, что у нас есть 192.168.2.11, 192.168.22.0.
У SP2 есть маршрут напрямки, есть маршрут в обход. Маршрут напрямки через next hop вот такой. Вес дефолтный, local preference дефолтный, метрика дефолтная. Но AS path у маршрута напрямую через нашего R2 получается длинный. Один раз 65500 добавилось, потому что это EBGP-шное соседство нам его прислало. И еще три раза подряд мы добавили с помощью техники AS prepending. А маршрут через провайдер 3 тоже local preference дефолтный, вес дефолтный, метрики MED тоже дефолтные. Но AS path здесь покороче получается. Маршрут пришел через 65300-ю автономку, туда он попал через 65100-ю автономку, туда он попал из 65500-й автономки. И длина AS path получается на единичку меньше. Аналогичная история с сеткой 192.168.22.0. Тоже выигрывает тот маршрут, у которого вес такой же,
local preference такой же, но длина AS path на единичку меньше, чем у другого. Таким образом вы можете немножко портить исходящие маршруты, отправляемые с вашего роутера, но портить не сильно, а так, чтобы он только проиграл какому-то другому маршруту, который вы тоже отправляете. Вы, конечно же, заранее не знаете топологию всего интернета, не можете гарантировать, что, испортив тремя разными prepend-ами свои маршруты, обязательно получится, что весь трафик до вашей сетки, анонсируемой вами, или до таких транзитных сетей, которые вы анонсируете, будет ходить через один аплинк. Во-первых, вы не можете гарантировать, что сосед будет сравнивать длину AS path, что он не штампует local preference, не штампует веса. Вот как раз провайдер 2 — мы смотрим, что он принимает маршруты, которые имеют разные длины AS path, и он действительно их сравнивает. Но никто ему во всем мире не может запретить проставить здесь local preference 200.
И он будет говорить, что вот этот next hop мне больше нравится. Простите, но я не буду сравнивать AS path, я буду ходить по тому local preference, который будет больше. Вы не можете проконтролировать, что будут делать другие. Поэтому вы можете испортить маршруты — можете. Вы можете заставить соседа использовать тот маршрут, который вы не испортили? Нет, не можете. Более того, вы не можете гарантировать, что маршрут, который вы в кавычках не испортили, всегда будет иметь длину AS path меньше, чем другой. Представьте себе, что у вас топология этих самых провайдеров будет немножко отличаться. Что у вас не один транзитный будет провайдер, а вот SP3 и SP4. И вот так они будут соединяться между собой. Вот так трафик будет ходить до SP2. И он будет проходить раз, два, три, четыре транзитных автономки. А вот так он будет проходить один линк,
плюс еще три в кавычках транзитные автономки, добавленные с помощью техники AS prepending. Поэтому на провайдере 2 в такой ситуации получится одинаковый длинный AS path. У нас здесь получается 65300, 65100, 65500. Здесь будет еще одна. Там условно 65400. И длина AS path здесь 4, здесь 4. Веса одинаковые, local preference одинаковые. Метрики одинаковые, next hop одинаковые, доступные, оба не придуманные. Это маршруты оба EBGP-шных. При таком раскладе получается, что сравниваться будут времена соседей, время, в течение которого маршрут стоит в таблице маршрутизации. Для EBGP-шных маршрутов мы сравниваем время, в течение которого маршрут живет в таблице. И кто первый прислал нам такой маршрут, того и будут тапки. А вероятность того, что R2 пришлет свой маршрут первым, перед тем как R1 пришлет маршрут на SP1, SP1 на SP3, SP3 на SP4,
SP4 пришлет на SP2 — существенно больше. Так надо будет кучу EBGP-шных соседств пройти, а так надо будет всего одно EBGP-шное соседство пройти. Поэтому, если у нас достаточно большое количество транзитных автономок на основном маршруте будет, может быть такое, что ваш prepending окажется недостаточно хорош. Вы вроде бы три лишние автономки вбросили, а все равно это оказывается недостаточно для того, чтобы трафик всегда шел по основному. Поэтому prepending — штука ненадежная. Есть провайдеры, которые его блокируют. Если они увидят, что у вас в ваших маршрутах, которые вы присылаете, стоит prepend-нутый номер вашей автономки, то они просто такие маршруты принимать не будут. И есть проблема с этой техникой, что слишком много номеров своих автономок писать тоже нехорошо,
слишком мало — может не сработать. Получается некрасиво. Сколько раз можно удлинять AS path? Сколько совести хватит. Каких-то фундаментальных ограничений нет. 255 — наверное, это максимум. Если говорить про Cisco, то у вас длина строки не может превышать 255 символов. А каждая автономка требует хотя бы там 3-4 символа для того, чтобы записать. Поэтому больше чем 60 вы не сможете это сделать просто из-за ограничения операционной системы Cisco IOS, что она вам такую длинную строчку не даст написать. А так BGP, по-моему, никаких ограничений не дает. Но, опять же, чтобы не хулиганили, слишком много этих самых автономок в AS path писать не принято.
BGP на самом деле протокол, который не очень хорошо адаптирован под ситуации с хулиганством. Вы должны будете контролировать, что вы не хулиганите. Вы можете хулиганить сами. Может быть такое, что пиры будут хулиганить, и тогда вы должны будете, если увидите, что хулиганит ваш пир, блокировать хулиганство. Но в целом интернет весь держится на том, что все друг другу так или иначе доверяют. И поэтому, если вдруг вы не отследили, что ваш пир хулиганит, и вы переслали такие апдейты, дальше эти апдейты будут уже разбегаться по всей сети. Поэтому здесь все держится на порядочности инженеров, которые обслуживают BGP. И просто предполагается, что нормальный адекватный инженер не будет делать prepending на 60 автономок. Правила на количество prepend-ов обычно делают розничные провайдеры, которые подключают клиентов и говорят:
ребята, вы prepending использовать право не имеете. Если вы хотите использовать prepending, то давайте я за вас его сделаю. Я вам prepend-ну немножечко в сторону своего магистрального аплинка, но вы мне это скажете, пожалуйста, с помощью community. Вот так это работает. Розничные провайдеры обычно, которые по BGP с клиентами пирятся, они prepending очень сильно не любят. Именно потому, что инженеры, которые в провайдерах работают, они не будут делать какую-то вещь, которая сломает интернет. А клиент это сделать может. Причем может случайно, даже не намеренно. Просто он будет говорить: я хочу, чтобы обязательно, непременно трафик ходил через один линк. И я знаю по учебнику, что если prepending использовать, гарантированно в этом случае можно будет повлиять на длину AS path. И я сделаю такую длину AS path, которая заведомо станет длиннее, чем любой другой маршрут в легальном интернете. Клиент в такой логике может работать, а инженер провайдера, который работает с BGP каждый день
и понимает, насколько это хрупкая вся экосистема, он такие вещи просто делать не будет. Так что с розничными клиентами обычно никто особо не церемонится, а магистралы — они никакие там фильтры не делают, по-честному-то. Они должны, конечно, делать такое, они должны отслеживать, что их нижестоящие клиенты, их розничные провайдеры тоже какие-то хулиганства не делают, но по факту никто не проверяет на честность своих пиров, если говорить про магистралов. Многие даже фильтры не вешают никакие. Вы должны, конечно, это делать. Если вдруг вы магистральный провайдер, вы должны проверять на какие-то разумные свойства маршрутов. Должны, да, должны. Делаете ли вы это? Не всегда. Что у нас еще? MED — Multi-Exit Discriminator. Нужен в ситуации, когда у нас есть два выхода из нашей автономки в сторону соседней автономки.
Мы говорим: один из этих выходов будет лучше, чем другой. 32-битное число, меньше — лучше, как в случае с метрикой. Если MED отсутствует, то он будет считаться максимально хорошим. Это небольшое отклонение от стандарта. В стандарте написано, что это должен быть максимально выгодный MED, если его совсем нет. Но Cisco с MED немножко по-странному поступила. Если к вам приходит маршрут, и у него стоит MED ноль, или если к вам приходит маршрут, у которого MED вообще нет, то Cisco предпочитает тот маршрут, у которого MED вообще нет. Есть какой-то совсем хороший MED, лучше, чем тот, который можно выразить числом. Часто наследуется от метрики в IGP. Если к вам присылают какой-то маршрут условный OSPF, вы этот OSPF перекладываете в BGP, либо командой Network, либо через редистрибуцию, то из таблицы маршрутизации вы забираете метрику и вкладываете её в MED.
Логически это происходит потому, что вы хотите сделать так, чтобы если у вас есть два бордера, ваш бордер один, бордер два, есть какая-то внутренняя сетка, которую вы хотите анонсировать, чтобы трафик входил в вашу автономку в том месте, где до сети назначения будет ближе. Если вы этот MED руками не назначаете, чтобы он автоматически назначался так, чтобы сеть лучше анонсировал тот бордер, который находится ближе к сети назначения. Это поведение, которое было бы желательно, если бы не один нюанс. Вы не отсылаете MED EBGP-шным пирам, если вы изучаете маршрут по IBGP. Если вы на двух роутерах делаете командой Network инъекцию OSPF-маршрута в BGP, то всё замечательно. Здесь у нас анонсируется MED, здесь у нас анонсируется MED, всё замечательно, всё хорошо.
Но если вы BGP держите также и вот здесь, то вы по IBGP рассказываете этот маршрут на роутер R1, и на роутер R1 этот MED уже больше не анонсируется. MED — атрибут необязательный, он опциональный, он нетранзитивный. Поэтому если вдруг роутер захочет, он его пристрелит совершенно ничтоже сумняшеся. И по умолчанию маршруты, полученные по IBGP, даже если там MED стоял, они на EBGP-шных соседствах не отправляют MED. Поэтому, если ваши бордеры сами вбрасывают такой маршрут, MED отправляется, этот маршрут уходит в сторону соседней автономки, здесь уходит, здесь уходит, и дальше внутри автономки соседа эти MED будут известны. И если роутер партнёра захочет выбрать маршрут, как добраться до сети А, он сравнит MED при прочих равных. Если у нас одинаковые, давайте напишу снова,
N, V, L, L, A, O, M, N, если у нас одинаково доступные NextHop, если у нас одинаковые веса, если у нас одинаковые Local Preference, если у нас коды происхождения в нашем случае точно одинаковые, длины AS Path одинаковые, коды происхождения маршрута одинаковые, MED — почти самый слабый атрибут из всех, если MED у нас различаются, в нашем случае здесь MED 50, здесь MED 100, то трафик пойдёт по тому маршруту, который имеет меньший MED. Далее. Этот роутер, если он будет дружить с кем-то по EBGP, он этот маршрут уже изучит по IBGP, и по EBGP он его не отправит дальше, за исключением случая, когда вы скажете «отправляй, пожалуйста». По умолчанию вы не отправляете по EBGP-шному соседству MED для маршрутов, изученных по IBGP. Поэтому если вы вбрасываете MED в сторону соседа, сосед этот MED будет по своей автономке распространять, но дальше его не передаст.
До тех пор, пока сосед в явном виде не скажет «надо передавать». Но он обычно этого не делает. Как назначается MED? Если вы не хотите использовать IGP-шную метрику, то вы можете его проставить руками. Чаще всего это делается с помощью route-map. Мы говорим, что у нас есть set metric на маршрутах, и дальше route-map говорим «маршруты, отправляемые на соседа», проходят через route-map, и мы им изменяем какие-то свойства, в частности метрику. На соседстве у нас будет, например, ISP-провайдер, и он будет видеть, что некоторые маршруты MED получили какой-то, а некоторые MED получили какой-то другой. Отсутствующий MED в нашем случае действительно отсутствует, он заведомо лучше, чем MED, указанный явно. Поэтому в нашем случае предпочитаться будет маршрут с отсутствующим MED. При прочих равных, и действительно, у нас все прочие свойства равные. Веса одинаковые, нули, Local Preference одинаковые — сотки.
Тип происхождения маршрута — в обоих случаях это удалённый маршрут, через каких-то соседей изученный. Третья L не применяется, длина AS Path одинаковая, маршруты пришли из одной и той же автономки. Коды происхождения маршрута одинаковые, и только в этом случае сравниваются MED. Если вы вбрасываете маршрут с помощью команды Network, у нас есть Network, дальше указываем IP-адрес, слово mask. Mask намекает на то, что это не wildcard mask, а именно настоящая прямая mask. В BGP, если вы что-то вбрасываете, то требуется строгое совпадение того, что вы вбрасываете, с тем, что есть в таблице маршрутизации. Нельзя анонсировать то, чего нет в таблице. Код происхождения для такого маршрута будет IGP. Вы можете посмотреть show IP BGP, дальше указываете нужный вам маршрут, и там среди прочего будет блок с атрибутами.
В нашем случае мы видим, что у нас есть тип маршрута IGP. Это как раз код происхождения. Какая-то метрика. Я не знаю, честно говоря, почему она здесь ноль. Возможно, в таблице маршрутизации действительно была метрика ноль. Local Preference проставился дефолтный. Вес для наших вброшенных нами маршрутов 32768. Дальше показывается, что этот маршрут был выбран лучшим. Вставился в таблицу маршрутизации. Он придуманный локально. И valid, значит, с ним всё хорошо. Он корректный, он правильный. У него NextHop правильный. Всё замечательно. Что такое source? Это я, правда, не помню, но не думаю, что это вам пригодится. Таким образом можно посмотреть на свойства маршрута. Если вы хотите вбросить какие-то маршруты, которые вы заранее не знаете по префиксам, вы не хотите выписывать Network такой IP-адрес, Network такой IP-адрес,
например, потому что вы заранее не представляете, какие IP-адреса у вас будут. Вы знаете, что они у вас могут быть разные. Например, статические. Вы знаете, что у вас некоторые маршруты прописаны статикой, и вы заранее не хотите выписывать все возможные IP-адреса, которые вы пропишете статикой. Типичнейший пример для розничного провайдера, который смотрит на клиентов. Особенно если клиенты — юрлица. У вас есть ваш бордер-роутер, провайдерский PE, у клиентов есть CPE-шки: CPE-шка такая, CPE-шка сякая, CPE-шка пятая, CPE-шка десятая. И за спиной у этих CPE-шек есть какие-то маршрутизируемые сетки. Network 1, здесь Network 2, Network 3 и Network 4. У вас есть шнурки от PE-шки до CPE-шек, и у PE-шки есть эти транзитные линки, на них какие-то IP-адреса висят, есть маршрутизируемые сетки за спиной у CPE-шки.
В этом случае PE-шка говорит: я знаю, что все сетки из диапазона Network 1 доступны через IP-адрес CPE-шки. Она добавляет статику и говорит: статический маршрут до сетки номер 1 через CPE-шку 1. И потом то же самое делает. Здесь у нас доступна CPE-шка 2, через неё сетки 2, здесь у нас сетки 3, тоже доступна через CPE-шку 3. Он просто статикой прописывает. И Network 4. И в этой ситуации на провайдерской железке для того, чтобы в BGP анонсировать все эти сетки, очень удобно просто сказать redistribute static. И вы забираете все эти статические сетки и забираете их в BGP. Инъекция и редистрибуция — это одно и то же? Не совсем. Инъекция — это как раз с помощью команды Network. Мы забираем маршрут из таблицы маршрутизации, и он порождается в BGP как нативный естественный маршрут. Это не перекладывание из какого-то другого источника.
Мы берём один маршрут и в явном виде вбрасываем его в BGP с помощью команды Network. А редистрибуция — мы заранее не знаем, что именно мы перекладываем. Мы их пачкой берём какие-то маршруты по условию и вбрасываем в BGP. Что касается того, что можно вбрасывать в BGP: можно вбрасывать connected-сетки, можно вбрасывать статики, можно вбрасывать маршруты, полученные по EIGRP, OSPF, OSPFv3, IS-IS, RIP — всё что угодно можно вбрасывать. Чаще всего, если мы редистрибутим что-нибудь в BGP, мы будем работать как раз со статическими маршрутами. Мы создаём какой-то маршрут и говорим: давайте его редистрибутим. Если у вас есть возможность командой Network в явном виде все префиксы указать, которые вы хотите порождать в BGP,
используйте эту возможность. Она даёт вам хоть и чуть меньшую гибкость, но зато существенно более предсказуемо работает. Редистрибуция — это достаточно сложный процесс, в котором можно легко ошибиться, поэтому если вы где-то что-то не так настроите, в какой-то момент, допустим, фильтр случайно уберёте, route-map, который забирает маршруты условно из BGP, вкладывает в OSPF или из OSPF в BGP, и вы слишком много маршрутов попытаетесь анонсировать из OSPF в BGP, то вы тем самым негативно повлияете на процесс распространения маршрутов в интернете. Поэтому чем меньше вы будете таких динамических процессов запускать, которые могут негативно повлиять на связность, тем лучше. Редистрибуция — это процесс, который очень легко может случайно пойти не по плану. Типичный пример: где-то опечатались, где-то случайно удалили что-то не то, где-то ошиблись и получили негативный результат. Вспомните Яндекс, который попытался переложить всю таблицу BGP в OSPF.
У них тоже была настроена редистрибуция, никто там не писал: «а ну-ка мне, пожалуйста, положи все-все-все маршруты BGP в интернете в OSPF». Любой человек в здравом уме, который знает, как работает BGP, как работает OSPF, как работает редистрибуция, он этого сделать не позволит. Он бить будет по рукам при попытке это сделать. Но бывают случаи, когда просто опечатался. Когда хотел набрать одно, набрал случайно совершенно другое. Когда у тебя был фильтр, а потом ты этот фильтр случайно удалил вместо какого-то другого фильтра. Когда был route-map, и в конце этого route-map случайно дописали permit, типа match any, permit. И у вас начало пермититься вообще всё. Из-за таких мелких косяков вы можете потерять связность во всей вашей сети, поэтому чем меньше вы будете использовать редистрибуцию, особенно при работе с BGP, тем лучше. Просто потому, что в редистрибуции очень много вещей могут пойти не по плану. В случае с командой Network вы говорите в явном виде — мы же знаем, какие сетки мы купили, какие у нас провайдеро-независимые сети. Мы сделаем статический маршрут до этих сетей.
Может быть даже 0.0.0.0. И дальше, после того как мы сделали такую сетку, мы вбрасываем её в BGP. Очень всё просто, очень предсказуемо. Главное — ничего не может пойти не по плану. Мы либо анонсируем эту сеть, либо не анонсируем. Ничего лишнего мы точно уже не вбросим. Но если вы лентяй, если у вас таких сетей реально много, если вы провайдер, то можно пойти по сценарию с редистрибуцией. То, что вы вбрасываете в BGP, имеет код происхождения incomplete, и MED у него заимствуется от метрики маршрута. Если хотите, можете метрику поменять. Redistribute чего-то там и указывайте metric чего-то там. Это вы будете MED менять таким незатейливым образом. И никто вам не запрещает редистрибутить по условию. Пишите политику route-map и говорите, например, OSPF to BGP. Не EIGRP, а BGP.
И вы забираете все маршруты из OSPF и вкладываете в BGP. Вкладываете по условию, естественно. Если вы импортируете какие-то маршруты, либо через Network, либо через redistribute, то маршруты, которые вы будете вбрасывать в BGP, будут иметь стартовые атрибуты. Если вы вбрасываете сами маршруты, то NextHop проставляется 0.0.0.0, если маршрут, который у вас изначально был, был придуман именно вами самими из таблицы маршрутизации, и он там был connected или static attached. Бывают случаи, когда вы вбрасываете маршрут, и он в таблице маршрутизации смотрит куда-то ещё. В этом случае BGP сразу показывает, какой NextHop должен у вас быть. Если у вас есть сетка, у вас есть, например, два роутера с BGP,
у вас есть несколько роутеров, например, с OSPF, у нас везде в вашей автономной системе OSPF работает. OSPF-овский роутер говорит: я знаю, как добраться до какой-то сети, и у нас здесь в BGP происходит редистрибуция этого маршрута, мы забираем OSPF-овский маршрут и кладём в BGP. У OSPF на роутере BGP-шном, очевидно, есть у этого маршрута NextHop, и он не интерфейс, а именно IP-адрес. Для того чтобы добраться до какой-то сети, надо пойти в сторону NextHop соседнего роутера, и дальше оно в сторону какого-то другого роутера пойдёт. Там уже не важно, что будет происходить дальше. Главное, что этот маршрут не на нас самих был придуман. В этом случае BGP при перекладывании маршрута из таблицы маршрутизации в BGP NextHop будет наследовать. Он скажет, что OSPF говорил, что надо ходить в сторону вон того роутера, и я тоже в BGP буду говорить, что надо ходить в сторону вон того роутера. Поэтому, если вдруг у нас другой BGP-шный роутер будет принимать такой маршрут,
он, конечно же, будет его принимать и по OSPF, и по BGP. Но если вдруг что-то скажет, что по OSPF он этот маршрут не получает, BGP всё равно ему скажет: ходи вон туда, NextHop у него будет наследоваться. Не сказать, чтобы это прямо было очень важно, но просто если вдруг увидите, что маршрут, который вы придумали, имеет NextHop не нулевой, не пугайтесь, это нормально. Такое вполне может быть. С MED ситуация вот какая. Если вы каким-то образом вбрасываете маршрут, который был connected, либо connected, либо static attached, то в этом случае, как бы вы ни вбрасывали, redistribute connected или Network, указываете, что IP-адрес и маска сети соответствуют тому маршруту, который у вас в таблице маршрутизации смотрит на интерфейс. В этом случае у вас MED будет ноль. Если вы берёте маршрут, который удалённый, который имеет действительно IGP-шную метрику,
то метрика у вас будет задаваться каким-то образом. Для маршрутов, которые redistribute static, вы эту метрику толком не знаете. Поэтому если default metric задана, то используется она. Если она не задана, то метрику ниоткуда не возьмёшь. Мы указываем, что у нас есть ip route, допустим, 8.8.8.8, по маске 255.255.255.255, и в какую-то сторону указываем, что такой маршрут есть. И дальше говорим redistribute static. Как узнать, как далеко этот маршрут по факту есть? Непонятно. И какой MED задавать тоже непонятно. Поэтому если у нас есть маршрут, который непонятно куда смотрит, и default metric в BGP у нас не задана командой default metric дальше какое-то число, то MED в этом случае выставляется в ноль. Если мы вбрасываем маршрут, который мы знаем, что имеет метрику, то есть в таблице маршрутизации метрика у этого маршрута есть,
это маршруты IGP-шные, и метрика в таблице маршрутизации заполнена, потому что там был либо EIGRP, либо OSPF, либо RIP, что-то он там поставил в качестве метрики. В этой ситуации, если default metric не задана, то наследуется эта самая метрика. А если она задана, то берётся именно она. В принципе, можно запомнить так: если default metric есть, то маршруты, которые вы придумываете, вбрасываются именно с этой метрикой. Если default metric не задана, то роутер пытается запомнить, какая метрика была в таблице маршрутизации, и у статических маршрутов, которые непонятно куда смотрят, в таблице маршрутизации там будет единица — это административное расстояние, и ноль — это метрика. По факту на эту ноль повлиять вы не можете. У тех маршрутов, которые далеко куда-то смотрят, метрика на самом деле всегда нулевая. Поэтому можно, в принципе, даже этот сценарий как отдельный случай не рассматривать. Вы просто наследуете метрику,
если она не задана в явном виде. Дальше. Если вы хотите, вы можете редистрибутить маршруты в BGP с использованием route-map, и, соответственно, то, что вы пермитите, вбрасывается, то, что вы не пермитите, динаете, вы не вбрасываете. И вы можете дополнительно проставлять атрибуты, как именно вбрасываются маршруты, с какими local preference, с какими весами, с какими… ну вес, да, не особо интересно вбрасывать. С какими local preference, с какими медами, с какими ice pass, с каким чем. Синтаксис предсказуемый. Вот у нас, опять же, наш любимый сценарий – три маршрута с разными метками. И мы говорим, отбираем статические маршруты в BGP, пермитим те маршруты, у которых метка проставлена 1, и ставим им, не знаю, local preference 300. Пермитим те маршруты, у которых метка 2, и ставим им local preference 500. Те маршруты, у которых метка 3, мы не пермитим, они не редистрибуются в BGP. И в таблице BGP у нас, соответственно, есть первый маршрут.
У него метрика 300, как мы проставляли. Видим второй маршрут, у него local preference 500, как мы проставляли. И поскольку оба маршрута придуманы, соответственно, здесь у нас вот IP road, соответственно, мы видим, да, next hop у нас нулевой. Ну и, да, здесь вес 32 768. Маршруты зародились в нашей автономке, поэтому ASPath пустой. Ну, код происхождения... Кстати, код происхождения здесь неправильный, он здесь должен быть не и, он должен быть вопросик. При редистрибуции код происхождения будет вопросик. Здесь на слайде, конечно же, ошибка. Такого быть не должно. Вот у нас будет incomplete показываться, что если мы берем что-то и перекладываем в BGP, то, соответственно, там код происхождения не то, что это нативный маршрут, который в BGP взялся с помощью команды Network. Также, как и всегда с другими протоколами, вы можете использовать фильтрацию маршрутов.
Можно фильтрацию маршрутов использовать на уровне таблицы маршрутизации, что вы из BGP согласны принять и что вы в BGP согласны отдать. Плюс вы можете фильтровать маршруты, которые вы получаете от соседей. На самом деле, да. Вот если у нас есть процесс BGP, если у нас есть какие-то апдейты, которые мы получаем от соседей, можно будет фильтровать эти маршруты с помощью команды Distribute List. Физически, на самом деле, фильтрация будет происходить для тех маршрутов, которые попадают в таблицу маршрутизации, потому что, да, если мы по BGP будем что-то анонсировать соседям, мы это будем забирать из таблицы маршрутизации. Если мы пристреливаем какой-то маршрут, не позволяем его положить в таблицу маршрутизации, то фактически это будет все равно, что мы его запретили принимать в BGP. Он все равно анонсировать тот маршрут, которого нет в таблице, не сможет. Ну и аналогично, да, мы можем запретить отправлять какие-то маршруты в сторону соседа определенного или на определенном интерфейсе. И мы можем при редистрибуции сказать,
что из таблицы маршрутизации мы не отдаем некоторые маршруты в BGP, которые изначально были получены из какого-то другого источника. Также, как и в случае с EGRP, мы можем оперировать префиксами, указываем префикс, можем оперировать айпишниками шлюзов, которые присылают нам такие маршруты. Можем сказать, что нас интересуют вообще все ходящие или все исходящие маршруты. Можно сказать, что нас интересуют только входящие или исходящие маршруты на определенном интерфейсе. И если мы фильтруем маршруты, которые редистрибуются в BGP из какого-то другого источника, то мы указываем, что именно от этого определенного источника в BGP отдается с помощью фильтра. Если мы вбрасываем маршрут по умолчанию, то для этого нужно будет использовать команду Default Information Originate. Она указывается на уровне всего роутера, и вы порождаете маршрут 0, 0, 0, 0, по нулевой маске. То есть даже если у вас такого маршрута нет, вы его придумываете.
В BGP это на самом деле норма. Вот остальные процессы динамической маршрутизации, которые мы с вами рассматривали, там с Default маршрутом всегда была какая-то вот закавыка, что мы в таблице маршрутизации должны были Default иметь, чтобы его отсылать. В BGP это особенный случай. У вас может быть такая ситуация, что вы знаете, где устроен вообще весь интернет, где конкретный каждый узел в интернете находится. Если вы с BGP работаете, у вас может быть ваш маршрутизатор транзитным где-то в серединке интернета, и он знает, где кто находится, знает, что эти сетки находятся в одном направлении, эти в другом, эти в третьем. То есть у него есть так называемый FullView. И если он знает, как добраться до всех сетей в интернете, он может об этом попытаться сказать. Он может сказать, я знаю, как добраться до любого IPшника, который действительно в интернете есть. И в этом случае получается, что он должен сгенерировать маршрут 0-0-0-0 по нулевой маске, которого в интернете нет, но он сделает вид, что он есть. И это делается командой Default Information Reginate.
После чего некоторым соседям, которые будут подключаться к вам как к провайдеру, вы говорите, я могу тебе выдать вообще всю сетку, вообще всю таблицу BGP, которая огромная, в которой 700 тысяч префиксов. Или я тебе могу выдать один дефолтный маршрут. Для тебя как бы выгоднее принять всего один маршрут таблицы маршрутизации, потому что вообще все сетки в мире в любом случае доступны через меня. Какой смысл будет в том, что я тебе скажу, что первая сетка доступна через меня, вторая через меня, третья через меня, 700 тысяч через меня, если все равно ты будешь ходить в интернет через меня. На тебе один маршрут. Пользуйся. Ну и если вы указываете Default Information Originate, то вы порождаете сами маршрут 0000 по нулевой маске. Код происхождения у него будет incomplete, то есть непонятно, откуда он вообще взялся, вы его сами придумали. Вес 32768, Local Preference, Defaultный 100. Ну и он будет лучший, очевидно лучший. Так, дальше.
Административное расстояние, так же, как и везде, можно будет менять. Так, я не понимаю, откуда у меня берутся вот эти цифры про 170. В SPF откуда-то вылезла цифра 170. Здесь 170. 200, там 20 на 200. Соответственно, мы можем в BGP назначить административное расстояние для EBGP-шных маршрутов, для IBGP-шных маршрутов и для маршрутов, которые наш роутер локально придумал. Дефолтное значение 20 на 200 на 200. Если вы хотите, вы можете это поменять. Я вам не рекомендую это делать, но да, гипотетически это можно сделать. Distance, дальше вы указываете там, либо BGP, все маршруты BGP-шные получат административное расстояние указанное. Это EBGP, IBGP и локальные. Либо, если вы хотите, вы можете назначить административное расстояние, так же, как в EJRP это делалось, или в RIP, указываете циферку, какое административное расстояние будет.
Если вы указываете не BGP, а циферку, то дальше вы должны задать IP-шник шлюза, маску, wildcard шлюза и аксесс-лист. И по этому аксесс-листу те маршруты, которые будут подходить под аксесс-лист, которые придут от соседей, которые попали под вот это вот условие, они получат административное расстояние, которое вы здесь вот задаете. Showiperoat BGP в нашем случае, вот мы видим, что да, у нас некоторые наборы маршрутов получили административное расстояние 180. так, я не рекомендую вам по BGP, по административному расстоянию с BGP играть, то есть, если, если вы собираетесь это делать, скорее всего, вы что-то делаете не так. То есть, в большинстве ситуаций можно обойтись без манипуляций с AD. Исключение может быть такой вот как раз сценарий, который мы уже обсуждали с вами, это миграция одного протокола на другой, но миграция внутри сети
одного IGP протокола на BGP, это все-таки очень странное явление. То есть, может, конечно, такое случиться, и в этом случае, возможно, вам пригодится, даже смена административного расстояния, но все-таки какой-то здесь вот такой душок определенный есть. Дальше. То, что к вам может прийти от PIR, вы должны будете определенно фильтровать. Вы не желаете принимать все подряд. То, что вам в апдейтах будет приходить вот EBGP-шных соседей, вы должны будете очень внимательно под микроскопом рассматривать и не принимать все подряд. Можно принимать следующие наборы. Если вы конечный абонент предприятия, то вы можете сказать, мне нужен только дефолт, либо вы можете сказать, мне нужен дефолт, и некоторые specific routes, некоторые конкретные маршруты, которые мне будут интересны, в том числе маршруты клиентов, которые подключены к тому же провайдеру, и маршруты крупных контент-провайдеров. Вконтакте,
Facebook, Google, что там еще бывает, YouTube. То есть, вот эти вот маршруты вы хотите получать для того, чтобы балансировать по ним трафик. Нет смысла получать вообще все маршруты в интернете. Их много, их там 700 тысяч штук, даже больше. Поэтому, если у вас железо не поддерживает такой объем префиксов, оно просто встанет колом и перестанет работать. Если оно поддерживает 700 тысяч префиксов, то возникает вопрос, а нахрена оно вам? Потому что это железо дорогое, это железо очень мощное, и если у вас компания, которая не задействует полностью все фичи этого железа, то вы просто бездарно потратите деньги. Зачем вам знать, как устроена дальняя, самая какая-то точка в Зимбабве, какая-то компания, которая продает там местные, не знаю, ромашки зимбабвийские? Ну, вы же получаете вообще все префиксы, в том числе и компании, которые производят ромашки в Зимбабве, в том числе и компании, которые топят снег на Камчатке. То есть, ну, вы получаете вообще все.
Зачем вам знать, какие сети там есть? Получайте только то, что вас интересует. Получаете маршруты клиентов, которые подключены к тому же провайдеру, чтобы трафик до них шел только через этого провайдера, чтобы он не ходил в обход по умолчанию. И получаете маршруты провайдеров, крупных контент-провайдеров Яндекс, Гугл, Фейсбук, Вконтакте, что там еще бывает, для того, чтобы можно было крупные куски трафика направлять по разным сетям. Вы говорите, что вот у нас есть там два канала в интернет, мы деньги платим за два канала, мы хотим, чтобы Гугл ходил сюда, там Ютуб ходил туда. Деньги платим за два канала, оба канала по факту используются. Все. То есть, этих маршрутов будет не так много. Их будет, ну, там, не знаю, тысяча, ну, две тысячи, ну, десять тысяч, ну, даже если будет сто тысяч, все равно не семьсот тысяч. Сто тысяч маршрутов пережует, в принципе, почти любая железка современная. А вот семьсот тысяч префиксов, это почти миллион, это уже не любая, это уже железки все-таки определенного класса.
Поэтому будьте осторожны и не соглашайтесь принимать дефолт, если вдруг вам провайдер говорит, ну, давайте вы примете дефолт. Или, в крайнем случае, говорите, присылай дефолт, присылай, не только фильтровать его буду. Так что ты отправишь префиксов мне, а я их зарублю. Я их расстреляю на подходе и брать буду только то, что мне интересно. В принципе, довольно популярная такая схема, когда вы говорите провайдеру, давай, вот я сейчас пока не знаю, что мне будет интересно, но ты присылай мне все, а я там дальше разберусь. Дальше вы вешаете фильтр, который почти все расстреливает, а если вдруг, в какой-то момент вам нужно будет подключить какую-нибудь сетку, не знаю, mail.ru, вот вы вспомнили, что вы mail.ru не попросили у него, вы говорите, окей, он нам все присылает, а мы все расстреливаем. Мы теперь пишем фильтр, который расстреливает, убираем из него mail.ru, чтобы он ее не расстреливал, у нас таблица маршрутизации появляется mail.ru, сетка. Вот. Дальше возникает вопрос, соответственно, с исходящими апдейтами. Их тоже надо фильтровать.
То, что входящие апдейты фильтровать надо, это вопрос денег. Исходящие апдейты тоже надо фильтровать, и это не вопрос денег, это вопрос здравого смысла. Представьте себе, что вы клиент, у вас есть провайдер 1, он вам присылает маршрут, говорит, Facebook, ходи через меня. Вы попросили у него контент-провайдерские сети, вот он сказал, ходи. Дальше вы клиент, вы получили в таблицу биджепишную анонс, что фейсбуковская сеть доступна через провайдер 1. Вы, если не будете фильтровать маршруты, то вы в сторону провайдера 2 скажете, ходи, Facebook, через меня. Провайдер 2 имеет платный апплинк в сторону своего магистрала. Провайдер 2 имеет линк в сторону вас, даунлинк, за который платите вы. Возникает вопрос, сюда направить трафик в Facebook стоит денег, сюда отправить трафик в Facebook стоит бесплатно. Более того, вы еще, может быть, даже за трафик платите в этом линке, поэтому чем больше трафика туда пойдет, тем лучше. Куда отправит провайдер 2 трафик до Facebook? Сюда за деньги, сюда бесплатно, и даже ему приплатят.
Это вот как бы неочевидный вопрос, правда? Скорее всего, он отправит его по такой вот трассе. Вам надо становиться транзитной автономной системой для фейсбуковского трафика? Не надо. Поэтому вы должны будете фильтровать трафик, фильтровать маршруты, которые вы отправляете BGP-шным пиром. Если вы клиент, то вы в сторону вашего провайдера отправляете только и исключительно в ваши провайдеры independent адреса. вообще без какого-либо фильтра вешать соседство это очень плохая идея. То есть в любом случае у вас на всех BGP-шных пирах какой-то фильтр должен висеть. И вы не должны разрешать отправлять что попало в сторону ваших соседей. Какие сетки вы, как конечное предприятие, будете анонсировать? Ну, в конце концов, те, у которых AS-Path пустой. В конце концов, те, которые зародились в вашей автономной системе. То есть вы не хотите, чтобы транзитные сетки, которые пришли допустим от роутера 1 прошли через вас
и ушли в сторону провайдера 2. Вот вы можете по префиксам ориентироваться, вы можете по AS-Path ориентироваться, вы можете по каким-то еще метрикам ориентироваться. Мед, наконец, тот же самый. Если вы знаете, что он у вас проставляется, вот вы можете на него ориентироваться. Ну, каким-то образом вы должны будете сказать, что наша автономка ни в коем случае не должна быть транзитной для чужого трафика. Каким образом можно будет зафильтровать маршруты средствами самого BGP? Естественно, вы можете использовать дистрибьют-лист, который будет использовать фильтрацию на уровне самой таблицы маршрутизации, что мы просто не согласны принимать маршруты в таблицу, как следствие мы не будем отсылать маршруты, не будем принимать маршруты. Ну, с дистрибьют-листами все скучно. А вот есть еще средства самого BGP и эти средства будут следующие. Вы можете повесить на соседа либо роутмап, либо фильтр-лист, либо префикс-лист. Соответственно, это на вход или на выход можно будет сделать.
Если у нас есть роутер соседа, который присылает нам апдейт, вот можно любыми из этих методов отбросить маршруты, которые присылает нам сосед. В случае с BGP разные версии операционной системы Cisco EOS и разные, скажем, документы указывают на то, в каком порядке принимаются эти решения. Но, как правило, большинство документов показывает следующий порядок применения инструментов. Самым первым на входе срабатывает роутмап. То есть, если мы вешаем и роутмап, и фильтр-лист, и префикс-лист, и дистрибьют-лист, самым первым срабатывает роутмап, потом фильтр-лист, потом префикс-лист. Это все вешается на соседа. Если дальше маршруты прошли через роутмап, фильтр-лист, префикс-лист, прошли в сторону таблицы маршрутизации, дальше дистрибьют-лист самым последним проверяет и говорит, что маршрут мы согласны принять или не согласны. Дистрибьют-лист позволяет фильтровать трафик на основе
аксесс-листов, ну, или префиксов, префикс-лист на основе префикс-листов, фильтр-лист на основе атрибута ispath и роутмап на основе чего угодно, плюс роутмап можно еще немножко модифицировать маршруты, которые к нам приходят. Дальше маршруты попадают в таблицу BGP, откуда начинают анонсироваться соседям, и здесь инструменты применяются в обратном порядке. Сначала из таблицы маршруты забираются с помощью дистрибьют-листа, потом с помощью конкретных нейборов они начинают отсылаться соседям и проверяется сначала префикс-лист, потом фильтр-лист, потом роутмап. Вот этот порядок на отправку он на самом деле логичный, потому что когда мы формируем из списков 700 тысяч префиксов какие префиксы надо отправить какому конкретному соседу, эти инструменты надо использовать в порядке от самого простого к самому сложному, то есть от вычислительного самого простого к вычислительному сложному. Аксесс-листом
пробит 700 тысяч префиксов Никаких сложностей нет. И, соответственно, на этапе мы забираем маршруты из таблицы маршрутизации и думаем, не отправить ли их куда-нибудь. Вот мы прогоняем эти префиксы через Distribute List. Это очень просто, потому что это Access List. Он быстрый. Он работает через T-CAM, он быстрый, он прогоняет любое количество записей за фиксированное время. И, соответственно, времени не требует, нагрузку на процессор не создает. Вот. Дальше. Конкретный сосед, возможно, имеет свой собственный Access List или префикс-лист, который надо будет проверить. Мы говорим, что вот у нас есть префикс-листы на конкретного соседа. Опять же, что вот эта штука работает с таблицей маршрутизации, RIP, а вот эти все штуки работают на нейборов. Мы проверяем Access List маршрута для конкретного нейбора. Дальше. Проверяем IS Path. Это уже более сложная вещь, потому что там надо будет процессором все это делать. Это уже на уровне аппаратного ускорителя сделать не получится.
И, наконец, самый сложный – это Roadmap, который фактически язык программирования. Опять же, он не ускоряется никак, поэтому все это дело будет центральным процессором двигаться. И поэтому, если есть какие-то механизмы, как можно на анализатор Roadmap направить меньшее количество маршрутов, отсеять сначала грубо Access List какие-то маршруты, а потом только то, что осталось, отправить на Roadmap, это, конечно, имеет смысл сделать. При фильтрации исходящих маршрутов этот процесс вполне осмысленный, потому что у нас одновременно большое количество маршрутов есть. Чем больше мы сэкономим ресурсов на фильтрации маршрутов, тем будет лучше. Вот. Да. При входящих маршрутах мы не можем сказать, что мы точно с халявием, потому что от разных соседей разные маршруты могут приходить в разное время. И они приходят фактически поштучно. У нас есть сосед, и он дает нам один маршрут, второй маршрут, третий маршрут. И мы каждый из этих маршрутов должны будем фильтровать.
Мы не знаем, сколько их будет, но мы говорим, что каждый из них мы отфильтруем. С халявить тут особо не получится. Каждый маршрут мы проверяем через все эти механизмы. А вот когда мы отправляем маршруты, мы точно знаем, что у нас в таблице BGP, ну, например, FullView 700 тысяч штук, и нам каждый из этих 700 тысяч штук надо попытаться отправить соседям. И нам надо принять решение, вот первый маршрут из этих 700 тысяч мы отправляем или нет. Мы сразу можем сказать, что при отправке маршрутов многим соседям многих маршрутов у нас будет много вычислительных задач на проверку, стоит отправлять конкретный маршрут конкретному соседу или нет. Поэтому здесь процедура сокращения вычислений, она уже имеет смысл. Ну и, соответственно, да, порядок, в котором проверяется туда, это в одном порядке, порядок, в котором проверяется при отправке трафика, это, соответственно, в обратном порядке. Так, что мы можем сделать, если мы хотим фильтровать маршруты с помощью аксесс-листов или префикс-листов?
С аксесс-листами мы можем повесить дистрибьют-лист, с префикс-листами мы можем повесить префикс-лист. По сути своей это одно и то же. То есть, если мы хотим сказать, что мы отправляем адреса по какому-то списку, мы можем сделать аксесс-лист, вот, например, говорим, permit такие-то сетки, и на нейборо, дистрибьют-лист, эти сетки, out. Ну и out-in, вы сами понимаете, да, что это в одном направлении или в другом направлении. То есть, либо мы отправляем маршруты, проверяем их по аксесс-листу, что мы сказали permit отправляем, что deny не отправляем, либо, если на вход, то сосед присылает нам префиксы, мы их анализируем и говорим да или нет. Если аксесс-лист сказал permit, принимаем, если deny, то нет. Если мы хотим не аксесс-листами рулить маршруты, а префикс-листами, то вот у нас есть префикс-лист, который говорит, мы разрешаем некоторый маршрут, вот здесь вот, И мы хотим сделать так, чтобы маршруты, которые попадают под префикс лист, мы принимали, а все остальное отбрасывали
Попробуйте угадать, вот у нас есть префикс лист, кстати, давайте такое домашнее упражнение, не домашнее, самостоятельное упражнение Напишите, пожалуйста, что конкретно будет разрешено префикс листом под названием pl-default-end-8-24 У него достаточно говорящее название, но тем не менее, да Постарайтесь посмотреть на его синтаксис и понять, почему это происходит Можно посмотреть на первую запись, IP-префикс лист pl-default-end-24 permit 0000-0 То есть вот эта вот строчка, она указывает на то, что мы permitим в явном виде дефолтный маршрут 0000-0 Вторая строчка с тем же самым именем pl-default-end-8-24 permitит IP-сеть 0000-0, такую же, как в предыдущем случае, но дает ограничение по маске Маршруты должны быть с маской больше либравной 8, но меньше либравной 24 Действительно, в таблице BGPS сегодня чаще всего мы будем видеть именно такие маршруты
То есть маршруты, которые получаются путем разделения блоков в слэш-8 Потому что ИАНа, когда раздавала блоки региональным регистраторам, она их раздавала именно по маскам, ну как минимум восьмым И крупнее блоков, чем слэш-8, на самом деле встретить сегодня нельзя Ну и, соответственно, меньше, чем 24 маски мы просим для того, чтобы не принимать отдельную мелочевку То есть если вдруг кто-то начинает в BGP вбрасывать мелочевку, это... Если вдруг разрешить вбрасывать в BGP мелочевку, это кардинально повлияет на количество префиксов в интернете И очень негативно скажется на производительности магистральных маршрутизаторов Поэтому для того, чтобы в BGP количество префиксов поддерживать на каком-то разумном уровне Есть соглашение о том, что сетки мельче 24 в BGP не пущать И поэтому вот достаточно типичный такой пример, когда вы согласны принимать восьминулевку дефолтовую
И вы согласны принимать префиксы, которые в FullView в принципе могут встретиться Но вы не согласны принимать маршруты, которые будут слишком мелкие или чересчур большие В принципе можно было просто сказать LE24, типа если там вдруг кто-то крупняк какой-то пришлет, ну ничего страшного Но тем не менее, да Я просто для примера, для того, чтобы вы вспомнили, как работает префикс листы Здесь привел, да, что у нас есть в одном префикс листе смесь и маршрута заданного в явном виде 0, 0, 0, 0, 0, 0, вот именно такой айпишник и именно такая маска И отдельно есть строчка, которая дает и родительскую сеть, и ограничение на маски дочерних сетей Вот первая строчка дает один маршрут, вторая строчка говорит Все дочерние маршруты для сетки 0, 0, 0, 0 с ограничением по маске от 8 до 24 мы пермитим Все остальное мы не пермитим Дальше мы на конкретного нейбора вешаем префикс лист Говорим, что вот мы при получении маршрутов от нейбора 10.1.1.1
Проверяем приходящие маршруты по префикс листу Все, на что префикс лист сказал пермит, мы пропускаем То, на что префикс лист сказал deny, мы не пропускаем, мы отбрасываем Если вы работаете с BGP, то вы должны будете понимать, что если вы вешаете фильтр на отправку маршрутов или на прием Это не вызывает немедленную реакцию у соседа Даже если вы повесили фильтр на прием, это не означает, что у вас все маршруты, которые вы раньше принимали А сейчас, соответственно, они фильтр перестали приходить, они немедленно из таблицы уйдут Нет, это не так Вы весьма вероятно должны будете после того, как вы какой-то фильтр повесили Переотправить, если вы фильтр на выход повесили Или переполучить маршруты Автоматически этого не происходит То есть, если вы повесили фильтр на отправку, то clear Clear, IP, BGP, 10, 1, 1, 1, там out или soft out Если вы на вход повесили, то то же самое, только на in
Указываете, что маршруты надо переполучить И дальше с помощью road refresh вы перезаказываете отправку маршрутов Сосед вам их переприсылает Дальше вы их уже через фильтр прогоняете И то, что сосед вам анонсировал, да, вы проверяете Подходит оно, не подходит и принимаете это в таблицу или нет Если вы хотите, можно фильтровать маршруты по префиксам Но это не очень удобно, потому что вы можете заранее не знать, какие именно префиксы сосед вам собирается анонсировать Если вы точно знаете, какие вы собираетесь анонсировать сетки Потому что вы, например, предприятие, и вы точно знаете, что вы купили только одну PI-сетку И никаких других вы анонсировать не собираетесь Там все просто Но если вы, например, провайдер И вы хотите сказать, что те сетки, которые будут у ваших клиентов А черт его знает, какие сетки они покупают Они же могут на лету покупать какие угодно сетки Вы можете фильтровать маршруты на основании других критериев На основании, например, атрибута AS Path Вы можете сказать, что если вы провайдер И у вас есть клиент конечной автономной системы, нетранзитная
Маршруты, которые будут приходить от клиента, вы проверяете на вшивость Если у маршрута AS Path с длиной единичку И там стоит в AS Path только автономка соседа Это значит, что сетка, которую он присылает, зародилась на самом клиенте Если же маршрут, который приходит от соседа, имеет AS Path больше, чем единичку в длину То это маршрут, который клиент принял от какой-то другой автономки И пытается нам его продать, как будто бы он хочет стать транзитным для этой сети Мы такие маршруты принимать не должны Вот пример У нас есть провайдер, который говорит Я знаю, как добраться до какой-то сети Клиент не настраивает фильтрацию исходящих маршрутов И зачем-то посылает эту сетку на провайдера 2 Провайдер 2 понимает, что если он отправит трафик по этому маршруту Он за него не будет платить, за него будет платить клиент Трафик, в принципе, ходить может Но возникает вопрос, насколько провайдер 2 хочет это делать?
Потому что, во-первых, это нечестно получается А во-вторых, клиент таким образом может, например, перехватить весь трафик И может устроить атаку man-in-the-middle И может сделать много разных неприятных вещей Поэтому провайдер 2 не хочет принимать такие префиксы И он должен будет их заблокировать И самый простой вариант, как можно будет их отличить от настоящих префиксов, которые клиент анонсирует Провайдер-независимый клиентский адрес Это как раз по AS Path Вы будете писать условия, какие AS Path вы хотите принимать от соседа И какие не хотите Или, если хотите, можете на выход отправить такое Вы можете сказать, что отправляем любые префиксы, у которых AS Path, например, пустая И вы тем самым скажете, что таким образом отправляете только то, что ваше В сторону провайдерского пира Если говорить про Cisco, то механизмы сравнения AS Path будут использовать регулярные выражения
Фактически строчка AS Path воспринимается именно как текстовая строчка И дальше вы регуляркой просто эту строчку матчите Регулярки в Cisco не совсем обычные, у них есть небольшие особенности Но в целом они очень похожи на регулярки в любом другом языке программирования Поэтому если вы с ними умеете работать, то и AS Path access-листы вы тоже быстро освоите Что может встречаться в регулярном выражении? Если вы указываете любую строчку из цифр, потому что в AS Path буквы встретиться не могут Там могут быть только цифры и знаки препинания Если вы указываете строчку 1, 2, 3, 4, то эта подстрока, которую вы в явном виде указали Она и должна встретиться в оригинальной AS Path Если вы скажете, что у вас есть одна строчка, дальше вертикальная палка и другая строчка То может встретиться одна строчка или другая, любая из двух указанных даст вам совпадение
Если вы знаете, что есть какой-то символ, который может встретиться Или диапазон символов, то вы можете набрать конструкцию в квадратных скобках Указать диапазон символов, и любой символ из этого диапазона вам будет давать результат Например, вы говорите, что автономка соседа может быть 1234 или 1235 В этом случае мы можем сделать регулярку 1, 2, 3 и дальше сказать На четвертом месте будет символ либо 4, либо 5 Эта конструкция задает диапазон из двух символов И любой символ — и 4, и 5 — соответственно даст нам матч И первые три символа заданы жестко Если мы заранее не знаем, какой символ нас устроит, то мы можем указать точку Например, если нас устроит 1234, 1235, 1236 и так далее То мы можем сделать 1, 2, 3, точка
И любой символ здесь нас устроит В принципе, нас устроит даже если это будет просто пробел То есть 1, 2, 3 и дальше ничего Конец номера автономной системы Поэтому будьте осторожны: если точку вы указываете, то это любой символ, включая отсутствие этого самого символа С текстовыми строчками хорошо то, что они начинаются с чего-то Если вы хотите сказать, что какая-то последовательность символов должна идти в начале строки То вы можете указать специальный символ — крышечку Это означает начало строки Если вы хотите принять AS Path, который начинается с этих автономок 1234 или 1235 или 123 Вы можете сказать: крышка 1, 2, 3, точка Начало строки, потом именно символы 1, 2, 3, а потом что попало Это и будет условие, которое отберет именно эти автономки в начале строки
1234, 1235, 1236, 1231, 1232 или 123 ровно Если вы хотите в конце строки матчить что-нибудь, то есть спецсимвол окончания строки В каком случае автономка будет идти в начале строки? Если ваша автономка получила какой-то префикс прямо напрямую из автономки соседа Если у нас есть наша автономная система сотая И у нас есть две автономки, из которых мы можем получать маршруты — 101 И 102 То матчим мы по началу строки, мы говорим Крышечка 101 Это то, что пришло из автономки 101 Крышечка 102 — то, что пришло из автономки 102 Если мы знаем, что у нас есть какие-то другие автономки в системе Например, 200 И мы хотим сказать: покажите нам маршруты, которые зародились в 200-й автономке Неважно, через кого они нам пришли То мы можем сказать: покажите нам те маршруты, у которых 200 и потом конец строки
Это спецсимволы начала и конца строки — крышечка и доллар Если вы хотите использовать любой разделитель, включая пробел, начало, конец строки Любой нецифровой символ То это будет подчеркивание Смотрите, какая штука Если я скажу просто крышечка 101 То матч у меня будет на 101 1011 1012 На все, что начинается на 101 посимвольно Если я хочу сказать, что именно 101, и ничего кроме — не 1011, не 1012 А именно 101 Мне хочется матчить То более правильно будет сделать так 101 и дальше подчеркивание От начала строки символы 101 и дальше любой разделитель Главное, что не цифра Это означает, что именно автономка 101 будет в начале И равным образом подчеркивание 200 доллар
Значит, что именно автономка 200 в конце Не 1200, не 10200, не 15200, а именно 200 Если вам нужно будет с каким-то символом сказать, что этот символ может встретиться несколько раз подряд Например, вы хотите сказать, что у вас есть желание ловить автономки 1, 11, 111, 1011 Или даже 11111 Фактически вы можете сказать, что это символ 1, повторенный несколько раз подряд В этом случае вы можете сказать, что символ, который вас интересует — единичка И дальше квантификатор, сколько раз он может повториться Если вы указываете звездочку, то символ, который стоит перед звездочкой, может повториться любое количество раз от нуля до бесконечности
Если вы указываете символ и вопросик, то это квантификатор 0 или 1 Либо он вообще отсутствует, либо присутствует, но только один раз И если вы указываете плюсик, то это квантификатор 1 или более Как раз ситуация, когда у нас ловятся автономки 1, 11, 111 — это 1 плюс Мы говорим: сколько-то раз должна повториться единичка Если вы хотите сказать, что должна повториться не один символ, а какая-то комбинация символов То эту комбинацию надо взять в круглые скобки Например, мы хотим поймать тот самый AS prepending Мы говорим: у нас есть какая-то комбинация символов Берем ее в скобки и дальше говорим, что эта комбинация символов повторяется Точка плюс
Какой-то символ есть, не нулевой И эта комбинация символов повторяется некоторое количество раз подряд Более правильно — у нас пробел есть Какие-то символы, после них пробел И дальше плюс, что некоторое количество символов с пробелом повторяется определенное количество раз подряд Это как раз ловит тот самый prepending Примеры У нас есть вот такой AS Path Нам нужно проверить, попадает ли этот AS Path под regexp 31 Что такое 31? Это два символа — 3 и 1 Если сочетание символов 3 и 1 в этом AS Path есть Значит, мы говорим: да, попадание есть Если мы говорим, что попадания нет Значит, ни разу сочетание символов 3 и 1 где-то в середине этой текстовой строки мы не встретили Здесь, очевидно, встретили, потому что вот 31, вот 31
Мы говорим: да, матчи есть Вот ещё 31 я не заметил 2316 Здесь тоже 31 есть Поэтому regexp здесь сработал У нас permit Если мы говорим 21 или 31 То здесь, очевидно, тоже есть — вот 21, вот 31, вот ещё 31, вот ещё 31 Матчей тут полно Если мы указываем вот такую конструкцию Квадратная скобка 1-3 Дальше квадратная скобка 4-5 1-3 задает диапазон — это либо символ 1, либо символ 2, либо символ 3 И дальше другие квадратные скобки — либо символ 4, либо символ 5 Здесь можно было поставить минусик как диапазон, можно было не ставить, всё равно ни на что не влияло Соответственно, любая комбинация из двух символов Первый из которых 1, 2 или 3 А второй либо 4, либо 5, даст нам позитивный результат В нашем случае мы видим: 2 и 1 не подходят
2 попадает в диапазон, а 1 нет Дальше 1 и 4 попадают Мы говорим: совпадение есть Дальше 3 и 1 не попадают, 1 не подходит 1 и 7 — 7 не подходит 3 и 5 — есть попадание 3 попадает в первый диапазон, 5 попадает во второй 5 и 6 не попадают, 6 и 7 не попадают В нашем случае опять же есть, причем матчей целых 2 Но всё равно, сколько бы матчей ни было, мы выносим вердикт permit Есть попадание Если мы указываем 1, точка, 3 То это 1, дальше любой символ, и 3 Проверяем 3, 2, 1 — не попадает 2, 1, пробел — не попадает 1, что-то там, 3 Есть попадание У нас 1, пробел, 3 Это действительно 1, любой символ, 3 Пробел, 3, 3 — нет 3, 3, 3 — нет 3, 3, пробел — нет 3, пробел, 6 — нет
Пробел, 6, 6 — нет 6, пробел — нет 6, пробел, 1 — нет 1, 2, 3 Есть попадание Это тоже попадает под 1, точка, 3 У нас 2 матча Сколько бы матчей ни было, в любом случае мы выносим вердикт permit Крышка 1, 2 Проверяем Начало строки 1, 2 Попадание есть Всё остальное можно не проверять, потому что начало строки только в одном месте 31 доллар Смотрим Есть ли у нас такое? Опять же, надо смотреть конец строки В конце строки мы смотрим Вот он, доллар — конец строки И здесь у нас попадания нет Поэтому мы говорим: permit нет У нас нет совпадений, ни одного матча нет Следовательно, не попали Пробел 31 пробел Это подчеркивание 31 подчеркивание Проверяем Начало строки считается за подчеркивание 1, 3, 1
Нет попадания Пробел 31 пробел Есть попадание Пробел 10 пробел Нет попадания Пробел 31, конец строки Есть попадание Здесь у нас опять два матча Круглые скобки 213 или 218 Дальше подчеркивание 31 Сложное условие Нас интересует либо автономка 213, либо автономка 218 Которая получила из 31-й автономки Или любой другой, которая начинается на 31 Смотрим, что получается 213, 31 Вот оно Совпадение есть 317, 12, 18 Нет 1218 пробел 316 Есть матч Вот текстовая строчка Вот матч, который у нас есть 218, 31 Да, номера автономок другие Но мы рассматриваем посимвольно текстовую строчку С точки зрения regexp
Если вы не указали здесь пробел То 1218 или 218, или 2218 Это всё равно матчи, они у нас появятся Вот такая конструкция Даже затруднительно подумать, что она может означать Соответственно, проверяем Пробел 23, потом, может быть, 78 Не факт, что она есть, но может быть И потом 45 Смотрим: 213, потом 23, потом 45, потом 345 23 есть 78 нету, но мы вопросиком указали, что он и не обязан быть Потом 45 У нас действительно матч в этом случае есть Равным образом матч мог бы быть на 23, 78, 45. То есть, ну, в нашем случае, да, оно показывает, что у нас... Мы попросили, чтобы 78 либо ни одного раза не была, либо была бы хотя бы... Была бы ровно один раз. Вот в нашем случае ни одного раза ее нету, и у нас матч по-прежнему есть.
Если бы мы хотели сказать, что 78 должна хотя бы раз появиться, мы бы сказали, что 23 автономка и только она. Потом 78 хотя бы раз, а лучше больше, и потом 45. Вот это вот тогда у нас опять 23, а потом 78 хотя бы раз, она здесь три раза, и потом 45. Вот у нас опять же матч здесь есть. С регулярками вы не должны будете прям хорошо быть знакомыми на экзамене. То есть, вам не потребуются какие-то сложные регулярки писать, но вы должны будете на экзамене показать, что вы хотя бы приблизительно в них разбираетесь, что вы способны прочитать, что делает та или иная регулярка. Я могу вам порекомендовать какие-то ресурсы, но не по цискам, а по, скорее, просто общему программированию. Можно взять какой-то язык, в котором регулярные выражения есть, и они достаточно хорошие. Ну, тут, например, тот же самый Python, или даже, прости господи, JavaScript.
Ну, или, в конце концов, если вдруг вам лень разбираться с программированием, в Official Certification Guide по RAW, то, в принципе, регулярки описаны достаточно неплохо. Поэтому посмотрите. Если вдруг что-то будет непонятно, то можно будет посмотреть какие-то другие ресурсы. Ну, в принципе, да. Должно быть достаточно того, что в книжке есть. Некоторые удобные регулярки, или, скажем, механизмы, которые можно использовать с регулярными выражениями, это, во-первых, проверка на то, что определенная автономная система присутствует в ISPASS в любом месте. Указывайте подчеркивание, номер автономки, подчеркивание. Может быть, в начале строки, может быть, в конце строки, может быть, в серединке. Но главное, что содержит. Если маршрут должен иметь ISPASS только из одной единственной автономки, причем заранее известно какой, вы указываете крышка, номер автономки, доллар. То есть это сосед прислал маршрут, и в этом маршруте номер автономки указан его собственный, и только один, больше ничего нет.
Если маршрут зародился в BGP в определенной автономке, то подчеркивание номер автономки доллар. Ну, то есть потом, когда он будет пересылаться соседям, он будет обрастать слева всякими другими номерами автономок, но все равно исходная автономка, она будет самая правая в самом конце строки. Если маршрут получен из автономки какой-то еще, то есть зародился он где-то непонятно, потом передавался между автономками, и самая последняя автономка в списке, если считать слева, после начала строки идет вот сотая подчеркивание. Значит, мы ловим маршруты, которые получились из сотой автономки. Регулярка доллар-крышка, точнее, крышка-доллар. Очень интересная регулярка, которая позволяет отловить маршруты, которые зародились в своей собственной автономке. То есть очень удобно, например, с помощью такого очень простого выражения сказать, мы не отправляем маршруты, для которых мы транзитная автономка. Мы отправляем только свои. Вот такой вот фильтр очень удобно повесить на исходящие пиринги,
для того, чтобы не отправлять маршруты, которые вы получили от других провайдеров. Опять же, если вы в предприятии, то вот эту вот штуку вы, скорее всего, захотите сделать. А ваш сосед, ваш провайдер, скорее всего, захочет повесить вот такой фильтр, который скажет, что он принимает от вас только маршруты, которые зародились в вашей автономке. Если вы хотите сказать, что маршруты были получены из какой-то автономки, но заранее непонятно из какой, то вы указываете, что в AS Path у вас есть некоторое количество символов, повторенное несколько раз подряд. То есть какое-то количество символов в диапазоне от 0 до 9, то есть любой символ фактически, но не пробел. И пробелов в этой автономке нет. То есть мы получили какой-то маршрут, этот маршрут получен от соседа. Заранее автономку соседа мы не прописывали. И, соответственно, вот мы просто говорим, что этот маршрут был зарожден в автономке соседа. В чем преимущество по сравнению с вот этой штукой?
Что вы можете повесить такой фильтр на вообще всех ваших пиров. Если вы, например, провайдер, вы говорите, у меня есть клиент, там, ЗАО Ромашка, ЗАО Василек, ООО Петрушка. Мы номера автономок их вешаем на каждого соседа. Но мы рядом с этим соседом говорим, этот сосед входит в пиргруппу. И на пиргруппу мы вешаем фильтр, что эти соседи присылают только маршруты, которые зародились в их собственной автономке. Они не могут присылать маршруты, которые получены из каких-либо других автономок. Как мы знаем, что это маршруты, зародившиеся в их автономке? А то, что если это EBGP-шные пиры, они как минимум свой номер автономки там указывают. И мы говорим, это может быть любая автономка, но длина ISPath должна быть строгой единицей, потому что мы не допускаем, пардон, мы не допускаем приема маршрутов, у которых в ISPath пробелы. Как отловить маршруты с ISPrepending? Допустим, вы хотите сказать, как провайдер, что вы разрешаете ISPrepending, но вы не разрешаете, чтобы маршруты были транзитными. Вы говорите, окей, вот эта вот штука обозначает,
простите, обозначает номер автономки. Мы говорим, последняя автономка, которая в этом списке есть, самая левая, это автономка соседа. Вот пусть она, это самая автономка соседа, состоит из каких-то символов от 0 до 9, как минимум один раз повторяю. И пусть мы говорим, у нас есть это число, плюс пробел в начале, повторенный несколько раз подряд. Вот это вот slash 1 указывает, что мы повторяем то, что в первых скобочках. То есть вот то, что в первых скобочках, это номер автономки соседа, повторенные как минимум несколько раз, это, соответственно, маршруты, которые вы получили с препендингом от соседа. Маршруты, которые пришли от соседа и имеют длину AS Path больше единицы, и которые попадают под этот фильтр, они, соответственно, немножко испорчены, но тем не менее, это все еще маршруты от соседа. Если хотите сказать,
что любой маршрут вас интересует, с любой AS Path, то просто любое количество символов повторено на любое количество раз. Вот такие вот регулярки, они достаточно часто встречаются. Если вдруг вы их увидите или аналогичные какие-то, не пугайтесь. Как прописать AS Path на соседа? Указываем IP, AS Path Access List, то есть вот эта вот конфигурация создает Access List, который будет работать с AS Path. Дальше указываете номер. Эти штуки только номерованные. Permit и дальше регулярку, которую вы хотите сделать. Например, AS Path Access List 1 говорит, я буду пермитить только маршруты, которые зародились в моей собственной автономке. И дальше мы на выход, на соседа говорим, neighbor такой-то, фильтр лист и номер фильтр листа out. Если вы хотите сделать фильтр лист, который будет принимать маршруты со стороны провайдера, вот вы можете сделать, что вы разрешаете маршруты, которые зародились в автономке 65000.001
и присланы нам напрямую из этой самой автономки. Вот мы говорим, у нас есть neighbor, фильтр лист, один in. Достаточно простая вещь, но тем не менее, очень мощная, очень удобная. Если вы работаете с Access List, с AS Path Access List, то, соответственно, вы можете отфильтровать те маршруты, которые вас интересуют, просто по признаку, что у них в AS Path есть какие-то очень характерные последовательности. Практически все, что, собственно говоря, в CISC можно сделать с маршрутами, это вот как раз это. То есть, можно повесить на соседа фильтрацию маршрутов по Access List. Это команда distribute list на вход, на выход. Можно повесить на соседа фильтрацию маршрутов по префикс-листу. Опять же, на вход, на выход. Вы префикс-листом пишете IP-шники сетей, которые вы согласны принимать или отправлять. Вы можете на соседа повесить маршруты, повесить фильтрацию маршрутов по AS Path и вы можете роутмапом собрать
все это дело в какую-то большую конструкцию, где скажете, что матчами вы обираете трафик, который... Не трафик, матчами вы обираете маршруты, у которых и IP-шники правильные, матч IP-адрес, и AS Path, правильный матч AS Path по Access List и какие-то еще свойства вы можете проверять. И, соответственно, вы пермитите или динаете маршруты, которые вы хотите пропускать или не хотите пропускать. Вот такие вот механизмы вам будут доступны и вы можете в BGP фильтровать маршруты по самым разным критериям, которые вы захотите. Понятное дело, что роутмап это самая сложная вещь. Если вы принимаете большое количество маршрутов и все их по роутмапу только прогоняете, то нагрузка на роутер у вас может быть довольно большой. Ну и равным образом, если у вас много пиров и вы хотите отправлять много маршрутов, опять же, возможно, вы хотите сократить количество маршрутов, которые вы хотите отправлять в сторону пира, именно с помощью простых механизмов перед тем, как направлять приходящие, возможные кандидаты на отправку
через роутмап. Как-то так.