412 lines
15 KiB
Markdown
412 lines
15 KiB
Markdown
# BGP Gateway Failover: SWE-HIPHOST → FIN-HIPHOST
|
||
|
||
## Проблема
|
||
|
||
У вас есть:
|
||
- BGP приносит список адресов
|
||
- Трафик фильтруется на шлюз `swe-hiphost`
|
||
- Нужно автоматически переключаться на `fin-hiphost` при недоступности `swe-hiphost`
|
||
|
||
## Архитектура решения
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "HOME"
|
||
HOME[HOME<br/>home.rt.shx.su]
|
||
BGP[BGP Routes]
|
||
FILTER[Route Filter<br/>swe-hiphost]
|
||
FAILOVER[Failover Logic]
|
||
end
|
||
|
||
subgraph "Швеция"
|
||
SWE[SWE-HIPHOST<br/>swe.hiphost.rt.shx.su]
|
||
BFD_SWE[BFD Session]
|
||
end
|
||
|
||
subgraph "Финляндия"
|
||
FIN[FIN-HIPHOST<br/>fin.hiphost.rt.shx.su]
|
||
BFD_FIN[BFD Session]
|
||
end
|
||
|
||
%% BGP и маршрутизация
|
||
BGP -. "BGP routes" .- HOME
|
||
FILTER -. "Primary gateway" .- SWE
|
||
FAILOVER -. "Backup gateway" .- FIN
|
||
|
||
%% BFD мониторинг
|
||
HOME -. "BFD monitoring" .- SWE
|
||
HOME -. "BFD monitoring" .- FIN
|
||
|
||
%% Failover
|
||
FAILOVER -. "Auto switch" .- FILTER
|
||
|
||
style HOME fill:#e1f5fe
|
||
style SWE fill:#4caf50
|
||
style FIN fill:#ff9800
|
||
style BFD_SWE fill:#9c27b0
|
||
style BFD_FIN fill:#9c27b0
|
||
```
|
||
|
||
## Решение 1: Динамические маршруты с check-gateway
|
||
|
||
### Настройка на HOME (home.rt.shx.su):
|
||
|
||
```shell
|
||
# Создать address-list для адресов из BGP (пример)
|
||
/ip firewall address-list
|
||
add list=BGP-ROUTES list=173.194.0.0/16 comment="BGP route"
|
||
add list=BGP-ROUTES list=74.125.0.0/16 comment="BGP route"
|
||
add list=BGP-ROUTES list=142.250.0.0/16 comment="BGP route"
|
||
# ... добавьте все ваши BGP маршруты
|
||
|
||
# Создать статические маршруты с failover
|
||
/ip route
|
||
# Основной маршрут через SWE-HIPHOST
|
||
add dst-address=173.194.0.0/16 gateway=swe-hiphost distance=1 check-gateway=ping
|
||
add dst-address=74.125.0.0/16 gateway=swe-hiphost distance=1 check-gateway=ping
|
||
add dst-address=142.250.0.0/16 gateway=swe-hiphost distance=1 check-gateway=ping
|
||
|
||
# Резервный маршрут через FIN-HIPHOST
|
||
add dst-address=173.194.0.0/16 gateway=fin-hiphost distance=2 check-gateway=ping
|
||
add dst-address=74.125.0.0/16 gateway=fin-hiphost distance=2 check-gateway=ping
|
||
add dst-address=142.250.0.0/16 gateway=fin-hiphost distance=2 check-gateway=ping
|
||
```
|
||
|
||
## Решение 2: BFD с динамическими маршрутами
|
||
|
||
### Настройка BFD мониторинга:
|
||
|
||
```shell
|
||
# Настроить BFD для SWE-HIPHOST
|
||
/routing bfd
|
||
add interface=gre-SWE-HIPHOST interval=100ms multiplier=3
|
||
|
||
# Настроить BFD для FIN-HIPHOST
|
||
/routing bfd
|
||
add interface=gre-FIN-HIPHOST interval=100ms multiplier=3
|
||
|
||
# Создать маршруты с check-gateway=bfd
|
||
/ip route
|
||
add dst-address=173.194.0.0/16 gateway=swe-hiphost distance=1 check-gateway=bfd
|
||
add dst-address=74.125.0.0/16 gateway=swe-hiphost distance=1 check-gateway=bfd
|
||
add dst-address=142.250.0.0/16 gateway=swe-hiphost distance=1 check-gateway=bfd
|
||
|
||
# Резервные маршруты
|
||
add dst-address=173.194.0.0/16 gateway=fin-hiphost distance=2 check-gateway=bfd
|
||
add dst-address=74.125.0.0/16 gateway=fin-hiphost distance=2 check-gateway=bfd
|
||
add dst-address=142.250.0.0/16 gateway=fin-hiphost distance=2 check-gateway=bfd
|
||
```
|
||
|
||
## Решение 3: Скрипт для автоматического управления маршрутами
|
||
|
||
### Создание скрипта на HOME:
|
||
|
||
```shell
|
||
# Скрипт для мониторинга и переключения шлюзов
|
||
/system script
|
||
add name=gateway-failover source={
|
||
:local sweStatus [/routing bfd print where interface=gre-SWE-HIPHOST]
|
||
:local finStatus [/routing bfd print where interface=gre-FIN-HIPHOST]
|
||
|
||
# Проверить статус SWE-HIPHOST
|
||
:if ([:len $sweStatus] > 0) do={
|
||
# SWE доступен - использовать его как primary
|
||
:log info "SWE-HIPHOST is UP - using as primary gateway"
|
||
/ip route set [find where dst-address=173.194.0.0/16 and gateway=swe-hiphost] distance=1
|
||
/ip route set [find where dst-address=173.194.0.0/16 and gateway=fin-hiphost] distance=2
|
||
/ip route set [find where dst-address=74.125.0.0/16 and gateway=swe-hiphost] distance=1
|
||
/ip route set [find where dst-address=74.125.0.0/16 and gateway=fin-hiphost] distance=2
|
||
/ip route set [find where dst-address=142.250.0.0/16 and gateway=swe-hiphost] distance=1
|
||
/ip route set [find where dst-address=142.250.0.0/16 and gateway=fin-hiphost] distance=2
|
||
} else={
|
||
# SWE недоступен - переключиться на FIN
|
||
:log info "SWE-HIPHOST is DOWN - switching to FIN-HIPHOST"
|
||
/ip route set [find where dst-address=173.194.0.0/16 and gateway=swe-hiphost] distance=100
|
||
/ip route set [find where dst-address=173.194.0.0/16 and gateway=fin-hiphost] distance=1
|
||
/ip route set [find where dst-address=74.125.0.0/16 and gateway=swe-hiphost] distance=100
|
||
/ip route set [find where dst-address=74.125.0.0/16 and gateway=fin-hiphost] distance=1
|
||
/ip route set [find where dst-address=142.250.0.0/16 and gateway=swe-hiphost] distance=100
|
||
/ip route set [find where dst-address=142.250.0.0/16 and gateway=fin-hiphost] distance=1
|
||
}
|
||
}
|
||
|
||
# Запускать скрипт каждые 5 секунд
|
||
/system scheduler
|
||
add name=gateway-failover interval=5s on-event=gateway-failover
|
||
```
|
||
|
||
## Решение 4: Routing Rules с динамическими таблицами
|
||
|
||
### Создание динамических routing tables:
|
||
|
||
```shell
|
||
# Создать routing tables для каждого шлюза
|
||
/routing table
|
||
add name=SWE-Gateway fib
|
||
add name=FIN-Gateway fib
|
||
|
||
# Создать address-list для BGP маршрутов
|
||
/ip firewall address-list
|
||
add list=BGP-ROUTES list=173.194.0.0/16 comment="BGP route"
|
||
add list=BGP-ROUTES list=74.125.0.0/16 comment="BGP route"
|
||
add list=BGP-ROUTES list=142.250.0.0/16 comment="BGP route"
|
||
|
||
# Routing rules для BGP маршрутов
|
||
/routing rule
|
||
add dst-address=173.194.0.0/16 action=lookup table=SWE-Gateway
|
||
add dst-address=74.125.0.0/16 action=lookup table=SWE-Gateway
|
||
add dst-address=142.250.0.0/16 action=lookup table=SWE-Gateway
|
||
|
||
# Маршруты в таблице SWE-Gateway
|
||
/ip route
|
||
add dst-address=0.0.0.0/0 gateway=swe-hiphost routing-table=SWE-Gateway distance=1
|
||
|
||
# Маршруты в таблице FIN-Gateway (резервные)
|
||
/ip route
|
||
add dst-address=0.0.0.0/0 gateway=fin-hiphost routing-table=FIN-Gateway distance=1
|
||
```
|
||
|
||
### Скрипт для переключения таблиц:
|
||
|
||
```shell
|
||
# Скрипт для переключения между routing tables
|
||
/system script
|
||
add name=switch-routing-table source={
|
||
:local sweStatus [/routing bfd print where interface=gre-SWE-HIPHOST]
|
||
|
||
:if ([:len $sweStatus] > 0) do={
|
||
# SWE доступен - использовать SWE-Gateway
|
||
:log info "SWE-HIPHOST is UP - using SWE-Gateway"
|
||
/routing rule set [find where table=SWE-Gateway] action=lookup
|
||
/routing rule set [find where table=FIN-Gateway] action=lookup-only
|
||
} else={
|
||
# SWE недоступен - переключиться на FIN-Gateway
|
||
:log info "SWE-HIPHOST is DOWN - switching to FIN-Gateway"
|
||
/routing rule set [find where table=SWE-Gateway] action=lookup-only
|
||
/routing rule set [find where table=FIN-Gateway] action=lookup
|
||
}
|
||
}
|
||
|
||
# Запускать каждые 5 секунд
|
||
/system scheduler
|
||
add name=switch-routing-table interval=5s on-event=switch-routing-table
|
||
```
|
||
|
||
## Решение 5: OSPF с динамическими cost
|
||
|
||
### Настройка OSPF с динамическим cost:
|
||
|
||
```shell
|
||
# Создать скрипт для изменения OSPF cost на основе доступности
|
||
/system script
|
||
add name=adjust-ospf-cost source={
|
||
:local sweStatus [/routing bfd print where interface=gre-SWE-HIPHOST]
|
||
:local finStatus [/routing bfd print where interface=gre-FIN-HIPHOST]
|
||
|
||
:local sweInterface [/routing ospf interface-template find where interfaces=gre-SWE-HIPHOST]
|
||
:local finInterface [/routing ospf interface-template find where interfaces=gre-FIN-HIPHOST]
|
||
|
||
# Настроить cost для SWE-HIPHOST
|
||
:if ([:len $sweStatus] > 0) do={
|
||
/routing ospf interface-template set $sweInterface cost=10
|
||
:log info "SWE-HIPHOST UP - OSPF cost=10"
|
||
} else={
|
||
/routing ospf interface-template set $sweInterface cost=1000
|
||
:log info "SWE-HIPHOST DOWN - OSPF cost=1000"
|
||
}
|
||
|
||
# Настроить cost для FIN-HIPHOST
|
||
:if ([:len $finStatus] > 0) do={
|
||
/routing ospf interface-template set $finInterface cost=20
|
||
:log info "FIN-HIPHOST UP - OSPF cost=20"
|
||
} else={
|
||
/routing ospf interface-template set $finInterface cost=1000
|
||
:log info "FIN-HIPHOST DOWN - OSPF cost=1000"
|
||
}
|
||
}
|
||
|
||
# Запускать каждые 5 секунд
|
||
/system scheduler
|
||
add name=adjust-ospf-cost interval=5s on-event=adjust-ospf-cost
|
||
```
|
||
|
||
## Автоматическое создание маршрутов из BGP
|
||
|
||
### Скрипт для автоматического создания маршрутов:
|
||
|
||
```shell
|
||
# Скрипт для создания маршрутов из BGP с failover
|
||
/system script
|
||
add name=create-bgp-routes source={
|
||
:local bgpRoutes [/routing bgp route print where active=yes]
|
||
:local sweStatus [/routing bfd print where interface=gre-SWE-HIPHOST]
|
||
|
||
:foreach route in=$bgpRoutes do={
|
||
:local dstAddress [:pick $route 0 [:find $route " "]]
|
||
|
||
# Проверить существует ли уже маршрут
|
||
:local existingRoute [/ip route print count-only where dst-address=$dstAddress]
|
||
|
||
:if ($existingRoute = 0) do={
|
||
# Создать маршрут с failover
|
||
:if ([:len $sweStatus] > 0) do={
|
||
# SWE доступен - создать с distance=1
|
||
/ip route add dst-address=$dstAddress gateway=swe-hiphost distance=1 check-gateway=bfd
|
||
/ip route add dst-address=$dstAddress gateway=fin-hiphost distance=2 check-gateway=bfd
|
||
:log info "Created route $dstAddress with SWE primary"
|
||
} else={
|
||
# SWE недоступен - создать с FIN primary
|
||
/ip route add dst-address=$dstAddress gateway=fin-hiphost distance=1 check-gateway=bfd
|
||
/ip route add dst-address=$dstAddress gateway=swe-hiphost distance=2 check-gateway=bfd
|
||
:log info "Created route $dstAddress with FIN primary"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
# Запускать каждые 30 секунд
|
||
/system scheduler
|
||
add name=create-bgp-routes interval=30s on-event=create-bgp-routes
|
||
```
|
||
|
||
## Проверка настройки
|
||
|
||
### Проверка BFD статуса:
|
||
```shell
|
||
# Проверить BFD сессии
|
||
/routing bfd print
|
||
|
||
# Проверить детали BFD
|
||
/routing bfd print detail
|
||
```
|
||
|
||
### Проверка маршрутов:
|
||
```shell
|
||
# Проверить все маршруты
|
||
/ip route print
|
||
|
||
# Проверить маршруты к конкретному адресу
|
||
/ip route print where dst-address~"173.194"
|
||
|
||
# Проверить routing tables
|
||
/ip route print where routing-table=SWE-Gateway
|
||
/ip route print where routing-table=FIN-Gateway
|
||
```
|
||
|
||
### Проверка BGP маршрутов:
|
||
```shell
|
||
# Проверить активные BGP маршруты
|
||
/routing bgp route print where active=yes
|
||
|
||
# Проверить BGP соседей
|
||
/routing bgp neighbor print
|
||
```
|
||
|
||
## Тестирование failover
|
||
|
||
### Тест 1: Проверка переключения при отключении SWE:
|
||
```shell
|
||
# Отключить GRE туннель к SWE
|
||
/interface gre disable [find where name=gre-SWE-HIPHOST]
|
||
|
||
# Подождать 10-30 секунд и проверить маршруты
|
||
/ip route print where dst-address~"173.194"
|
||
|
||
# Включить туннель обратно
|
||
/interface gre enable [find where name=gre-SWE-HIPHOST]
|
||
```
|
||
|
||
### Тест 2: Проверка traceroute:
|
||
```shell
|
||
# Проверить маршрут к BGP адресу
|
||
traceroute 173.194.0.1
|
||
|
||
# Должен показать путь через активный шлюз
|
||
```
|
||
|
||
## Мониторинг и логирование
|
||
|
||
### Настройка логирования:
|
||
```shell
|
||
# Включить логирование для BFD
|
||
/system logging
|
||
add topics=bfd
|
||
|
||
# Включить логирование для routing
|
||
/system logging
|
||
add topics=route
|
||
|
||
# Включить логирование для BGP
|
||
/system logging
|
||
add topics=bgp
|
||
```
|
||
|
||
### Создание дашборда:
|
||
```shell
|
||
# Скрипт для отображения статуса
|
||
/system script
|
||
add name=show-gateway-status source={
|
||
:log info "=== Gateway Status Report ==="
|
||
:log info "BFD Status:"
|
||
/routing bfd print
|
||
:log info "Active Routes:"
|
||
/ip route print where dst-address~"173.194"
|
||
:log info "BGP Routes:"
|
||
/routing bgp route print where active=yes
|
||
:log info "=== End Report ==="
|
||
}
|
||
|
||
# Запускать каждую минуту
|
||
/system scheduler
|
||
add name=gateway-status interval=1m on-event=show-gateway-status
|
||
```
|
||
|
||
## Полная конфигурация для копирования
|
||
|
||
### HOME (home.rt.shx.su):
|
||
```shell
|
||
# BFD для мониторинга шлюзов
|
||
/routing bfd
|
||
add interface=gre-SWE-HIPHOST interval=100ms multiplier=3
|
||
add interface=gre-FIN-HIPHOST interval=100ms multiplier=3
|
||
|
||
# Создать routing tables
|
||
/routing table
|
||
add name=SWE-Gateway fib
|
||
add name=FIN-Gateway fib
|
||
|
||
# Address-list для BGP маршрутов
|
||
/ip firewall address-list
|
||
add list=BGP-ROUTES list=173.194.0.0/16 comment="BGP route"
|
||
add list=BGP-ROUTES list=74.125.0.0/16 comment="BGP route"
|
||
add list=BGP-ROUTES list=142.250.0.0/16 comment="BGP route"
|
||
|
||
# Routing rules
|
||
/routing rule
|
||
add dst-address=173.194.0.0/16 action=lookup table=SWE-Gateway
|
||
add dst-address=74.125.0.0/16 action=lookup table=SWE-Gateway
|
||
add dst-address=142.250.0.0/16 action=lookup table=SWE-Gateway
|
||
|
||
# Маршруты в таблицах
|
||
/ip route
|
||
add dst-address=0.0.0.0/0 gateway=swe-hiphost routing-table=SWE-Gateway distance=1
|
||
add dst-address=0.0.0.0/0 gateway=fin-hiphost routing-table=FIN-Gateway distance=1
|
||
|
||
# Логирование
|
||
/system logging
|
||
add topics=bfd
|
||
add topics=route
|
||
add topics=bgp
|
||
```
|
||
|
||
## Заключение
|
||
|
||
Данное решение обеспечивает:
|
||
|
||
1. **Автоматический failover** между SWE-HIPHOST и FIN-HIPHOST
|
||
2. **Быстрое обнаружение проблем** через BFD (100ms интервал)
|
||
3. **Динамическое управление маршрутами** в зависимости от доступности шлюзов
|
||
4. **Поддержку BGP маршрутов** с автоматическим созданием failover маршрутов
|
||
5. **Гибкость настройки** через routing tables и rules
|
||
|
||
Теперь при недоступности SWE-HIPHOST трафик автоматически переключится на FIN-HIPHOST, а при восстановлении SWE-HIPHOST вернется к нему. |