среда, 17 февраля 2021 г.

VyOS | Странная лаба | BGP

Так-то еще пару маршрутов добавит к тому, что получилось в прошлом посте и все будет работать. Но в такой конфигурации велик риск "заблэкхолить" трафик. Попробуем улучшить ситуацию...

Посты в серии:

В общем

При статических маршрутах B1 будет слать трафик к файерволу, даже не смотря на то, что R1 "вышел покурить". И в обратную сторону, даже если B1 по какой-то причине потеряет доступ в интернет, это не остановит R1 и тот будет слать трафик к файерволу как и слал. Ну и если файервол по середине "раскорячится", но линки будут подняты, никто и не заметит и будет продолжать слать трафик. Нужно иметь какой-то механизм сигнализации...

Проблему можно решить несколькими способами. Например, можно написать VRRP health check, благо VyOS позволяет.  Можно, скажем,  пинговать публичный адрес и переходить в BACKUP. Но это будет работать только для траффика снизу-вверх. Надо чтобы и B1/B2 не слали трафик вниз. 

В общем, я решил сделать комбинацию из BGP и VRRP health check + transition script. 
  • B1/B2 вниз анонсируют некий префикс (вероятно 0/0) на R1/R2, только если у них самих есть доступ в интернет. 
  • R1/R2 вверх анонсируют некий префикс, который используют файерволы для NAT. 
  • VRRP healthcheck скрипт смотрит, есть ли префикс от B1/B2 и если такого нет, VRRP группа переходит в состояние fault. 
  • Второй скрипт, который transition, будет фильтровать получаемые и анонсируемые префиксы на R1/R2 при переходе VRRP группы в BACKUP/FAULT и убирать route-map при переходе в MASTER.
Это схема страхует много от чего.  Например:
  1. При потере 0/0 маршрута B1/B2 перестанут его анонсировать, что переведет VRRP на R1 или R2 в FAULT состояние. Трафик снизу-вверх будет перейдет на "здоровую" сторону. При переходе в FAULT второй скрипт применит route-map и отфильтрует все анонсы в сторону B1/B2, что уберет и трафик сверху-вниз.
  2. Выход из строя файервола посередине должен привести к таким же последствиям, если он будет достаточно сильным для того, чтобы пропала BGP сессия.
  3. Если кто-то руками переведет VRRP группу на другой роутер, transition скрипт применит route-map и отфильтрует анонсы. B1/B2 перестанут слать трафик на неактивный файервол.


Посмотрим, будет ли оно так работать. План на сегодня
  • Настраиваем простой BGP в верхней части сети
  • Настраиваем наши бордеры и пиринг с роутерами за файерволами
В общем, будет базовый такой пост. Однако любой пост про BGP обычно разрастается донельзя, это не исключение. 

Итак, вот наша схема с адресацией. В прошлый раз касались только нижней части, сегодня заглянем и наверх.

eBGP

Настройка BGP в VyOS хочет казаться похожей на Junos, но мы видим старую добрую "квагу". Не поймите неправильно, я люблю "квагу". 

Честно признаюсь, я просто возьму за основу конфигурацию из этого поста и из этого поста пока без особых фильтраций. 

Для начала IP связность и BGP. Тут ничего особенного, просто перевод картинки сверху в конфиг. Кстати, интересный момент. По-умолчанию, в VyOS сеть можно анонсировать и без маршрута в таблице. 

На AS1, AS2 и AS3 настраиваем простой пиринг без каких-либо фильтров вообще. Я буду использовать 120.0.0.0/24 который находится за AS1, но и на остальные роутеры добавил по сеточке. 

AS1
set interfaces ethernet eth0 address '101.10.10.0/31'
set interfaces ethernet eth0 description 'AS2'
set interfaces ethernet eth1 address '102.10.10.0/31'
set interfaces ethernet eth1 description 'AS3'

