Настраиваем BGP используя quagga на FreeBSD
В статье описан способ поднять протокол динамической маршрутизации BGPv4 (EBGP) для минимального взаимодействия двух AS.
Протокол BGP сложный механизм состоящий из многих параметров. В одной статье сложно учесть и объяснить все. Статья будет пригодна тем, кто только начал сталкиваться с этим протоколом и не использовал quagga.
Основные понятия:
AS - Autonomous system - группа маршрутизаторов (шлюзов) из одной административной области, взаимодействующих с другими автономными системами посредством внешнего протокола маршрутизации. При наличии собственного номера AS и блока адресов позволяет использовать два и более каналов в сеть Интернет одновременно, с распределением нагрузки между ними.
EGP - Exterior Gateway Protocol, протокол внешнего шлюза. (например: BGPv4, IS-IS);
IGP - Interior gateway protocol, протокол внутреннего шлюза (например: RIP, EIGRP, OSPF);
EBGP - External BGP, взаимодействие протокола BGP с другими (чужими) автономными системами;
IBGP - Internal BGP, взаимодействие протокола BGP внутри своей автономной системы;
peer - Сосед по протоколу динамической маршрутизации;
as-path - "Путь" из номеров AS (автономных систем) до сети назначения;
Номера AS 64512 - 65535 выделены для частного использования ("серые" номера AS);
Тестовый стенд: компьютер Intel P4, 4Gb памяти, и два сетевых интерфейса em0, em1
Начнем:
cd /usr/ports/net/quagga/ make install clean
После установки нам необходимо настроить два демона: 1. zebra 2. bgpd
Переходим в директорию /usr/local/etc/quagga
Файл: zebra.conf
hostname zebra password 123 enable password 123 log file /usr/local/etc/quagga/zebra.log ! interface em0 ip address 10.1.1.1/24 ! interface em1 ip address 2.2.2.2/30 ! interface lo0 ! ip route 10.0.0.0/8 Null0 254 ip route 172.16.0.0/12 Null0 254 ip route 192.168.0.0/16 Null0 254 ip route 64.17.0.0/21 Null0 254 ip route 64.17.0.0/22 10.1.1.2 ip route 64.17.4.0/22 10.1.1.3 ! ip forwarding ! ! line vty exec-timeout 0 0 !
Пройдемся по конфигу zebra.conf
em0 - интерфейс смотрящий в сторону локальной сети
em1- интерфейс смотрящий в сторону провайдера маршруты 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 отправлены в Null0, иными словами все пакеты которые будут приходить от данных сетей будут отбрасываться, т.к. это "серые" сети которые не маршрутизируются в сети Интернет.
64.17.0.0/21 - это выделенный нам, организацией RIPE, блок внешних адресов.
Т.к. для того, что бы протокол BGP мог анонсировать (объявлять) эту подсеть провайдеру он сам должен знать где находится данная сеть. Для того, чтобы в последствии избежать ситуаций когда из-за проблем внутри локальной сети, например недоступность gateway на который (которые) будут маршрутизироваться подсети или сеть 64.17.0.0/21 при использовании внутренних протоколов динамической маршрутизации (RIP, OSPF, EIGRP), BGP перестанет анонсировать наш блок внешних адресов, для этого мы также отправляем маршрут этой сети в Null0. Таким образом мы заставим BGP всегда знать маршрут в эту сеть.
Теперь возмем блок 64.17.0.0/21 и поделим его на две подсети 64.17.0.0/22, 64.17.4.0/22 и "отмаршрутизируем" их внутрь сети на два других сервера 10.1.1.2, 10.1.1.3 где они будут использоваться под клиентов или другое оборудование, где могут быть ещё разбиты на более мелкие подсети.
Вы возможно подумали о том: "как же это будет работать раз /21 отправлена в Null0 ?"
Это будет работать по тому, что в таблице маршрутизации роутера будет три маршрута, два из которых более точные (/22), поэтому наш маршрутизатор будет пользоваться ими для продвижения пакетов приходящие от нашего блока.
Файл bgpd.conf:
hostname AS100 password 123 enable password 123 log file /usr/local/etc/quagga/bgpd.log ! router bgp 100 bgp router-id 2.2.2.2 bgp log-neighbor-changes no synchronization network 64.17.0.0/21 neighbor 2.2.2.1 remote-as 200 neighbor 2.2.2.1 description MY-PROVIDER neighbor 2.2.2.1 next-hop-self neighbor 2.2.2.1 route-map MY-PROVIDER-in in neighbor 2.2.2.1 route-map MY-PROVIDER-out out ! ip prefix-list bogons description bogus nets ip prefix-list bogons seq 15 permit 0.0.0.0/8 le 32 ip prefix-list bogons seq 20 permit 127.0.0.0/8 le 32 ip prefix-list bogons seq 30 permit 10.0.0.0/8 le 32 ip prefix-list bogons seq 35 permit 172.16.0.0/12 le 32 ip prefix-list bogons seq 40 permit 192.168.0.0/16 le 32 ip prefix-list bogons seq 45 permit 169.254.0.0/16 le 32 ip prefix-list bogons seq 50 permit 224.0.0.0/4 le 32 ip prefix-list bogons seq 55 permit 240.0.0.0/4 le 32 ip prefix-list default description default route ip prefix-list default seq 10 permit 0.0.0.0/0 ip prefix-list our-CIDR-blocks seq 5 permit 64.17.0.0/21 le 32 ip prefix-list upstream-out seq 10 permit 64.17.0.0/21 ! ip as-path access-list 1 permit _6451[2-9]_ ip as-path access-list 1 permit _645[2-9][0-9]_ ip as-path access-list 1 permit _64[6-9][0-9][0-9]_ ip as-path access-list 1 permit _65[0-9][0-9][0-9]_ ! route-map MY-PROVIDER-in deny 100 match as-path 1 ! route-map MY-PROVIDER-in deny 110 match ip address prefix-list bogons ! route-map MY-PROVIDER-in deny 115 match ip address prefix-list default ! route-map MY-PROVIDER-in deny 120 match ip address prefix-list our-CIDR-blocks ! route-map MY-PROVIDER-in permit 200 set local-preference 100 ! route-map MY-PROVIDER-out permit 100 match ip address prefix-list upstream-out ! route-map MY-PROVIDER-out deny 200 ! line vty !
Пройдемся по конфигу bgpd.conf
AS100 - Autonomous system, наш номер автономной системы так же выданный нам организацией RIPE
AS200 - автономная система нашего провайдера
no synchronization - не ждать подтверждения маршрута от протоколов внутреннего шлюза (IGP)
network 64.17.0.0/21 - указываем сеть для анонсирования командами neighbor мы описываем своего "соседа" (peer`а), указываем номер его AS, его IP-адрес, указываем маршрутные карты на вход и на выход, neighbor 2.2.2.1 next-hop-self - говорит о том, что для всех оглашаемых маршрутов next-hop будет выставлен на нас (в as-path будет содержаться номер нашей AS)
ip prefix-list bogons - описывает те сети маршруты в которые мы не хотим получать от своего "соседа"
ip as-path access-list 1 - описывает "серые" номера AS которые не маршрутизируются в сети Интернет и предоставлены для внутреннего использования, где бы они не встречались в as-path
route-map MY-PROVIDER-in - маршрутная карта которая применяется при передаче соседом маршрутов в нашу AS100
в deny 100 - запрещаем принимать маршруты в as-path которых содержатся "серые" AS, перечисленные в ip as-path access-list 1
в deny 110 - запрещаем принимать маршруты в которых содержатся сети перечисленные в ip prefix-list bogons
в deny 115 - запрещаем принимать default gateway
в deny 120 - запрещаем принимать маршрут в принадлежащие нам сети (наш блок адресов (prefix-list our-CIDR-blocks)) (на всякий случай ;))
в permit 200 - и последние правило которое разрешит все остальные маршруты и выставит на них local-preference 100
route-map MY-PROVIDER-out - маршрутная карта которая применяется при оглашении маршрутов от нашей AS100 к AS200 автономной системы нашего провайдера (prefix-list upstream-out).
в permit 100 - разрешаем свой блок /21
Принцип работы маршрутных карт (route-map) прост, то что разрешает access-list является совпадением, а дальше применяется действие указанное в маршрутной карте: permit или deny.
Последним действием которое не указано, но подразумевается это deny. Тот же самый принцип что и в access-list. Если совпадений не будет, то маршрут будет запрещен.
Рекомендуется присваивать "говорящие" названия для маршрутных карт (route-map) для дальнейшего удобства, когда конфиг будет разрастаться.
Ну вот мы и сделали необходимый минимум. Пишем в /etc/rc.conf:
quagga_enable="YES" quagga_daemons="zebra bgpd" quagga_flags="-d -A 127.0.0.1''
Стартуем:
/usr/local/etc/rc.d/quagga start
либо
/usr/local/sbin/zebra -f /usr/local/etc/quagga/zebra.conf -d -A 127.0.0.1 /usr/local/sbin/bgpd -f /usr/local/etc/quagga/bgpd.conf -d -A 127.0.0.1
Все то что описано в конфиге, можно настроить и через консоль, после запуска демона. Для того, чтобы настроить и управлять демоном zebra, после его запуска, устанавливаем telnet соединение на порт 2601 localhost (127.0.0.1:2601). Демон bgpd работает на порту 2605 localhost (127.0.0.1:2605).
Проверяем, что все работает: telnet 127.0.0.1 2605 вводим пароль 123 и переходим в enable режим опять таки вводя пароль 123 смотрим информацию по соседу, где нас интересует строка состояния:
sh ip bgp neighbors 2.2.2.1 .................. BGP state = Established, up for 09w6d19h .....................
даем команду sh ip bgp и смотрим получаем ли мы маршруты от соседа
AS100# sh ip bgp BGP table version is 0, local router ID is 89.111.159.22 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, R Removed Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path *> 3.0.0.0 2.2.2.1 100 0 200 310 600 701 703 80 i *> 4.0.0.0 2.2.2.1 100 0 200 310 3356 i *> 4.0.0.0/9 2.2.2.1 100 0 200 310 3356 i *> 4.23.112.0/24 2.2.2.1 100 0 200 310 174 21889 i *> 4.23.113.0/24 2.2.2.1 100 0 200 310 174 21889 i *> 4.23.114.0/24 2.2.2.1 100 0 200 310 174 21889 i *> 4.36.116.0/23 2.2.2.1 100 0 200 310 174 21889 i *> 4.36.116.0/24 2.2.2.1 100 0 200 310 174 21889 i *> 4.36.117.0/24 2.2.2.1 100 0 200 310 174 21889 i *> 4.36.118.0/24 2.2.2.1 100 0 200 310 174 21889 i ..................
Мы видим, что маршруты от соседа к нам приходят.
Теперь посмотрим, что мы огласили своему соседу:
sh ip bgp neighbors 2.2.2.1 BGP table version is 0, local router ID is 2.2.2.2 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, R Removed Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path *> 64.17.0.0/21 2.2.2.2 0 32768 i Total number of prefixes 1
Мы должны видеть наш блок адресов 64.17.0.0/21 и next-hop наш IP-адрес, если это так то все в порядке, наш маршрут соседу отправлен.
Настройка протокола BGP на оборудовании Cisco Systems
В основном принципе настройка на Cisco ничем не отличается от настройки BGP на FreeBSD используя Quagga.
Для примера возьмем немного другую ситуацию чем в предыдущей статье, итак:
схема BGP
AS200 -(full view)---> AS100 <--(private peer, 22.22.0.0/21)- AS300 <--(12.12.0.0/21)- AS400 (1.1.1.1/30) (1.1.1.2/30, 2.2.2.10/30) (2.2.2.9/20)
AS100 - наш номер ASки
5.5.0.0/20 - анонсируемый нами префикс (наш блок адресов)
AS200 - наш апстрим, который отдает нам full-view (полную таблицу маршрутов)
AS300 - наш privat peer (приватный пир), который отдает нам маршруты в свою AS и своего клиента AS400.
С чего начать ?
С настройки интерфейсов конечно.
GigabitEthernet3/0 - AS200 GigabitEthernet3/1 - AS300
Зайдите на router телнетом и перейдите в enable режим.
cisco# conf t cisco(config)# interface GigabitEthernet3/0 cisco(config-if)# ip address 1.1.1.2 255.255.255.252 cisco(config-if)# interface GigabitEthernet3/1 cisco(config-if)# ip address 2.2.2.10 255.255.255.252 cisco(config-if)# exit
Добавим маршруты, сначала отправим туда, откуда не возвращаются :), маршруты в "серые сети":
cisco(config)# ip route 10.0.0.0 255.0.0.0 Null0 254 cisco(config)# ip route 172.16.0.0 255.240.0.0 Null0 254 cisco(config)# ip route 192.168.0.0 255.255.0.0 Null0 254
Затем добавим маршрут на свой полный блок:
cisco(config)# ip route 5.5.0.0 255.255.240.0 Null0 254
Протокол BGP не будет анонсировать префикс, пока сам не узнает маршрут до него. Именно для этого мы и создали этот маршрут, который будет присутствовать в таблице маршрутизации всегда. Вы можете пророутить внутрь своей сети как полный блок (тогда маршрут в Null0 (нуль ноль) можно и не добавлять) так и его, побитые на подсети, части. Например подсети по /21:
cisco(config)# ip route 5.5.0.0 255.255.248.0 10.0.0.2 cisco(config)# ip route 5.5.0.0 255.255.248.0 10.0.0.3 Где:
* 10.0.0.2 * 10.0.0.3
маршрутизаторы внутри сети. Ессно, что они должны быть доступны с маршрутизатора BGP.
Роутер всегда отправляет пакеты по маршруту с лучшим совпадением по маске, именно поэтому маршрут в Null0 и два маршрута, которые мы сделали выше, будут прекрасно сосуществовать и пакеты будут идти на хосты 10.0.0.2 и 10.0.0.3, т.к. у них более точное совпадение по маске.
Приступим к созданию необходимых route-map. Сначала начнем со всего "серого" (адресов и номеров AS).
Создадим необходимые prefix-list и as-path access-list.
Маршрут в default: cisco(config)# ip prefix-list bogons description bogus nets cisco(config)# ip prefix-list bogons seq 15 permit 0.0.0.0/8 le 32 Затем остальное: cisco(config)# ip prefix-list bogons seq 20 permit 127.0.0.0/8 le 32 cisco(config)# ip prefix-list bogons seq 25 permit 192.0.2.0/24 le 32 cisco(config)# ip prefix-list bogons seq 30 permit 10.0.0.0/8 le 32 cisco(config)# ip prefix-list bogons seq 35 permit 172.16.0.0/12 le 32 cisco(config)# ip prefix-list bogons seq 40 permit 192.168.0.0/16 le 32 cisco(config)# ip prefix-list bogons seq 45 permit 169.254.0.0/16 le 32 cisco(config)# ip prefix-list bogons seq 50 permit 192.42.172.0/24 le 32 cisco(config)# ip prefix-list bogons seq 55 permit 198.18.0.0/15 le 32 cisco(config)# ip prefix-list bogons seq 60 permit 192.88.99.0/24 le 32 cisco(config)# ip prefix-list bogons seq 65 permit 224.0.0.0/4 le 32 cisco(config)# ip prefix-list bogons seq 70 permit 240.0.0.0/4 le 32
Теперь "серые" номера AS`ок: cisco(config)# ip as-path access-list 1 permit _6451[2-9]_ cisco(config)# ip as-path access-list 1 permit _645[2-9][0-9]_ cisco(config)# ip as-path access-list 1 permit _64[6-9][0-9][0-9]_ cisco(config)# ip as-path access-list 1 permit _65[0-9][0-9][0-9]_
Создадим маршрутную карту на IN для AS200 (нашего апстрима). Запрещаем маршруты с "серыми" номерами AS в as-path, то что матчит (разрешает (permit)) наш as-path access-list, то запрещает наша следующая маршрутная карта:
cisco(config)# route-map map-AS200-in deny 100 cisco(config-route-map)# description -- filter private ASs cisco(config-route-map)# match as-path 1 cisco(config-route-map)# exit
Теперь по маршруту по умолчанию и "серым" сетям, логика действия как и в пред. случае, запрещаем то что permit в prefix-list bogons:
cisco(config)# route-map map-AS200-in deny 110 cisco(config-route-map)# description -- - filter bogons cisco(config-route-map)# match ip address prefix-list bogons cisco(config-route-map)# exit
Ну и последнее, т.к. мы хотим принимать от AS200 full-view (т.е. полную таблицу), то:
* разрешаем все остальные маршруты * выставляем local-preference по умолчанию внутри своей AS
cisco(config)# route-map map-AS200-in permit 200 cisco(config-route-map)# description -- permit any else, set default loc-pref cisco(config-route-map)# set local-preference 100 cisco(config-route-map)# exit
Создадим маршрутную карту на OUT для AS200 (нашего апстрима). Эта маршрутная карта нужна нам для того, чтобы наша AS анонсировала только свой префикс. Если маршрутной карты на OUT не будет, то ваша AS будет анонсировать всем своим соседям все известные ей маршруты и вы, сами того не желая, дадите возможность прогонять через вас трафик. Но прежде создадим префикс лист со своим префиксом:
cisco(config)# ip prefix-list own-prefixes permit 5.5.0.0/20
Вот теперь вернемся к маршрутке на OUT:
cisco(config)# route-map map-AS200-out permit 100 cisco(config-route-map)# description -- permit our prefixes cisco(config-route-map)# match ip address prefix-list own-prefixes cisco(config-route-map)# exit
Т.к. в конце маршрутки по умолчанию идет неявный deny, то все остальные префиксы (маршруты) будут запрещены.
Настало время приступить к маршрутным картам для нашего private peer`а. Т.к. от него мы собираемся получать только маршруты принадлежащие ему (AS300) и его клиенту (AS400), то будет проще, разрешим только необходимые префиксы, а все остальное запретим:
cisco(config)# ip prefix-list peer-prefixes permit 11.11.0.0/21 cisco(config)# ip prefix-list peer-prefixes permit 12.12.0.0/21
Теперь можно создать маршрутную карту на IN, в которой разрешим необходимые префиксы и поднимем loc-pref, на данные префиксы, чтобы маршруты полученные от этого пира имели приоритет над маршрутами к этим префиксам полученными от других апстримов/пиров:
cisco(config)# route-map map-AS300-in permit 100 cisco(config-route-map)# description -- - permit peer prefix cisco(config-route-map)# match ip address prefix-list peer-prefixes cisco(config-route-map)# set local-preference 200 cisco(config-route-map)# exit
Ну и тут не обойдется без маршрутной карты на OUT:
cisco(config)# route-map map-AS300-out permit 100 cisco(config-route-map)# description -- permit our prefixes cisco(config-route-map)# match ip address prefix-list own-prefixes cisco(config-route-map)# exit
Зачем мы создали две маршрутные карты на OUT с разными названиями, но с одинаковым содержимым ? Ответ прост. Если, в последствии, нам нужно будет, например добавить community к своему маршруту или оглашать свой блок меньшими подсетями, то все равно придется делать разные маршрутные карты, вот поэтому сделаем это сразу, чтобы потом не изменять конфигурацию bgp, а просто подправить маршрутную карту.
Закончим подготовку перед настройкой BGP:
cisco(config)# ip classless cisco(config)# ip routing cisco(config)# ip subnet-zero
Подготовку мы сделали, теперь можно переходить непосредственно к настройке и запуску BGP.
cisco(config)# router bgp 100 cisco(config-router)# no synchronization cisco(config-router)# bgp log-neighbor-changes cisco(config-router)# bgp deterministic-med
Объявим наш префикс: cisco(config-router)# network 5.5.0.0 mask 255.255.240.0
Пропишем наего апстрима AS200: cisco(config-router)# neighbor 1.1.1.1 remote-as 200 cisco(config-router)# neighbor 1.1.1.1 description AS200-upstream cisco(config-router)# neighbor 1.1.1.1 send-community cisco(config-router)# neighbor 1.1.1.1 version 4 cisco(config-router)# neighbor 1.1.1.1 soft-reconfiguration inbound cisco(config-router)# neighbor 1.1.1.1 route-map map-AS200-in in cisco(config-router)# neighbor 1.1.1.1 route-map map-AS200-out out
Пропишем нашего private peer`а: cisco(config-router)# neighbor 2.2.2.9 remote-as 300 cisco(config-router)# neighbor 2.2.2.9 description AS300-private-peer cisco(config-router)# neighbor 2.2.2.9 send-community cisco(config-router)# neighbor 2.2.2.9 version 4 cisco(config-router)# neighbor 2.2.2.9 soft-reconfiguration inbound cisco(config-router)# neighbor 2.2.2.9 route-map map-AS300-in in cisco(config-router)# neighbor 2.2.2.9 route-map map-AS300-out out
Заканчиваем: cisco(config-router)# distance bgp 180 200 200 cisco(config-router)# no auto-summary cisco(config-router)# exit cisco(config)# exit cisco# wri
После запуска посмотрите, что все настроенные BGP сессии поднялись. Команда: cisco# show ip bgp summary
Так же стоит взгянуть что именно мы огласили нашему апстриму: cisco# show ip bgp neighbors 1.1.1.1 advertised-routes
И нашему private peer`у: cisco# show ip bgp neighbors 2.2.2.9 advertised-routes
Можно взглянуть и что мы от них получили: cisco# show ip bgp neighbors 1.1.1.1 received-routes cisco# show ip bgp neighbors 2.2.2.9 received-routes
После того как вы убедились, что все соответствует задуманному можно расслабиться и выпить пива :)
Заметка: После каждого изменения route-map, в процессе работы, чтобы изменения вступили в силу необходимо оборвать (clear`нуть) BGP сессию с сосседом.
Для того чтобы этого не делать и существует команда soft-reconfiguration inbound при настройке neighbor. Она заставляет роутер хранить маршруты полученные от соседа не только после обработки вашими route-map, но и до этого.
Тем самым вы не обрываете сессию с соседом, а роутер просто берет сохраненные у себя маршруты, которые пришли от соседа и сохранены в первозданном виде ДО обработки вашими route-map и снова прогоняет их через уже измененную route-map.
Например вы изменили route-map map-AS200-in, значит нуна клирнуть
сессию с соседом IP-адрес 1.1.1.1.
cisco# clear ip bgp 1.1.1.1 soft in
|