Zebra и BGP в организации бесперебойной работы каналов связи с переключением на резервные на базе FreeBSD.На первый взгляд типичная задача обеспечения бесперебойной связи меджу удаленными точками при глубинном изучении выявила несколько различных по степени сложности подходов. Надо отметить что готовых и "родных" методов для решения этой проблемы ни в одной системе я не увидел. А зачастую задача усугубляется еще и требованиями к балансировке нагрузки, что тоже является очень непростой задачей, например, исходя из каких условий установить приоритеты использования каналов? А требования к балансировке могут быть самыми разными, например, стоимость трафика, ширина и скорость каналов, латентность(пинг). С честной балансировкой нагрузки во FreeBSD очень плохо в связи с отсутствием фичи "поддержка multi route path", это когда непосредственно в ядре хранится несколько записей для одного и того же хоста, с заданием приоритетов. А в Линуксе есть, ага. Но вернемся к нашей теме. Условно к решению задачи динамического переключения каналов есть два подхода. Первый, любительский, переключение каналов пингующими скриптами. Второй промышленный, настройкой и использованием bgp протокола динамической маршрутизации. Первый метод достаточно прост, и в этой заметке рассматриваться не будет, суть в двух словах: пингуем шлюзы, при отсутствии пинга прописываем default route на второй шлюз. Но мы же эта, конечно, легких путей не ищем :) В моем хитром случае (который подойдет далеко не всем) имеется: две площадки, которые нужно связать между собой бесперебойными каналами связи, сервер на площадке провайдера (он же главный роутер) в дальнейшем - colo (195.202.61.146, 195.202.61.164, 195.202.61.165), через который и проходит весь внешний трафик (самые недорогие тарифы). Одна площадка (в дальнейшем HQ - head quarter) имеет прямой канал на colocation (195.202.61.106-195.202.61.105) и два запасных провайдера (85.171.240.233, 215.36.171.94), другая площадка (в дальнейшем - склад), также имеет прямой канал к серверу на colocation (195.202.61.101-195.202.61.102) плюс дополнительный канал к резервному провайдеру (шлюз 195.29.234.110). Задача: динамическое переключение на резервные каналы при падении любого основного. Первое, с чего хотелось бы начать, так это с необходимости создания туннелей через шлюзы резервных провайдеров к colo серверу. Для чего? А очень просто, так нам не прийдется руками переписывать таблицы маршрутизации на складе для сетей расположенных в HQ (и к тому же в HQ не нужно будет переписывать таблицы для сетей склада, не говоря уже о сервере colo). Пробрасываем туннели к colo через резервных провайдеров через специальные FreeBSD теннельные gif интерфейсы. Тут есть небольшая загвоздка, для корректного проброса туннелей через резервных провайдеров нам необходимы дополнительные IP адреса на colo сервере, к которым мы пропишем пути через шлюзы резервных провайдеров. Для складского роутера, например, так: ----- gate-stock rc.conf ---- (FreeBSD 5.3) - ## резервный канал ifconfig_ste1="inet 195.29.234.110 netmask 255.255.255.252" ## основной канал к colo ifconfig_rl0="inet 195.202.61.102 netmask 255.255.255.252" ## локальная сеть ifconfig_ste0="inet 192.168.3.2 netmask 255.255.255.0" ## шлюз через неосновгого провайдера к colo route_165="195.202.61.165/32 195.29.234.109" static_routes="165" ## непосредственно проброс туннеля к colo gif_interfaces="gif0" gifconfig_gif0="195.29.234.110 195.202.61.165" ## виртуальная сеть ifconfig_gif0="192.168.8.10 netmask 255.255.255.252 192.168.8.9 netmask 255.255.255.252" ------------------------------ ----- gate-hq /etc/rc.conf -- (FreeBSD 5.4) - ## локальная сеть ifconfig_ste0="inet 192.168.0.1 netmask 255.255.255.0" ## один провайдер ifconfig_xl0="inet 215.36.171.94 netmask 255.255.255.240" ## основной канал ifconfig_fxp0="inet 195.202.61.106 netmask 255.255.255.252" ## статический маршрут через шлюз резервного провайдера route_164="195.202.61.164/32 215.36.171.93" static_routes="164" ## туннель через резервный маршрут gif_interfaces="gif0" gifconfig_gif0="215.36.171.94 195.202.61.164" ifconfig_gif0="inet 192.168.8.14 netmask 255.255.255.252 192.168.8.13 netmask 255.255.255.252" ------------------------------ ----- colo server /etc/rc.conf -- (в FreeBSD 4.11 отличается синтаксис gif от 5.3 !) - ifconfig_fxp0="inet 195.202.61.146 netmask 255.255.255.252" ## алиас 1 ifconfig_fxp0_alias0="inet 195.202.61.164 netmask 255.255.255.255" ## алиас 2 ifconfig_fxp0_alias1="inet 195.202.61.165 netmask 255.255.255.255" ### туннели к hq и склад gif_interfaces="gif0 gif1" gifconfig_gif0="195.202.61.165 195.29.234.110" gifconfig_gif1="195.202.61.164 215.36.171.94" ifconfig_gif0="inet 192.168.8.9 netmask 255.255.255.252 192.168.8.10 netmask 255.255.255.252" ifconfig_gif1="inet 192.168.8.13 netmask 255.255.255.252 192.168.8.14 netmask 255.255.255.252" --------------------------------- Внимание! Маршрутизацией, т.е. получением и передачей маршрутов заниматься у нас будет специальный демон: zebra. И у нас не будет явным образом задан default route! (look ma, no default route!) Подготовительные работы будем считать выполнеными. Да, скажете вы, а секурность? А вам, отвечу я, ничто не мешает повесить поверх туннелей ipsec криптование, но это уже тема для отдельной статьи. Перейдем к матчасти. Default route мы будем получать от colo сервера, который, в свою очередь, возьмет его у провайдера (Михайлову респект ;). Роутеры на складе и HQ будут автоматически пинговать по маршрутам, и анонсировать живые маршруты далее по цепочке соседских роутеров. Пару слов о BGP (в моем холопском понимании). Единицей, с которой работает BGP является запись о известном маршруте, который роутер может передавать соседнему роутеру. Область, в которой объединены роутеры под управлением одного администратора называется AS (автономная система). AS диапазоны выдаются провайдерам организацией RIPE и берут за это деньги :) Существует специальный AS номер для приватных сетей 65001, который мы и будем использовать в нашем примере, это наподобие зарезервированных частных сетей 127.0.0 и 192.168.0. :) Когда анонс внутреннего машршута (iBGP) выходит за пределы своей AS он становится "внешним" (eBGP). Работа с внешними маршрутами имеет свои нюансы, в которые мы пока вдаваться не будем. Подготовим зебру к запуску при загрузке, для чего у каждого сервера укажем в rc.conf router_enable="YES" router="/usr/local/sbin/zebractl" router_flags="start" И перейдем к фазе конфигурации. Настроим colo сервер на дружбу с соседскими роутерами и беспрепятственным получением маршрутов. ---- colo сервер /usr/local/etc/zebra/bgpd.conf --- ## приватный диапазон router bgp 65001 bgp router-id 195.202.61.146 ## соседний роутер в той же AS neighbor 195.202.61.106 remote-as 65001 ## заменяем провайдерский default route на свой neighbor 195.202.61.106 next-hop-self ## необходимо указывать в internal bgp непосредственно для передачи маршрутов от роутера neighbor 195.202.61.106 route-reflector-client neighbor 195.202.61.102 remote-as 65001 neighbor 195.202.61.102 next-hop-self neighbor 195.202.61.102 route-reflector-client ## предпочтительный канал с весом 2000 (этой штукой мы задаем используемы канал по умолчанию как основной) neighbor 195.202.61.102 weight 2000 neighbor 192.168.8.14 remote-as 65001 neighbor 192.168.8.14 next-hop-self neighbor 192.168.8.14 route-reflector-client neighbor 192.168.8.10 remote-as 65001 neighbor 192.168.8.10 next-hop-self neighbor 192.168.8.10 route-reflector-client ## резервный канал с весом 1000, тот, на который мы переключимся при падении основного neighbor 192.168.8.10 weight 1000 ## передавать маршруты со статусом CONNECTED redistribute connected ## получение default route из провайдерского BGP и его AS neighbor 195.202.61.145 remote-as 24995 neighbor 195.202.61.145 prefix-list DENYALL out neighbor 195.202.61.145 ebgp-multihop 3 ip prefix-list DENYALL deny 0.0.0.0/0 log stdout ------------------------------------------------- Роутер на складе. --- gate-stock /usr/local/etc/zebra/bgpd.conf --- ## тот же приватный AS router bgp 65001 bgp router-id 195.202.61.102 network 192.168.3.0/24 ## его непосредственный сосед - colo сервер neighbor 195.202.61.101 remote-as 65001 neighbor 195.202.61.101 next-hop-self neighbor 195.202.61.101 route-reflector-client neighbor 195.202.61.101 distribute-list 1 out ## задаем основной канал neighbor 195.202.61.101 weight 2000 neighbor 192.168.8.9 remote-as 65001 neighbor 192.168.8.9 next-hop-self neighbor 192.168.8.9 route-reflector-client neighbor 192.168.8.9 distribute-list 1 out ## задаем резервный канал neighbor 192.168.8.9 weight 1000 ## разрешаем передавать свои маршруты redistribute connected ## не анонсируем маршруты через другого провайдера access-list 1 deny 195.29.234.0 0.0.0.255 access-list 1 permit any log file bgpd.log log stdout ------------------------------------------ Роутер в HQ --- gate-hq /usr/local/etc/zebra/bgpd.conf --- router bgp 65001 bgp router-id 195.202.61.106 neighbor 195.202.61.105 remote-as 65001 neighbor 195.202.61.105 next-hop-self neighbor 195.202.61.105 route-reflector-client neighbor 195.202.61.105 distribute-list 1 out neighbor 192.168.8.13 weight 2000 !redistribute connected neighbor 192.168.8.13 remote-as 65001 neighbor 192.168.8.13 next-hop-self neighbor 192.168.8.13 route-reflector-client neighbor 192.168.8.13 weight 1000 access-list 1 deny 215.36.171.0 0.0.0.255 access-list 1 permit any access-list all permit any log stdout ---------------------------------------------- Демоном зебры мы можем управлять через zebractl [start|stop|restart] Кончено, с первого раза врядли у вас все пойдет как по маслу, поэтому для отладки bgp задайте в обязательном порядке пароль для соединения с консолью зебры password xxxxx enable password yyyyy Для просмотра и отладки таблицы маршрутизации роутеров запускаем телнет и коннектимся к складскому роутеру на порт 2601 >telnet gate-stock 2601 оказываемся в консоли: gate-stock> show ip rou Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, B - BGP, > - selected route, * - FIB route ## машрут по умолчанию, B указывает на то, что он получен по протоколу BGP B>* 0.0.0.0/0 [200/0] via 195.202.61.101, rl0, 3d01h38m ## модем 1 B>* 10.1.0.104/29 [200/0] via 195.202.61.101, rl0, 3d01h38m ## модем 2 B>* 10.1.0.112/29 [200/0] via 195.202.61.101, rl0, 3d01h38m C>* 127.0.0.0/8 is directly connected, lo0 C>* 192.168.3.0/24 is directly connected, ste0 C>* 192.168.8.8/30 is directly connected, gif0 ## по BGP получием также и другие маршруты, прописанные на colo B>* 192.168.8.12/30 [200/0] via 195.202.61.101, rl0, 3d01h38m B>* 192.168.26.104/32 [200/0] via 195.202.61.101, rl0, 02:22:12 C>* 195.29.234.108/30 is directly connected, ste1 C>* 195.202.61.100/30 is directly connected, rl0 B>* 195.202.61.104/30 [200/0] via 195.202.61.101, rl0, 3d01h38m B>* 195.202.61.144/30 [200/0] via 195.202.61.101, rl0, 3d01h38m B>* 195.202.61.164/30 [200/0] via 195.202.61.101, rl0, 3d01h38m S>* 195.202.61.164/32 [1/0] via 195.29.234.109, ste1 ## вот она, заветная строчка, > указывает на то, что маршрут в данный момент не выбран, и является бекапным B 195.202.61.165/32 [200/0] via 195.202.61.101, rl0, 3d01h38m K>* 195.202.61.165/32 via 195.29.234.109, ste1 Для просмотра и отладки работы BGP протокола запускаем телнет и коннектимся к зебре на порт 2605 >telnet gate-stock 2605 bgpd> show ip bgp BGP table version is 0, local router ID is 195.202.61.102 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path ## два маршрута по умолчанию :) сейчас выбран гейт с наибольшим приоритетом * i0.0.0.0 192.168.8.9 100 1000 24995 i *>i 195.202.61.101 100 2000 24995 i ## резервный гейт, неактивен * i10.1.0.104/29 192.168.8.9 0 100 1000 ? *>i 195.202.61.101 0 100 2000 ? * i10.1.0.112/29 192.168.8.9 0 100 1000 ? *>i 195.202.61.101 0 100 2000 ? * i192.168.0.0 195.202.61.106 0 100 1000 i * i 195.202.61.106 0 100 2000 i * 192.168.3.0 0.0.0.0 0 32768 ? *> 0.0.0.0 0 32768 i * i192.168.5.0 195.202.61.106 0 100 1000 i * i 195.202.61.106 0 100 2000 i * i192.168.6.0 195.202.61.106 0 100 1000 i * i 195.202.61.106 0 100 2000 i * i192.168.7.0 195.202.61.106 0 100 1000 i * i 195.202.61.106 0 100 2000 i * i192.168.8.8/30 192.168.8.9 0 100 1000 ? * i 195.202.61.101 0 100 2000 ? * i192.168.8.12/30 192.168.8.9 0 100 1000 ? *>i 195.202.61.101 0 100 2000 ? * i192.168.26.104/32 192.168.8.9 0 100 1000 ? *>i 195.202.61.101 0 100 2000 ? *> 195.29.234.108/30 0.0.0.0 0 32768 ? * i195.202.61.100/30 192.168.8.9 0 100 1000 ? * i 195.202.61.101 0 100 2000 ? *> 0.0.0.0 0 32768 ? * i195.202.61.104/30 192.168.8.9 0 100 1000 ? *>i 195.202.61.101 0 100 2000 ? * i195.202.61.144/30 192.168.8.9 0 100 1000 ? *>i 195.202.61.101 0 100 2000 ? * i195.202.61.164/30 192.168.8.9 0 100 1000 ? *>i 195.202.61.101 0 100 2000 ? * i195.202.61.165/32 192.168.8.9 0 100 1000 ? *>i 195.202.61.101 0 100 2000 ? * i195.202.61.184/29 195.202.61.106 0 100 1000 ? * i 195.202.61.106 0 100 2000 ? Total number of prefixes 18 Стоит отметить, что BGP протокол достаточно неторопливый, смена маршрутов иногда занимает несколько минут, но тем не менее, работает!
по моей просьбе были даны дельные комментарии от гуру: кроме того можно заюзать механизм "bgp dampening" дабы не переключатся на хлопающий канал... |
© Максим Прокопов 2005-2024 | О сервере |