set protocols bgp 64503 address-family ipv4-unicast network 103.0.0.0/22
set protocols bgp 64503 address-family ipv4-unicast network 120.0.0.0/24
set protocols bgp 64503 neighbor 101.10.10.1 remote-as '64501'
set protocols bgp 64503 neighbor 101.10.10.1 update-source eth0
set protocols bgp 64503 neighbor 101.10.10.1 address-family ipv4-unicast soft-reconfiguration inbound 
set protocols bgp 64503 neighbor 102.10.10.1 remote-as '64502'
set protocols bgp 64503 neighbor 102.10.10.1 update-source eth1
set protocols bgp 64503 neighbor 102.10.10.1 address-family ipv4-unicast soft-reconfiguration inbound

AS2
set interfaces ethernet eth0 address '101.10.10.2/31'
set interfaces ethernet eth0 description 'B1'
set interfaces ethernet eth1 address '101.10.10.1/31'
set interfaces ethernet eth1 description 'AS1'

set protocols bgp 64501 address-family ipv4-unicast network 101.0.0.0/20
set protocols bgp 64501 neighbor 101.10.10.0 remote-as '64503'
set protocols bgp 64501 neighbor 101.10.10.0 update-source eth1
set protocols bgp 64501 neighbor 101.10.10.0 address-family ipv4-unicast soft-reconfiguration inbound 
set protocols bgp 64501 neighbor 101.10.10.3 remote-as '64500'
set protocols bgp 64501 neighbor 101.10.10.3 update-source eth0
set protocols bgp 64501 neighbor 101.10.10.3 address-family ipv4-unicast soft-reconfiguration inbound 

AS3
set interfaces ethernet eth2 address '102.10.10.1/31'
set interfaces ethernet eth2 description 'AS3'
set interfaces ethernet eth0 address '102.10.10.2/31'
set interfaces ethernet eth0 description 'B2'
set interfaces ethernet eth1 address '102.10.10.4/31'
set interfaces ethernet eth1 description 'B1'

set protocols bgp 64502 address-family ipv4-unicast network 102.0.0.0/21
set protocols bgp 64502 neighbor 102.10.10.0 remote-as '64503'
set protocols bgp 64502 neighbor 102.10.10.0 update-source eth2
set protocols bgp 64502 neighbor 102.10.10.0 address-family ipv4-unicast soft-reconfiguration inbound 
set protocols bgp 64502 neighbor 102.10.10.3 remote-as '64500'
set protocols bgp 64502 neighbor 102.10.10.3 update-source eth0
set protocols bgp 64502 neighbor 102.10.10.3 address-family ipv4-unicast soft-reconfiguration inbound 
set protocols bgp 64502 neighbor 102.10.10.5 remote-as '64500'
set protocols bgp 64502 neighbor 102.10.10.5 update-source eth1
set protocols bgp 64502 neighbor 102.10.10.5 address-family ipv4-unicast soft-reconfiguration inbound 

Аналогично на B1/B2. Пока просто пиринг. 

B1
set interfaces ethernet eth0 address '101.10.10.3/31'
set interfaces ethernet eth0 description 'AS2'
set interfaces ethernet eth2 address '102.10.10.5/31'
set interfaces ethernet eth2 description 'AS3'

set protocols bgp 64500 address-family ipv4-unicast network 100.0.0.0/24
set protocols bgp 64500 neighbor 101.10.10.2 remote-as '64501'
set protocols bgp 64500 neighbor 101.10.10.2 update-source eth0
set protocols bgp 64500 neighbor 101.10.10.2 address-family ipv4-unicast soft-reconfiguration inbound 
set protocols bgp 64500 neighbor 102.10.10.4 remote-as '64502'
set protocols bgp 64500 neighbor 102.10.10.4 update-source eth2
set protocols bgp 64500 neighbor 102.10.10.4 address-family ipv4-unicast soft-reconfiguration inbound

B2
set interfaces ethernet eth0 address '102.10.10.3/31'
set interfaces ethernet eth0 description 'AS3'

set protocols bgp 64500 address-family ipv4-unicast network 100.0.0.0/24
set protocols bgp 64500 neighbor 102.10.10.2 remote-as '64502'
set protocols bgp 64500 neighbor 102.10.10.2 update-source eth0
set protocols bgp 64500 neighbor 102.10.10.2 address-family ipv4-unicast soft-reconfiguration inbound 

Теперь на B1/B2 добавим еще и простой фильтр. Будем отдавать только наш /24 префик, чтобы не стать транзитом для внешних префиксов. 

