# BGP Gateway Failover: SWE-HIPHOST → FIN-HIPHOST
## Проблема
У вас есть:
- BGP приносит список адресов
- Трафик фильтруется на шлюз `swe-hiphost`
- Нужно автоматически переключаться на `fin-hiphost` при недоступности `swe-hiphost`
## Архитектура решения
```mermaid
graph TB
subgraph "HOME"
HOME[HOME
home.rt.shx.su]
BGP[BGP Routes]
FILTER[Route Filter
swe-hiphost]
FAILOVER[Failover Logic]
end
subgraph "Швеция"
SWE[SWE-HIPHOST
swe.hiphost.rt.shx.su]
BFD_SWE[BFD Session]
end
subgraph "Финляндия"
FIN[FIN-HIPHOST
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 вернется к нему.