BGP overlay для магазинов через L2TP/WireGuard
1. Цель
Заменить большой набор статических маршрутов на центральном офисном CCR динамической маршрутизацией BGP.
Текущая модель сети:
- центральный офис — основной routing hub;
- магазины подключаются к офису звездой через L2TP и/или WireGuard;
- каждый магазин имеет минимум две локальные сети:
LANиCAM; - офис должен иметь устойчивую достижимость до обеих сетей, особенно
CAM; - в перспективе часть магазинов имеет второй туннель в облачный CHR, связанный с офисом через IPsec;
- GPON/ISP должны оставаться только underlay и не участвовать в корпоративной BGP-маршрутизации.
Основной смысл BGP здесь — не «интернетный best-path», а:
- автоматическая публикация сетей магазинов;
- автоматический withdraw при падении площадки/туннеля;
- централизованная routing policy;
- возможность позже добавить резервный путь через облако без ручных static route;
- сокращение статической routing table на Office CCR.
2. Архитектура
Underlay
Shop01 ── GPON01 ──┐
Shop02 ── GPON02 ──┼── ISP ── Office
ShopNN ── GPONNN ──┘
Underlay отвечает только за IP-доставку VPN-трафика.
GPON:
- NAT/masquerade;
- маршрут в ISP;
- никакого BGP до Office;
dst-nat tcp/179для BGP не нужен, если BGP идёт поверх VPN.
Overlay
Office
AS65000
10.100.1.1
/ \
eBGP eBGP
/ \
Shop01 Shop02
AS65101 AS65102
10.100.1.3 10.100.1.2
│ │
LAN + CAM networks LAN + CAM networks
BGP peering выполняется по адресам VPN overlay, а не через внешние/GPON-адреса.
3. Почему eBGP, а не iBGP
Рекомендуемая модель:
- Office:
AS65000; - каждый Shop: собственный private ASN. Пример:
Office AS65000
Shop01 AS65101
Shop02 AS65102
...
Shop50 AS65150
Преимущества eBGP в текущей hub-and-spoke архитектуре:
- не требуется Route Reflector;
- нет iBGP split-horizon ограничения;
- AS_PATH естественно отражает происхождение маршрута;
- Office естественно становится next-hop при передаче маршрутов между магазинами;
- проще troubleshooting;
- легко добавить второй peer через Cloud;
- отдельный ASN хорошо идентифицирует конкретную площадку.
50–100 eBGP peers для центрального CCR — нормальный масштаб при адекватном железе и простой policy.
4. Текущий лабораторный стенд
Office
ASN: 65000
BGP ID: 10.100.1.1
L2TP local: 10.100.1.1
Shop01
ASN: 65101
Router ID: 10.255.1.1
L2TP address: 10.100.1.3
LAN: 172.20.252.0/24
CAM: 172.20.253.0/24
Shop02
ASN: 65102
Router ID: 10.255.1.2
L2TP address: 10.100.1.2
LAN: 172.20.250.0/24
CAM: 172.20.251.0/24
Сессии:
Office 10.100.1.1 <-> Shop01 10.100.1.3
Office 10.100.1.1 <-> Shop02 10.100.1.2
Обе eBGP session успешно работают в состоянии ESTABLISHED.
5. PPP/L2TP addressing
Office может иметь один и тот же local-address на нескольких динамических PPP/L2TP bindings:
10.100.1.1 <-> 10.100.1.2
10.100.1.1 <-> 10.100.1.3
10.100.1.1 <-> 10.100.1.4
...
Это point-to-point интерфейсы, поэтому повторение local endpoint нормально.
Для BGP желательно закреплять remote-address магазина статически в /ppp/secret.
Пример:
/ppp/secret
set [find name="Shop01"] \
local-address=10.100.1.1 \
remote-address=10.100.1.3
set [find name="Shop02"] \
local-address=10.100.1.1 \
remote-address=10.100.1.2
Не рекомендуется использовать динамический pool для BGP peer IP, если BGP connection привязан к конкретному адресу.
6. BGP instance
RouterOS v7.20+.
Office
/routing/bgp/instance
add name=office \
as=65000 \
router-id=10.100.1.1
Shop01
/routing/bgp/instance
add name=shop \
as=65101 \
router-id=10.255.1.1
Shop02
/routing/bgp/instance
add name=shop \
as=65102 \
router-id=10.255.1.2
Router ID должен быть уникальным и стабильным. В production желательно выделить отдельную схему Router ID / loopback адресов.
7. BGP connections
Office -> Shop01
/routing/bgp/connection
add name=Shop01 \
instance=office \
local.role=ebgp \
local.address=10.100.1.1 \
remote.address=10.100.1.3 \
remote.as=65101
Office -> Shop02
/routing/bgp/connection
add name=Shop02 \
instance=office \
local.role=ebgp \
local.address=10.100.1.1 \
remote.address=10.100.1.2 \
remote.as=65102
Shop01 -> Office
/routing/bgp/connection
add name=Office \
instance=shop \
local.role=ebgp \
local.address=10.100.1.3 \
remote.address=10.100.1.1 \
remote.as=65000
Shop02 -> Office
/routing/bgp/connection
add name=Office \
instance=shop \
local.role=ebgp \
local.address=10.100.1.2 \
remote.address=10.100.1.1 \
remote.as=65000
Для directly-connected L2TP peer multihop не нужен.
8. Проверка BGP session
/routing/bgp/session/print
Нормальное состояние:
Flags: E - ESTABLISHED
Подробно:
/routing/bgp/session/print detail
Проверять:
remote.address;remote.as;remote.id;local.address;local.as;uptime;prefix-count;- negotiated capabilities;
- hold/keepalive timers.
9. Firewall для BGP
BGP работает по TCP/179.
Если input firewall ограничивает доступ к самому роутеру, разрешить BGP только из VPN overlay.
Office
/ip/firewall/filter
add chain=input \
action=accept \
protocol=tcp \
src-address=10.100.1.0/24 \
dst-port=179 \
comment="BGP from shops"
Shop
/ip/firewall/filter
add chain=input \
action=accept \
protocol=tcp \
src-address=10.100.1.1 \
dst-port=179 \
comment="BGP from Office"
Правило должно находиться до общего drop input.
Не публиковать TCP/179 наружу через GPON/Internet.
10. Анонс локальных сетей Shop
Не рекомендуется:
redistribute connected
или массовый redistribute static.
Лучше явно указывать origin prefixes.
Shop01
/ip/firewall/address-list
add list=BGP-ORIGIN address=172.20.252.0/24 comment="Shop01 LAN"
add list=BGP-ORIGIN address=172.20.253.0/24 comment="Shop01 CAM"
Shop02
/ip/firewall/address-list
add list=BGP-ORIGIN address=172.20.250.0/24 comment="Shop02 LAN"
add list=BGP-ORIGIN address=172.20.251.0/24 comment="Shop02 CAM"
Connection:
/routing/bgp/connection
set [find where remote.address=10.100.1.1] \
output.network=BGP-ORIGIN
11. Важный нюанс output.network
Наличие prefix в BGP-ORIGIN само по себе недостаточно.
Для advertisement соответствующий маршрут должен существовать и быть пригоден в локальной RIB.
На стенде был кейс:
Uc 172.20.252.0/24
Uc 172.20.253.0/24
Причина — ether2/ether3 были link-down, так как к LAN/CAM не было подключено устройств.
BGP уже создал:
n 172.20.252.0/24
n 172.20.253.0/24
но не отправлял их, потому что исходные connected routes были UNREACHABLE.
После подключения VPC интерфейсы стали active, connected routes стали usable, и BGP advertisement заработал.
Диагностика:
/routing/route/print detail where dst-address=172.20.252.0/24
Нормально:
Ac ...
Плохо:
Uc ...
contribution=unreachable
12. Output policy на Shop
Желательно иметь whitelist и на стороне магазина.
Пример Shop01:
/routing/filter/rule
add chain=SHOP01-OUT \
rule="if (dst==172.20.252.0/24) { accept }"
add chain=SHOP01-OUT \
rule="if (dst==172.20.253.0/24) { accept }"
Connection:
/routing/bgp/connection
set [find where remote.address=10.100.1.1] \
output.filter-chain=SHOP01-OUT
Причина двойной защиты:
output.network
+
output.filter
Даже если позже кто-то ошибочно добавит сеть в address-list или включит redistribute, filter ограничивает фактический advertisement.
13. Office input policy
В лаборатории использован общий фильтр:
/routing/filter/rule
add chain=SHOP-IN \
rule="if (dst in 172.20.0.0/16 && dst-len==24) { accept }"
Это означает:
172.20.250.0/24 ACCEPT
172.20.251.0/24 ACCEPT
172.20.252.0/24 ACCEPT
172.20.0.0/16 REJECT
172.20.250.0/25 REJECT
10.0.0.0/8 REJECT
0.0.0.0/0 REJECT
Важно:
dst==172.20.0.0/16
означает только exact match /16.
Для subprefix используется:
dst in 172.20.0.0/16
14. Недостаток общего SHOP-IN
Текущий LAB filter:
if (dst in 172.20.0.0/16 && dst-len==24) { accept }
не проверяет ownership prefix.
Например Shop01 сможет ошибочно объявить 172.20.250.0/24, который принадлежит Shop02, и Office примет его.
Для production желательно решить ownership одним из следующих способов.
Вариант A — отдельный filter на peer
Максимально строгий вариант.
Shop01 -> только LAN01 + CAM01
Shop02 -> только LAN02 + CAM02
Плюсы:
- сильная защита;
- очень понятная диагностика.
Минусы:
- много правил;
- ручная поддержка плохо масштабируется.
Вариант B — генерируемая конфигурация
Предпочтительный production-вариант при 50+ площадках.
Хранить inventory:
shop01:
asn: 65101
tunnel_ip: 10.100.1.3
lan: 172.20.252.0/24
cam: 172.20.253.0/24
Из inventory автоматически генерировать:
- PPP secret;
- BGP connection;
- input filter;
- output filter;
- monitoring labels.
Это убирает ручную «статику с дополнительными шагами».
Вариант C — строгий адресный план
Если новый addressing позволяет вывести ownership алгоритмически:
Shop37:
LAN 172.20.37.0/24
CAM 172.21.37.0/24
ASN 65137
тогда часть policy можно стандартизировать.
15. Проверка маршрутов на Office
/routing/route/print where protocol=bgp
Подробно:
/routing/route/print detail where protocol=bgp
Ожидаемый смысл:
Ab 172.20.252.0/24
gateway=10.100.1.3
distance=20
bgp.as-path=65101
Ab 172.20.253.0/24
gateway=10.100.1.3
distance=20
bgp.as-path=65101
Ab 172.20.250.0/24
gateway=10.100.1.2
distance=20
bgp.as-path=65102
Ab 172.20.251.0/24
gateway=10.100.1.2
distance=20
bgp.as-path=65102
A — active.
b — BGP.
16. Что происходит при падении Shop
Нормально:
Shop01 BGP ESTABLISHED
↓
Office имеет LAN01 + CAM01
L2TP/WG падает:
BGP TCP session DOWN
↓
маршруты Shop01 withdraw
↓
Office удаляет их из active RIB/FIB
После восстановления:
VPN UP
↓
BGP ESTABLISHED
↓
UPDATE
↓
LAN/CAM снова появляются
Это основной operational выигрыш относительно static route.
17. Advertisement Office -> Shops
Следующий этап лаборатории:
Office должен передавать Shop01 маршруты Shop02 и наоборот.
Пример:
Shop01 originates:
172.20.252.0/24
AS_PATH: локально пустой
Office receives:
172.20.252.0/24
AS_PATH: 65101
Shop02 receives from Office:
172.20.252.0/24
AS_PATH: 65000 65101
NEXT_HOP: Office
eBGP естественно формирует подходящий next-hop для hub-and-spoke:
Shop02 -> Office -> Shop01
18. Нужно ли всем магазинам знать все магазины
Отдельное архитектурное решение.
Full branch visibility
Shop01 знает Shop02...Shop50
Плюсы:
- branch-to-branch доступ;
- новый магазин автоматически появляется у остальных.
Минусы:
- больше blast radius;
- ошибка одного Shop может затронуть остальные;
- больше routes и policy.
Hub-only visibility
Office знает все Shops
Shop знает только Office/Cloud services
Плюсы:
- проще;
- безопаснее;
- меньше таблицы маршрутов на филиалах.
Рекомендация: если реальные сервисы не требуют прямого branch-to-branch traffic, не рекламировать все branch prefixes всем магазинам без необходимости.
BGP visibility и firewall access должны рассматриваться отдельно:
есть маршрут != разрешён доступ
19. Cloud topology — следующий этап
В production уже существует/планируется дополнительный Shop -> Cloud tunnel.
Возможная целевая схема:
Office
AS65000
/ \
VPN IPsec
/ \
Shop37 --------- Cloud
AS65137 AS65010
\ /
\ VPN /
Shop может рекламировать LAN/CAM одновременно Office и Cloud.
При падении прямого Shop -> Office туннеля возможен альтернативный путь:
Office -> Cloud -> Shop
20. Будущий failover
Пример policy:
Direct Shop path:
LOCAL_PREF 200
Via Cloud:
LOCAL_PREF 100
Нормально:
Office -> Shop
Direct tunnel падает:
direct BGP path withdrawn
↓
Office -> Cloud -> Shop
Direct tunnel возвращается:
LOCAL_PREF 200 > 100
↓
traffic возвращается на direct path
Cloud failover лучше вводить после стабилизации базовой схемы Office c Shop
21. Communities — перспективное улучшение
Позже можно маркировать route по назначению.
Пример:
65000:100 = LAN
65000:200 = CAM
65000:300 = Cloud
65000:400 = Office service
Преимущества:
- policy строится по классу маршрута;
- не нужно в каждом фильтре перечислять сотни prefix;
- удобнее observability и troubleshooting.
Не внедрять communities до того, как базовый BGP и prefix ownership работают предсказуемо.
22. Security recommendations
BGP
- TCP/179 разрешать только внутри VPN overlay;
- фиксировать
remote.as; - фиксировать peer IP;
- input/output filters обязательны;
- не использовать слепой
redistribute connected; - не принимать
0.0.0.0/0от Shop без отдельной осознанной policy; - ограничивать допустимые prefix-length;
- по возможности ограничивать количество prefixes на peer;
- логировать session flap.
VPN
Текущий LAB использует L2TP без IPsec.
Для production:
- WireGuard — предпочтительный вариант, если архитектурно допустим;
- либо L2TP/IPsec, если L2TP необходимо сохранить;
- не считать plain L2TP криптографически защищённым транспортом.
23. MTU
Текущий L2TP MTU:
1450
При дальнейших вложенных туннелях:
Shop -> L2TP/WG -> Cloud/Office -> IPsec
обязательно проверить:
- effective MTU;
- fragmentation;
- PMTUD;
- TCP MSS;
- камеры/RTSP потоки.
BGP session может работать даже при проблемном MTU, а крупный payload/data-plane — ломаться отдельно.
24. Monitoring
Минимум мониторить:
BGP
session state
uptime
prefix-count
last-started
last-stopped
remote AS
remote ID
VPN
interface running
uptime
packet loss
RTT
reconnect count
Routes
ожидаемые LAN/CAM prefix присутствуют
route active
gateway соответствует нужному Shop
нет неожиданных prefix
Критичный alert:
BGP ESTABLISHED, но prefix-count != expected
Для каждого Shop ожидается, например, 2 prefixes, если он публикует только LAN + CAM.
25. Troubleshooting flow
Session не Established
Ping tunnel peer
↓
TCP/179
↓
BGP OPEN
↓
remote AS / local AS
↓
firewall
Команды:
/ping <peer>
/tool/sniffer/quick ip-protocol=tcp port=179
/routing/bgp/session/print detail
/log/print where topics~"bgp"
Session Established, prefix-count=0
Проверять по порядку:
1. origin route существует?
2. route ACTIVE / reachable?
3. output.network содержит prefix?
4. output filter принимает prefix?
5. UPDATE действительно отправляется?
6. Office input filter принимает prefix?
Команды:
/routing/route/print detail where dst-address=<prefix>
/ip/firewall/address-list/print where list="BGP-ORIGIN"
/routing/bgp/connection/print detail
/routing/filter/rule/print detail
Route received, но не active
Смотреть:
filtered?
unreachable?
конкурирующий static?
другой BGP path?
distance?
BGP attributes?
/routing/route/print detail where dst-address=<prefix>
26. Что НЕ делать
Не рекомендуется:
redistribute connected
без строгого output filter.
Не рекомендуется принимать 0.0.0.0/0-32 от branch без явной policy.
Не рекомендуется открывать TCP/179 в Internet/GPON.
Не рекомендуется давать Shop динамический L2TP IP из общего pool, если BGP peer ожидает фиксированный endpoint.
Не рекомендуется вручную писать сотни однотипных per-shop правил без inventory/automation.
27. Рекомендованный rollout
Phase 1 — LAB
- L2TP Shop01 -> Office;
- L2TP Shop02 -> Office;
- eBGP Shop01 -> Office;
- eBGP Shop02 -> Office;
- уникальные Router ID;
- advertise LAN/CAM;
- Office получает active BGP routes;
- Office re-advertise branch routes;
- проверить branch-to-branch;
- проверить withdraw при падении L2TP;
- проверить неправильный prefix и filter reject;
- проверить duplicate prefix;
- проверить восстановление session.
Phase 2 — Production pilot
Выбрать 1–2 некритичных магазина.
Не удалять static routes сразу.
Сначала:
BGP routes подняты
+
static routes оставлены
Проверить routing selection и traffic.
После стабильного burn-in убрать соответствующие static routes.
Phase 3
- rollout по группам;
- inventory/config generation;
- monitoring;
- route ownership validation.
Phase 4
- Cloud CHR;
- secondary BGP peers;
- LOCAL_PREF policy;
- automatic failover;
- communities.
28. Ключевая operational модель
До BGP:
Администратор знает топологию
↓
ручные static routes
↓
CCR содержит сотни вручную поддерживаемых записей
После BGP:
Каждый Shop объявляет собственные LAN/CAM
↓
Office динамически учит topology
↓
route существует пока существует reachable Shop/BGP path
BGP становится control-plane корпоративной overlay сети.
VPN определяет:
как физически добраться до peer
BGP определяет:
какие сети находятся за peer и какой путь использовать
29. Рекомендуемое направление
Для текущей сети:
VPN transport:
L2TP / WireGuard
Routing control-plane:
eBGP
Office:
AS65000
Shop:
отдельный private ASN
Shop advertisement:
только LAN + CAM
Office policy:
строгая validation входящих prefixes
Будущее:
Cloud AS + secondary path + LOCAL_PREF failover
Это позволяет постепенно заменить текущую статическую routing table без большого одномоментного redesign всей сети.