Пишем префикс лист с роут мапом. 

set policy prefix-list BGPOUT description 'BGP Export List'
set policy prefix-list BGPOUT rule 100 action 'permit'
set policy prefix-list BGPOUT rule 100 prefix '100.0.0.0/24'
set policy prefix-list BGPOUT rule 10000 action 'deny'
set policy prefix-list BGPOUT rule 10000 prefix '0.0.0.0/0'
set policy route-map BGPOUT description 'BGP Export Filter'
set policy route-map BGPOUT rule 10 action 'permit'
set policy route-map BGPOUT rule 10 match ip address prefix-list 'BGPOUT'
set policy route-map BGPOUT rule 10000 action 'deny'

Применяем на соседей. 

B1
set protocols bgp 64500 neighbor 101.10.10.2 address-family ipv4-unicast route-map export BGPOUT
set protocols bgp 64500 neighbor 102.10.10.4 address-family ipv4-unicast route-map export BGPOUT

B2
set protocols bgp 64500 neighbor 102.10.10.2 address-family ipv4-unicast route-map export BGPOUT

Как и говорил, все довольно просто.


Предлагаю сконцентрировать внимание только на двух префиксах, остальные тут для вида. Посмотрим на 100.0.0.0/24 и 120.0.0.0/24. 

Вот так видит наш "мир" B1 например. 120.0.0.0/24 анонсируемый с AS2 доступен через двух "провайдеров" - AS2 и AS3.


А вот картина на AS1. 100.0.0.0/24 анонсируемый B1 и B2 доступен так же по двум путям.

iBGP

Конечно, вся эта картина была бы не полной без iBGP. Во-первых, у нас два маршрутизатора (B1/B2) анонсируют один и тот же префикс, но никак не связаны. Во-вторых, в прошлом посте я затеял использовать BGP как некий сигнальный протокол. В общем, iBGP и займемся.

B1-B2

Для начала поднимем сессию между B1 и B2. Тут будем испотльзовать nexthop-self. Все как в учебниках. 

B1
set interfaces ethernet eth3 address 172.16.101.1/30
set interfaces ethernet eth3 description B2

set protocols bgp 64500 neighbor 172.16.101.2 address-family ipv4-unicast nexthop-self
set protocols bgp 64500 neighbor 172.16.101.2 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp 64500 neighbor 172.16.101.2 remote-as '64500'
set protocols bgp 64500 neighbor 172.16.101.2 update-source 'eth3'

B2
set interfaces ethernet eth3 address 172.16.101.2/30
set interfaces ethernet eth3 description B1

set protocols bgp 64500 neighbor 172.16.101.1 address-family ipv4-unicast nexthop-self
set protocols bgp 64500 neighbor 172.16.101.1 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp 64500 neighbor 172.16.101.1 remote-as '64500'
set protocols bgp 64500 neighbor 172.16.101.1 update-source 'eth3'

B1 теперь знает про 120.0.0.0/24 например еще и через соседа (172.16.101.2)

B-R

Чуть интересней дело будет обстоять с B1-R1, B2-R2. Моя идея - поднять сессии через файервол. Настройка интерфейсов ниже

B1
set interfaces ethernet eth1 address 172.16.1.0/31
set interfaces ethernet eth1 description F1

F1
set interfaces ethernet eth2 address 172.16.1.1/31
set interfaces ethernet eth2 description B1

B2
set interfaces ethernet eth1 address 172.16.1.0/31
set interfaces ethernet eth1 description F2

F2
set interfaces ethernet eth2 address 172.16.1.1/31
set interfaces ethernet eth2 description B2

Маршруты на B1/B2, R1/R2 и пока базовая iBGP сессия. 

B1/B2
set protocols static route 172.16.0.0/32 next-hop 172.16.1.1 

set protocols bgp 64500 neighbor 172.16.0.0 address-family ipv4-unicast nexthop-self
set protocols bgp 64500 neighbor 172.16.0.0 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp 64500 neighbor 172.16.0.0 remote-as '64500'
set protocols bgp 64500 neighbor 172.16.0.0 update-source 'eth1'

R1/R2
set protocols static route 172.16.1.0/32 next-hop 172.16.0.1

