OSPF на MikroTik — динамическая маршрутизация для офисов
OSPF (Open Shortest Path First) — протокол динамической маршрутизации, который автоматически строит таблицу маршрутов между всеми участниками сети. В RouterOS 7 синтаксис настройки OSPF полностью переработан: появились instance, area и interface-template вместо прежних network-объявлений. В этом руководстве настроим OSPF v2 для связи трёх офисов через VPN-туннели, разберём фильтрацию маршрутов и диагностику.
Описание
Зачем нужен OSPF
При наличии двух-трёх офисов статические маршруты ещё управляемы. Но когда филиалов больше пяти, ручное управление маршрутами становится кошмаром:
- Добавление нового офиса требует изменений на всех маршрутизаторах
- При падении канала маршруты не переключаются автоматически
- Нет информации о состоянии каналов в реальном времени
OSPF решает эти проблемы:
| Преимущество | Описание |
|---|---|
| Автоматическое построение маршрутов | Каждый роутер узнаёт о подсетях всех участников автоматически |
| Быстрая сходимость | При падении линка маршруты перестраиваются за секунды |
| Оптимальный путь | OSPF выбирает кратчайший маршрут на основе стоимости (cost) |
| Масштабируемость | Поддержка зон (area) позволяет строить сети любого размера |
| Стандартный протокол | Совместимость с Cisco, Juniper, Linux и другими вендорами |
Ключевые концепции OSPF
Router ID — уникальный 32-битный идентификатор маршрутизатора в формате IP-адреса. Рекомендуется задавать явно, чтобы избежать непредсказуемого поведения при смене IP-адресов.
Area — логическая зона, в которую объединяются маршрутизаторы. Area 0 (backbone) — обязательная центральная зона. Все остальные зоны должны быть подключены к Area 0 напрямую или через virtual link.
Cost — метрика, определяющая «стоимость» маршрута. Чем ниже cost, тем предпочтительнее маршрут. По умолчанию cost рассчитывается как reference-bandwidth / interface-bandwidth.
DR/BDR — Designated Router и Backup Designated Router. На broadcast-сегментах (Ethernet) OSPF выбирает один DR, который собирает и распространяет LSA. Это уменьшает количество служебного трафика. На point-to-point линках (VPN-туннели) DR/BDR не используются.
LSA (Link-State Advertisement) — пакеты с информацией о состоянии каналов, которые маршрутизаторы обмениваются между собой для построения единой карты сети.
LSDB (Link-State Database) — база данных всех LSA, одинаковая на всех маршрутизаторах в пределах одной области. На её основе алгоритм Дийкстры рассчитывает кратчайшие пути.
Схема сети
Три офиса, соединённые WireGuard-туннелями через Area 0:
code[Офис A - HQ] Router ID: 1.1.1.1 LAN: 192.168.10.0/24 WG: 10.255.255.1/30 (к B) WG: 10.255.255.5/30 (к C) / \ / \ [Офис B] [Офис C] Router ID: 2.2.2.2 Router ID: 3.3.3.3 LAN: 192.168.20.0/24 LAN: 192.168.30.0/24 WG: 10.255.255.2/30 WG: 10.255.255.6/30
Предполагается, что WireGuard-туннели уже настроены и работают. OSPF будет объявлять LAN-подсети каждого офиса и автоматически строить маршруты.
Настройка
Синтаксис OSPF в RouterOS 7
В RouterOS 7 структура OSPF полностью изменена по сравнению с v6:
| RouterOS 6 (старый синтаксис) | RouterOS 7 (новый синтаксис) |
|---|---|
/routing ospf instance | /routing/ospf/instance |
/routing ospf area | /routing/ospf/area |
/routing ospf network | Заменено на /routing/ospf/interface-template |
/routing ospf interface | Объединено в /routing/ospf/interface-template |
Ключевое отличие: в RouterOS 7 нет секции network. Вместо этого используются interface-template с масками интерфейсов.
Шаг 1: Настройка OSPF Instance
Instance — это экземпляр процесса OSPF. Для каждого маршрутизатора создаём instance с уникальным Router ID.
Офис A (HQ):
[admin@MikroTik] >/routing/ospf/instance add name=ospf-main \ router-id=1.1.1.1 \ version=2 \ redistribute=connected \ comment="Main OSPF instance"
Офис B:
[admin@MikroTik] >/routing/ospf/instance add name=ospf-main \ router-id=2.2.2.2 \ version=2 \ redistribute=connected \ comment="Main OSPF instance"
Офис C:
[admin@MikroTik] >/routing/ospf/instance add name=ospf-main \ router-id=3.3.3.3 \ version=2 \ redistribute=connected \ comment="Main OSPF instance"
Параметр redistribute=connected указывает OSPF объявлять directly connected подсети (LAN-подсети) как external-маршруты. Альтернативно, можно объявлять LAN-подсети через interface-template напрямую.
Шаг 2: Создание OSPF Area
Для простых сценариев достаточно одной Area 0 (backbone):
На каждом маршрутизаторе:
[admin@MikroTik] >/routing/ospf/area add name=backbone \ instance=ospf-main \ area-id=0.0.0.0
Если сеть крупная (более 50 маршрутизаторов), имеет смысл разделить на несколько Area. Например, каждый регион — отдельная Area:
[admin@MikroTik] ># Пример для крупной сети (не для нашего сценария) /routing/ospf/area add name=region-east \ instance=ospf-main \ area-id=0.0.0.1 \ type=default
Шаг 3: Настройка Interface Templates
Interface template определяет, на каких интерфейсах включается OSPF и с какими параметрами. Это самая важная часть конфигурации в RouterOS 7.
Офис A (HQ):
[admin@MikroTik] ># OSPF на WireGuard-туннеле к Офису B /routing/ospf/interface-template add \ interfaces=wg-to-office-b \ area=backbone \ type=ptp \ cost=10 \ hello-interval=10s \ dead-interval=40s \ comment="WG tunnel to Office B" # OSPF на WireGuard-туннеле к Офису C /routing/ospf/interface-template add \ interfaces=wg-to-office-c \ area=backbone \ type=ptp \ cost=10 \ hello-interval=10s \ dead-interval=40s \ comment="WG tunnel to Office C" # OSPF на LAN-интерфейсе (для объявления подсети) /routing/ospf/interface-template add \ interfaces=bridge-lan \ area=backbone \ type=broadcast \ passive \ cost=1 \ comment="LAN network - passive"
Офис B:
[admin@MikroTik] >/routing/ospf/interface-template add \ interfaces=wg-to-office-a \ area=backbone \ type=ptp \ cost=10 \ hello-interval=10s \ dead-interval=40s \ comment="WG tunnel to Office A" /routing/ospf/interface-template add \ interfaces=bridge-lan \ area=backbone \ type=broadcast \ passive \ cost=1 \ comment="LAN network - passive"
Офис C:
[admin@MikroTik] >/routing/ospf/interface-template add \ interfaces=wg-to-office-a \ area=backbone \ type=ptp \ cost=10 \ hello-interval=10s \ dead-interval=40s \ comment="WG tunnel to Office A" /routing/ospf/interface-template add \ interfaces=bridge-lan \ area=backbone \ type=broadcast \ passive \ cost=1 \ comment="LAN network - passive"
Ключевые параметры interface-template:
| Параметр | Значение | Описание |
|---|---|---|
| type | ptp | Point-to-point — для VPN-туннелей (без выбора DR/BDR) |
| type | broadcast | Для Ethernet-сегментов (с выбором DR/BDR) |
| passive | — | Интерфейс объявляет подсеть, но не отправляет Hello-пакеты и не формирует соседство |
| cost | 10 | Стоимость маршрута через данный интерфейс |
| hello-interval | 10s | Интервал отправки Hello-пакетов |
| dead-interval | 40s | Время, после которого сосед считается недоступным (обычно 4x hello) |
Важно: LAN-интерфейсы настроены как passive. Это означает, что OSPF объявляет их подсети, но не пытается найти соседей на этих интерфейсах. Это правильный подход для клиентских сетей, где нет других OSPF-маршрутизаторов.
Шаг 4: Использование масок интерфейсов
Вместо перечисления каждого интерфейса можно использовать wildcard-маски:
[admin@MikroTik] ># Включить OSPF на всех WireGuard-интерфейсах, начинающихся с "wg-" /routing/ospf/interface-template add \ interfaces=wg-* \ area=backbone \ type=ptp \ cost=10
Это удобно при большом количестве туннелей — новые интерфейсы автоматически подхватываются OSPF.
Шаг 5: Фильтрация маршрутов
Не всегда нужно объявлять все подсети. Например, management-сеть администраторов не должна быть доступна из филиалов.
Фильтрация через routing filter:
[admin@MikroTik] ># Создаём правило фильтрации /routing/filter/rule add chain=ospf-out \ rule="if (dst == 192.168.99.0/24) { reject }" # Применяем фильтр к OSPF instance /routing/ospf/instance set ospf-main out-filter-chain=ospf-out
Фильтрация входящих маршрутов:
[admin@MikroTik] >/routing/filter/rule add chain=ospf-in \ rule="if (dst == 10.0.0.0/8) { reject }" /routing/ospf/instance set ospf-main in-filter-chain=ospf-in
Контроль redistribute:
Вместо redistribute=connected можно точнее контролировать, какие маршруты попадают в OSPF:
[admin@MikroTik] >/routing/filter/rule add chain=ospf-redist \ rule="if (dst == 192.168.10.0/24) { accept } else { reject }" /routing/ospf/instance set ospf-main \ redistribute=connected \ out-filter-chain=ospf-redist
Шаг 6: Настройка аутентификации OSPF
Для защиты OSPF-сессий от подмены используйте аутентификацию:
[admin@MikroTik] ># MD5-аутентификация на интерфейсе /routing/ospf/interface-template set \ [find comment="WG tunnel to Office B"] \ auth=md5 \ auth-id=1 \ auth-key="OspfSecretKey2024"
Ключ и auth-id должны совпадать на обоих концах линка.
Проверка
Проверка соседства
Самый важный шаг — убедиться, что маршрутизаторы установили OSPF-соседство:
[admin@MikroTik] >/routing/ospf/neighbor print
Ожидаемый вывод на Офисе A:
codeColumns: ROUTER-ID, ADDRESS, INSTANCE, AREA, STATE-CHANGES, STATE # ROUTER-ID ADDRESS INSTANCE AREA STATE-CHANGES STATE 0 2.2.2.2 10.255.255.2 ospf-main backbone 6 Full 1 3.3.3.3 10.255.255.6 ospf-main backbone 6 Full
Состояние Full означает, что соседство полностью установлено и базы LSA синхронизированы.
Возможные состояния:
| State | Описание |
|---|---|
| Down | Нет связи с соседом |
| Init | Получен Hello, но двусторонняя связь не подтверждена |
| 2-Way | Двусторонняя связь подтверждена, идёт выбор DR/BDR |
| ExStart | Начало обмена базами данных |
| Exchange | Обмен Database Description пакетами |
| Loading | Загрузка LSA |
| Full | Полная синхронизация — рабочее состояние |
Проверка таблицы маршрутов
[admin@MikroTik] >/ip/route print where routing-table=main ospf
Должны появиться маршруты ко всем удалённым подсетям:
codeColumns: DST-ADDRESS, GATEWAY, DISTANCE # DST-ADDRESS GATEWAY DISTANCE 0 192.168.20.0/24 10.255.255.2 110 1 192.168.30.0/24 10.255.255.6 110
Distance 110 — стандартное значение для OSPF. Если статический маршрут с distance 1 существует для той же подсети, он будет приоритетнее.
Просмотр LSDB
[admin@MikroTik] >/routing/ospf/lsa print
Эта команда показывает все LSA в базе данных. Типы LSA:
| Тип | Название | Описание |
|---|---|---|
| 1 | Router LSA | Информация о линках маршрутизатора |
| 2 | Network LSA | Информация о broadcast-сети (генерируется DR) |
| 3 | Summary LSA | Межзонные маршруты (от ABR) |
| 5 | External LSA | Внешние маршруты (redistribute) |
Проверка OSPF-интерфейсов
[admin@MikroTik] >/routing/ospf/interface print detail
Убедитесь, что каждый интерфейс находится в ожидаемом состоянии, указана правильная area и cost.
Трассировка маршрута
[admin@MikroTik] >/tool traceroute 192.168.30.1 src-address=192.168.10.1
Тест при отказе канала
Отключите WireGuard-туннель к одному из офисов и наблюдайте за перестроением маршрутов:
[admin@MikroTik] ># Отключаем туннель /interface/wireguard disable wg-to-office-c # Через 40 секунд (dead-interval) проверяем соседей /routing/ospf/neighbor print # Проверяем, изменились ли маршруты /ip/route print where dst-address=192.168.30.0/24 # Включаем обратно /interface/wireguard enable wg-to-office-c
Если между Офисом B и Офисом C существует прямой туннель, OSPF автоматически перенаправит трафик через него.
Типичные ошибки
1. Соседство не устанавливается (состояние Init или Down)
Причина: несовпадение параметров Hello-interval, Dead-interval, Area ID или аутентификации.
Решение:
[admin@MikroTik] ># Проверьте параметры на обеих сторонах /routing/ospf/interface-template print detail # Убедитесь, что hello-interval и dead-interval одинаковы # Убедитесь, что area-id совпадает # Проверьте аутентификацию — ключ должен быть идентичным
Также проверьте, что файрвол не блокирует OSPF-трафик (протокол 89):
[admin@MikroTik] >/ip firewall filter add chain=input protocol=ospf action=accept \ comment="Allow OSPF" place-before=0
2. Соседство зависает в состоянии ExStart/Exchange
Причина: проблема с MTU. OSPF проверяет MTU при обмене Database Description (DD) пакетами. Если MTU отличается — обмен зависает.
Решение:
[admin@MikroTik] ># Проверьте MTU на интерфейсах туннеля /interface print detail where name~"wg-" # Установите одинаковый MTU на обоих концах /interface/wireguard set wg-to-office-b mtu=1420
Альтернативный вариант — отключить проверку MTU (не рекомендуется как постоянное решение, но помогает при диагностике):
[admin@MikroTik] ># В RouterOS 7 можно игнорировать MTU mismatch через interface-template # Убедитесь, что type=ptp для VPN-линков — это избавляет от многих проблем
3. Маршруты появляются, но трафик не проходит
Причина: файрвол блокирует транзит или incorrect NAT.
Решение:
[admin@MikroTik] ># Проверьте forward-цепочку /ip firewall filter print where chain=forward # Добавьте правила для OSPF-подсетей /ip firewall filter add chain=forward \ src-address=192.168.0.0/16 dst-address=192.168.0.0/16 \ action=accept comment="Allow inter-office traffic" place-before=0 # Исключите inter-office трафик из NAT /ip firewall nat add chain=srcnat \ src-address=192.168.0.0/16 dst-address=192.168.0.0/16 \ action=accept place-before=0
4. Route flapping (маршруты постоянно появляются и исчезают)
Причина: нестабильный линк (packet loss на VPN-туннеле), из-за чего OSPF-соседство периодически рвётся.
Решение: увеличьте таймеры, чтобы OSPF был менее чувствителен к кратковременным потерям:
[admin@MikroTik] >/routing/ospf/interface-template set \ [find comment="WG tunnel to Office B"] \ hello-interval=30s \ dead-interval=120s
Но помните: увеличение таймеров замедляет сходимость при реальном отказе. Лучше устранить первопричину — нестабильность канала.
5. Неправильный Router ID
Причина: Router ID не задан явно и выбирается автоматически. При перезагрузке или изменении IP-адресов он может измениться, что приводит к пересчёту всей LSDB.
Решение:
[admin@MikroTik] ># Всегда задавайте Router ID явно /routing/ospf/instance set ospf-main router-id=1.1.1.1
Используйте IP-адрес loopback-интерфейса или просто уникальный идентификатор в формате IP.
6. Redistribute connected добавляет лишние подсети
Причина: redistribute=connected объявляет все directly connected сети, включая management-подсеть, WAN-подсеть и т.д.
Решение: используйте фильтр для redistribute или добавляйте подсети через passive-интерфейсы вместо redistribute:
[admin@MikroTik] ># Вариант 1: фильтр /routing/filter/rule add chain=ospf-redist \ rule="if (dst == 192.168.10.0/24) { accept } else { reject }" /routing/ospf/instance set ospf-main \ redistribute=connected \ out-filter-chain=ospf-redist # Вариант 2: убрать redistribute и использовать passive interface /routing/ospf/instance set ospf-main redistribute="" /routing/ospf/interface-template add \ interfaces=bridge-lan \ area=backbone \ passive \ cost=1
Вариант 2 предпочтительнее, так как подсети объявляются как intra-area (тип LSA 1), а не external (тип LSA 5).
Мониторинг OSPF в продакшене
Для постоянного мониторинга настройте логирование:
[admin@MikroTik] >/system logging add topics=ospf,!debug action=memory
Регулярно проверяйте:
[admin@MikroTik] ># Количество соседей /routing/ospf/neighbor print count-only # Количество маршрутов от OSPF /ip/route print count-only where ospf # Статистика по instance /routing/ospf/instance print detail
OSPF — мощный инструмент для построения автоматически управляемой маршрутизации между филиалами. При правильной настройке он избавляет от ручного управления маршрутами и обеспечивает автоматическое переключение при отказах. Начинайте с простой конфигурации с одной Area 0 и добавляйте сложность по мере роста сети.
[Офис A - HQ]
Router ID: 1.1.1.1
LAN: 192.168.10.0/24
WG: 10.255.255.1/30 (к B)
WG: 10.255.255.5/30 (к C)
/ \
/ \
[Офис B] [Офис C]
Router ID: 2.2.2.2 Router ID: 3.3.3.3
LAN: 192.168.20.0/24 LAN: 192.168.30.0/24
WG: 10.255.255.2/30 WG: 10.255.255.6/30
/routing/ospf/instance add name=ospf-main \
router-id=1.1.1.1 \
version=2 \
redistribute=connected \
comment="Main OSPF instance"
/routing/ospf/instance add name=ospf-main \
router-id=2.2.2.2 \
version=2 \
redistribute=connected \
comment="Main OSPF instance"
/routing/ospf/instance add name=ospf-main \
router-id=3.3.3.3 \
version=2 \
redistribute=connected \
comment="Main OSPF instance"
/routing/ospf/area add name=backbone \
instance=ospf-main \
area-id=0.0.0.0
# Пример для крупной сети (не для нашего сценария)
/routing/ospf/area add name=region-east \
instance=ospf-main \
area-id=0.0.0.1 \
type=default
# OSPF на WireGuard-туннеле к Офису B
/routing/ospf/interface-template add \
interfaces=wg-to-office-b \
area=backbone \
type=ptp \
cost=10 \
hello-interval=10s \
dead-interval=40s \
comment="WG tunnel to Office B"
# OSPF на WireGuard-туннеле к Офису C
/routing/ospf/interface-template add \
interfaces=wg-to-office-c \
area=backbone \
type=ptp \
cost=10 \
hello-interval=10s \
dead-interval=40s \
comment="WG tunnel to Office C"
# OSPF на LAN-интерфейсе (для объявления подсети)
/routing/ospf/interface-template add \
interfaces=bridge-lan \
area=backbone \
type=broadcast \
passive \
cost=1 \
comment="LAN network - passive"
/routing/ospf/interface-template add \
interfaces=wg-to-office-a \
area=backbone \
type=ptp \
cost=10 \
hello-interval=10s \
dead-interval=40s \
comment="WG tunnel to Office A"
/routing/ospf/interface-template add \
interfaces=bridge-lan \
area=backbone \
type=broadcast \
passive \
cost=1 \
comment="LAN network - passive"
/routing/ospf/interface-template add \
interfaces=wg-to-office-a \
area=backbone \
type=ptp \
cost=10 \
hello-interval=10s \
dead-interval=40s \
comment="WG tunnel to Office A"
/routing/ospf/interface-template add \
interfaces=bridge-lan \
area=backbone \
type=broadcast \
passive \
cost=1 \
comment="LAN network - passive"
# Включить OSPF на всех WireGuard-интерфейсах, начинающихся с "wg-"
/routing/ospf/interface-template add \
interfaces=wg-* \
area=backbone \
type=ptp \
cost=10
# Создаём правило фильтрации
/routing/filter/rule add chain=ospf-out \
rule="if (dst == 192.168.99.0/24) { reject }"
# Применяем фильтр к OSPF instance
/routing/ospf/instance set ospf-main out-filter-chain=ospf-out
/routing/filter/rule add chain=ospf-in \
rule="if (dst == 10.0.0.0/8) { reject }"
/routing/ospf/instance set ospf-main in-filter-chain=ospf-in
/routing/filter/rule add chain=ospf-redist \
rule="if (dst == 192.168.10.0/24) { accept } else { reject }"
/routing/ospf/instance set ospf-main \
redistribute=connected \
out-filter-chain=ospf-redist
# MD5-аутентификация на интерфейсе
/routing/ospf/interface-template set \
[find comment="WG tunnel to Office B"] \
auth=md5 \
auth-id=1 \
auth-key="OspfSecretKey2024"
/routing/ospf/neighbor print
Columns: ROUTER-ID, ADDRESS, INSTANCE, AREA, STATE-CHANGES, STATE
# ROUTER-ID ADDRESS INSTANCE AREA STATE-CHANGES STATE
0 2.2.2.2 10.255.255.2 ospf-main backbone 6 Full
1 3.3.3.3 10.255.255.6 ospf-main backbone 6 Full
/ip/route print where routing-table=main ospf
Columns: DST-ADDRESS, GATEWAY, DISTANCE
# DST-ADDRESS GATEWAY DISTANCE
0 192.168.20.0/24 10.255.255.2 110
1 192.168.30.0/24 10.255.255.6 110
/routing/ospf/lsa print
/routing/ospf/interface print detail
/tool traceroute 192.168.30.1 src-address=192.168.10.1
# Отключаем туннель
/interface/wireguard disable wg-to-office-c
# Через 40 секунд (dead-interval) проверяем соседей
/routing/ospf/neighbor print
# Проверяем, изменились ли маршруты
/ip/route print where dst-address=192.168.30.0/24
# Включаем обратно
/interface/wireguard enable wg-to-office-c
# Проверьте параметры на обеих сторонах
/routing/ospf/interface-template print detail
# Убедитесь, что hello-interval и dead-interval одинаковы
# Убедитесь, что area-id совпадает
# Проверьте аутентификацию — ключ должен быть идентичным
/ip firewall filter add chain=input protocol=ospf action=accept \
comment="Allow OSPF" place-before=0
# Проверьте MTU на интерфейсах туннеля
/interface print detail where name~"wg-"
# Установите одинаковый MTU на обоих концах
/interface/wireguard set wg-to-office-b mtu=1420
# В RouterOS 7 можно игнорировать MTU mismatch через interface-template
# Убедитесь, что type=ptp для VPN-линков — это избавляет от многих проблем
# Проверьте forward-цепочку
/ip firewall filter print where chain=forward
# Добавьте правила для OSPF-подсетей
/ip firewall filter add chain=forward \
src-address=192.168.0.0/16 dst-address=192.168.0.0/16 \
action=accept comment="Allow inter-office traffic" place-before=0
# Исключите inter-office трафик из NAT
/ip firewall nat add chain=srcnat \
src-address=192.168.0.0/16 dst-address=192.168.0.0/16 \
action=accept place-before=0
/routing/ospf/interface-template set \
[find comment="WG tunnel to Office B"] \
hello-interval=30s \
dead-interval=120s
# Всегда задавайте Router ID явно
/routing/ospf/instance set ospf-main router-id=1.1.1.1
# Вариант 1: фильтр
/routing/filter/rule add chain=ospf-redist \
rule="if (dst == 192.168.10.0/24) { accept } else { reject }"
/routing/ospf/instance set ospf-main \
redistribute=connected \
out-filter-chain=ospf-redist
# Вариант 2: убрать redistribute и использовать passive interface
/routing/ospf/instance set ospf-main redistribute=""
/routing/ospf/interface-template add \
interfaces=bridge-lan \
area=backbone \
passive \
cost=1
/system logging add topics=ospf,!debug action=memory
# Количество соседей
/routing/ospf/neighbor print count-only
# Количество маршрутов от OSPF
/ip/route print count-only where ospf
# Статистика по instance
/routing/ospf/instance print detail