set protocols bgp 64500 neighbor 172.16.1.0 address-family ipv4-unicast nexthop-self
set protocols bgp 64500 neighbor 172.16.1.0 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp 64500 neighbor 172.16.1.0 remote-as '64500'
set protocols bgp 64500 neighbor 172.16.1.0 update-source 'eth0'

Сессии поднимаются, префиксы прилетают, все классно, но это совсем не то, что нам нужно. Уж очень много всего знают R1/R2. 


Схема iBGP сессий для наглядности (позже мы поймем, что так делать не надо). 

Обрабатываем iBGP напильником


Выше то, что должно получиться для пары B-R. Как видно, то что получилось, от задумки довольно далеко. 
  • На R1/R2 нам нужно получать только 0./0 и ничего больше. На этот префикс, напомню, будет смотреть VRRP процесс. Все остальные префиксы нам не нужны.
  • B1/B2 должны анонсировать 0./0 "условно" при наличии 0./0 от вышестоящих роутеров.
  • R1/R2 должны анонсировать /27 сети для привлечения трафика к файерволам.
  • Нужен route-map который будем применяться на BGP сессию при переключении VRRP группы.
Этим и займемся.

 - Для начала на AS1/AS2 анонсируем 0.0.0.0/0 в сторону B1/B2

set protocols bgp AS neighbor IP address-family ipv4-unicast default-originate

- Добавим фильтр на B1/B2 в сторону R1/R2. Анонсируем только дефолт.

set policy prefix-list DEFAULT-ONLY description 'Only default route'
set policy prefix-list DEFAULT-ONLY rule 10 action 'permit'
set policy prefix-list DEFAULT-ONLY rule 10 prefix '0.0.0.0/0'

set policy route-map DEFAULT-ONLY description 'Only default route'
set policy route-map DEFAULT-ONLY rule 10 action 'permit'
set policy route-map DEFAULT-ONLY rule 10 match ip address prefix-list 'DEFAULT-ONLY'
set policy route-map DEFAULT-ONLY rule 10000 action 'deny'

set protocols bgp 64500 neighbor 172.16.0.0 address-family ipv4-unicast route-map export 'DEFAULT-ONLY'

reset ip bgp 172.16.0.0 

Теперь R1/R2 получают только дефолт.



- По задумке, R1/R2 должны анонсировать /27 для привлечения трафика к файерволам F1/F2.

set protocols bgp 64500 address-family ipv4-unicast network 100.0.0.0/27

Со стороны B1\B2 видно /27 смотрящий вниз. Дальше в мир этот префикс не пойдет, мы фильтруем на экспорт только /24. 


- Добавляем по маршруту на F1/F2, чтобы полученный трафик от R1/R2 они отправляли вверх. 

set protocols static route 0.0.0.0/0 next-hop 172.16.1.0

Теперь осталось написать простой route-map для того чтобы выводить R1/R2 из сети.

set policy route-map SEE-YOU-LATER rule 10 action 'deny'

После этого мы можем отфильтровать все приходящие и исходящие анонсы тремя командами

set protocols bgp 64500 neighbor 172.16.1.0 address-family ipv4-unicast route-map export 'SEE-YOU-LATER'
set protocols bgp 64500 neighbor 172.16.1.0 address-family ipv4-unicast route-map import 'SEE-YOU-LATER'
reset ip bgp 172.16.1.0

После этого R1 или R2 перестает получать дефолтный маршрут.


A B1 или B2 не получает /27. 


Причем не получает вообще... и это плохо... вообще-то надо было раньше об этом подумать...

Представим, что трафик в таком состоянии придет на B1 и тот его просто сбросит. В нашем случае он просто обязан отправить его на своего BGP пира B2. 

Получается это из-за одного из главных правил iBGP. "Не отправляй префикс полученный от iBGP соседа другому iBGP соседу". Мде....

Решить эту проблему можно по разному. Мне нравится сменить iBGP между B и R на eBGP. В таком случае, B1 и B2 обменяются своими маршрутами "вниз" и при потере локального маршрута трафик пойдет к соседу. Ниже чуть подкорректированная схемка. 


На B1 создаем соседа, но уже с другой AS. Плюс, нужно указать ebgp-multihop, чтобы сессия поднялась через лишний хоп (файервол). В iBGP это работает по умолчанию. 

set protocols bgp 64500 neighbor 172.16.0.0 address-family ipv4-unicast route-map export 'DEFAULT-ONLY'
set protocols bgp 64500 neighbor 172.16.0.0 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp 64500 neighbor 172.16.0.0 remote-as '65501'
set protocols bgp 64500 neighbor 172.16.0.0 update-source 'eth1'
set protocols bgp 64500 neighbor 172.16.0.0 ebgp-multihop 2

Примерно похожая конфигурация на R1
set protocols bgp 65501 address-family ipv4-unicast network 100.0.0.0/27
set protocols bgp 65501 neighbor 172.16.1.0 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp 65501 neighbor 172.16.1.0 remote-as '64500'
set protocols bgp 65501 neighbor 172.16.1.0 update-source 'eth0'
set protocols bgp 65501 neighbor 172.16.1.0 ebgp-multihop 2

B2
set protocols bgp 64500 neighbor 172.16.0.0 address-family ipv4-unicast route-map export 'DEFAULT-ONLY'
set protocols bgp 64500 neighbor 172.16.0.0 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp 64500 neighbor 172.16.0.0 remote-as '65502'
set protocols bgp 64500 neighbor 172.16.0.0 update-source 'eth1'
set protocols bgp 64500 neighbor 172.16.0.0 ebgp-multihop 2

R2
set protocols bgp 65502 address-family ipv4-unicast network 100.0.0.0/27
set protocols bgp 65502 neighbor 172.16.1.0 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp 65502 neighbor 172.16.1.0 remote-as '64500'
set protocols bgp 65502 neighbor 172.16.1.0 update-source 'eth0'
set protocols bgp 65502 neighbor 172.16.1.0 ebgp-multihop 2

Теперь, если посмотреть, на B1, то можно увидеть, что префиксов теперь в таблице два. Первый приходит от B2, а второй (лучший) от R1. R1 является eBGP соседом и маршрут который он анонсирует будет всегда приоритетным.


Теперь, если убрать из сети R1, приоритетный анонс пропадет и трафик с B1 уйдет на B2.


Примерно вот так будет выглядеть вся картинка при отказе R1. Заметим одну особенность. B1/B2 анонсируют /24 безусловно. При включённом aspath relax (ставить в таблицу маршрутизации префиксы с одинаковой длинной AS_PATH, даже при разных значениях AS), AS1 будет балансировать трафик между AS2 и AS3. AS3 также балансирует трафик между B1 и B2. B1 потом отправит трафик на B2, где все еще сидит /27. В общем, это может быть не очень хорошо. У нас три разных пути с разным latency. 


Решить проблему можно несколькими способами
- Как вариант, при отказе R1 можно "препендить" /24 наружу. В таком случае весь трафик уйдет на B2, но в сети будет дополнительный путь на случай отказа B2 ("запрепенженый" /24 от R1). Не очень вариант, потому что сети не входящие в /27 все еще разумно роутить на B1.
- К сложалению, VyOS пока не поддерживает BGP cobditional adverisement. С этой штукой можно было бы смотреть есть ли префикс от локального R маршрутизатора. При его отсутствии вешать route-map с prepend на B1 или B2 или анонсировать /27, чтобы привлечь трафик к "живому" маршрутизатору. 
- Второй вариант, анонсировать оба префикса (/27 и /24)  с обоих устройств. При потере /27 от локального R1 префикс перестанет уходить в мир. Ничего так вариант, мне мне не нравится
- VyOS поддерживает скрипты. Можно смотреть таблицу полученных маршрутов и менять route-map при пропадании /27. 
- Наверняка есть еще варианты и, возможно, получше. 

Мне пока больше всего нравится анонсировать /27 c B2 при пропадании /27 снизу на B1. 

Обо всем этом и многом другом в следующем посте. Поговорим про VRRP скрипты, попробуем решить проблему обозначенную выше и протестируем буде ли вообще это работать. )

Ну и да, все вышесказанное не имеет отношение к моему работодателю.

Комментариев нет:

Отправить комментарий