Split tunneling — це те місце, куди VPN-дизайни тихо йдуть помирати. Здається, усе «підключено», тунель піднятий, і все ж Teams лагає, входи в SaaS зациклюються, або фінансовий додаток наполягає, що ви в іншій країні. Тим часом маршрутизатор робить саме те, що ви випадково йому наказали.
Якщо ви експлуатуєте MikroTik у виробництві, вам потрібен нудний набір правил: детерміністична маршрутизація, мінімальний NAT і фаєрвол, який можна аудіювати о 2:00 без необхідності створювати нову релігію.
Принципи: як розділені тунелі виходять з ладу в реальному житті
Split tunneling — це не «деякий трафік іде через VPN, решта йде напряму». Це маркетингова версія. Реальна версія: ви будуєте два накладені домени маршрутизації на тому самому клієнті й потім сподіваєтеся, що DNS, MTU, NAT і стан фаєрволу всі погодяться, що означає «всередині».
На MikroTik ваш успіх залежить від того, чи зможете ви швидко відповісти на такі питання з доказами:
- Які пакети мають потрапляти в тунель?
- Де ви це вирішуєте (routing table, mangle, IPsec policy, WireGuard AllowedIPs)?
- Чи повертаються пакети тим же шляхом назад (симетрія), і чи згодний з цим conntrack?
- Чи робите ви NAT тільки там, де це необхідно, і ніде більше?
- Чи можете ви довести вищеописане за допомогою diff конфігів і лічильників?
Що означає «чисто» в RouterOS
Чисто — це не «мало правил». Чисто — це передбачувано і аудитовано. Я хочу набір правил, де:
- Кожне правило має коментар, і коментар пояснює намір (не «vpn rule 3»).
- Мітки і таблиці мають послідовні назви:
rt-vpn,rm-vpn,addr-vpn-dsts. - Всі рішення про split-tunnel відбуваються в одному очевидному місці.
- NAT явний і обмежений. Якщо потрібно приховати адреси, робіть це для визначеного набору потоків.
- Default deny залишається default deny.
Два шляхи, як split tunneling стає «ненавмисно повним тунелем»
Route creep — це основна проблема: хтось додає широке правило (наприклад 0.0.0.0/0) у невірну таблицю або розширює AllowedIPs занадто широко, і тепер усе огинає через HQ. Користувачі скаржаться на затримки; менеджмент каже «VPN повільний»; ви кажете «це баг політики маршрутизації з проблемою PR».
DNS creep — інша: ви розділили маршрутизацію, але не розділили іменорозвʼязування правильно. Клієнт резолвить внутрішні імена через публічний DNS (помилка), або резолвить публічні імена через внутрішній DNS (працює, але витікає внутрішня політика в інтернет). Обидва призводять до «на моєму ноуті працює», бо на ноуті ще є кешовані відповіді з минулого тижня.
Надійна істина: легше тримати split tunneling правильним, коли тунель вузький. Маршрутуйте тільки приватні префікси, які вам справді потрібні. Якщо постачальник каже «просто надсилайте 0/0», це не технічна вимога; це стратегія підтримки.
Жарт #1: Split tunneling — як дозволити коту вибирати, які двері відкриті. Він обере ті, про які ви пошкодуєте.
Цікаві факти і контекст (щоб ви не повторювали історію)
- Політична маршрутизація передує брендуванню «SD-WAN» десятиліттями. Ранні корпоративні маршрутизатори використовували route maps і множинні таблиці задовго до того, як це стало підписним продуктом.
- VPN split tunneling у 2000-х був широко не рекомендований, бо скомпрометовані клієнти могли з’єднати корпоративні мережі з інтернетом; сучасні засоби контролю кінцевих точок зробили це менш табу.
- IPsec політично-орієнтована модель сформувала звички багатьох адміністраторів: «traffic selectors вирішують, що шифрується». WireGuard перевернув ментальну модель тим, що AllowedIPs виступає одночасно як маршрут і ACL.
- NAT і IPsec історично не ладили між собою; NAT-T (UDP-інкапсуляція) став поширеним для виживання через NAT в інтернеті.
- Connection tracking став тихим регулятором поведінки фаєрволу у міру того, як stateful фільтрація замінила stateless ACL у обладнанні малого й середнього бізнесу. Коли conntrack «бреш», бреше все.
- DNS split-horizon старший за більшість хмарних платформ. Це не новий трюк; ми просто постійно забуваємо його проектувати.
- Проблеми з MTU такі ж давні, як тунелювання: інкапсуляція краде байти з корисного навантаження, і «пінг працює» нічого не доводить про реальний трафік.
- MikroTik популяризував «функції рівня операторів за аматорські ціни», що означає, що ваша «невелика» інфраструктура все ще може мати складність рівня провайдера — без провайдерського контролю змін.
Висновок: ваш дизайн split tunnel має передбачати, що люди змінять його пізніше під тиском. Оптимізуйте для виживання, а не для хитромудрості.
Чиста довідкова архітектура (ментальна модель RouterOS)
Ми заякоримося на простому, але реалістичному сценарії для виробництва:
- MikroTik маршрутизатор у філії або домашньому офісі.
- LAN:
192.168.88.0/24наbridge. - WAN:
ether1з доступом в інтернет. - VPN: інтерфейс WireGuard
wg0до хаба (HQ або хмара). - Віддалені захищені мережі:
10.10.0.0/16і10.20.30.0/24. - Мета split tunnel: тільки ці віддалені мережі йдуть через VPN; усе інше виходить локально.
Точки прийняття рішень: де трафік скеровують
У RouterOS у вас кілька «важелів». Не тягайте за всі одразу, якщо не любите постмортеми.
- Вибір таблиці маршрутизації (RouterOS v7 policy routing з
routing rulesі множинними таблицями). - Мітки mangle (
routing-mark), що живлять альтернативний пошук маршруту. - WireGuard AllowedIPs (контролює, що peer прийме і які маршрути ви можете встановити).
- IPsec політики (селектори визначають, що шифрується).
- NAT правила (можуть «виправити» помилки; не покладайтеся на це).
Мій пріоритет для аудитного split tunneling на MikroTik RouterOS v7:
- Використовуйте виділену таблицю маршрутизації (наприклад
rt-vpn). - Використовуйте одне правило mangle (або routing rule) щоб вибирати цю таблицю для чітко визначеного набору призначень.
- Тримайте WireGuard AllowedIPs узгодженим з цими призначеннями, але не використовуйте його як єдиний механізм політики.
- Мінімізуйте NAT; надавайте перевагу маршрутизації приватних префіксів наскрізь, коли це можливо.
Що слід логувати та рахувати
Аудит — це не галочка відповідності; це фіча для швидкості. Ви хочете лічильники і логи, що відповідають на:
- Чи співпадаєте ми зі списком «VPN призначень»?
- Чи відкидаємо ми несподіваний вхід із тунелю?
- Чи спрацьовує NAT там, де не треба?
- Чи використовується default route для інтернет-трафіку як задумано?
Це означає: списки адрес, коментарі до правил і тимчасове логування для перевірки, яке ви видаляєте після валідації. Постійне «логуй усе» — шлях до самостійного DoS.
Чистий, аудитний набір правил (WireGuard + політична маршрутизація)
Це довідковий шаблон. Налаштуйте імена інтерфейсів і підмережі під себе. Суть — структура: розділяйте обов’язки, маркуйте наміри і тримайте рішення про split в одному місці.
1) Визначте списки адрес: ваш контракт split tunnel
Почніть зі списку адрес, який перераховує, що має йти через VPN. Це стає вашим контрактом з бізнесом: «ці мережі — всередині». Усе інше — зовні.
Використовуйте невелику кількість списків:
addr-vpn-dsts: префікси призначень, що мають маршрутизуватися через VPN.addr-lan: локальні LAN префікси (опціонально, але корисно).addr-mgmt: джерела керування, яким дозволено доступ до сервісів маршрутизатора.
2) Створіть виділену таблицю маршрутизації і маршрути
RouterOS v7 представив перші класи таблиць маршрутизації. Використовуйте їх. Це робить конфіг читабельною і зменшує «магічні мітки».
В rt-vpn додайте маршрути для захищених мереж з gateway, вказаним на інтерфейс WireGuard (або endpoint peer, якщо робите щось складніше). Не додавайте default route, якщо ви не плануєте повний тунель.
3) Політична маршрутизація: скеровуйте тільки те, що треба
Це можна зробити через mangle mark-routing або через /routing rule. Обидва підходи легітимні. Мені подобається /routing rule за його читабельність, коли це можливо, але mangle все ще універсальний, коли потрібно зіставляти більше атрибутів.
Ключовий дизайн-вибір: матчити по списку адрес призначень. Це ускладнює випадкове розширення сфери через дивний портовий матч пізніше.
4) NAT: тільки якщо потрібно, і тільки для відповідних потоків
Якщо віддалена сторона може маршрутувати назад до вашого LAN, не робіть NAT. Маршрутизація чистіша, її легше відлагоджувати і вона зберігає логи на віддаленій стороні змістовними.
Якщо доводиться NAT через неможливість додати маршрути на віддалій стороні або через накладені підмережі, то NAT тільки для LAN→VPN-dsts. Не робіть masquerade для всього трафіку з wg0, якщо не хочете, щоб віддалена сторона бачила всіх користувачів як «маршрутизатор».
5) Фаєрвол: явний allow-list для тунелю
Для input chain ставте маршрутизатор як сервер: дозволяйте лише ті сервіси, які потрібні, з джерел, яким довіряєте. Для forward chain: allow established/related, drop invalid, потім allow LAN→VPN призначення, LAN→інтернет, і дозволяйте VPN→LAN тільки якщо потрібно (часто не потрібно).
Розділяйте правила для «трафіку тунелю» і «інтернет-трафіку». При відладці ви будете вдячні собі з минулого.
6) DNS: split tunnel — наполовину маршрутизація, наполовину імена
Вирішіть, де резолвитимуться внутрішні імена. Варіанти:
- Клієнти використовують внутрішні DNS-сервери, доступні через VPN для певних зон (найкраще).
- Маршрутизатор виконує умовну переспрямування (працює, але додає рухому частину).
- Клієнти використовують публічний DNS і ви приймаєте, що внутрішні імена не резолвитимуться (зазвичай неприйнятно).
Що б ви не обрали, документуйте це як частину контракту split tunnel. Інакше ваш «мережевий інцидент» насправді буде «невідповідність очікувань DNS».
Конкретний скелет конфігурації (концептуально, без копіпаст)
Я не буду вставляти тисячу рядків експорту, бо виробничі середовища — не демо для copy-paste. Ціль — патерн:
- Список адрес визначає захищені призначення.
- Таблиця маршрутизації містить тільки ці маршрути.
- Routing rule або mangle mark обирає цю таблицю тільки для цих призначень.
- NAT обмежений для LAN→захищених призначень, якщо потрібно.
- Фаєрвол явний щодо дозволених потоків і логує лише несподіване.
Жарт #2: NAT — як скотч: неймовірний, коли потрібен, тривожний, коли стає архітектурою.
Нотатки щодо IPsec/IKEv2 для розділених тунелів
WireGuard достатньо простий, щоб більшість багів split tunnel були самоствореними. IPsec додає більше рухомих частин: lifetimes фаз 1/2, селектори, пропозиції, NAT-T і класичне «він піднятий, але нічого не проходить».
Policy-based vs route-based IPsec на MikroTik
В policy-based IPsec селектори політик (src/dst підмережі) вирішують, що шифрується. Якщо ваш split tunnel вимагає лише кілька призначень, це може бути чистим — доки хтось не додасть широку політику «тимчасово» і не забуде її видалити.
Route-based IPsec (через VTI) як правило краще узгоджується з дизайном «виділена таблиця маршрутизації», бо ви можете маршрутувати префікси в інтерфейс VTI як будь-який інший інтерфейс, а потім застосувати політичну маршрутизацію подібно.
Хитрість для аудиту з IPsec
Зробіть селектори такими, що відповідають вашому контракту списку адрес. Якщо ваш список адрес каже 10.10.0.0/16 і 10.20.30.0/24, ваші IPsec політики повинні це відображати. Якщо ні — ви не робите split tunneling; ви робите «те, що останній інженер торкнувся».
Практичні завдання: 12+ команд, виводів і рішень
Ці завдання передбачають, що у вас є CLI доступ до MikroTik (через SSH) і Linux-хост в LAN для тестового трафіку. Команди реалістичні; виводи репрезентативні. Суть: виконати команду, інтерпретувати її, прийняти рішення.
Завдання 1: Перевірте, що інтерфейс WireGuard піднятий і має очікувану адресу
cr0x@server:~$ ssh admin@192.168.88.1 /interface/wireguard/print
Flags: X - disabled, R - running
0 R name="wg0" mtu=1420 listen-port=13231 private-key="<hidden>" public-key="<hidden>"
Що це означає: R означає, що інтерфейс запущений. MTU важливий; 1420 — типове безпечне значення для WireGuard через типові WAN.
Рішення: Якщо він не запущений — виправте це перед тим, як шукати проблеми з маршрутизацією. Якщо MTU 1500 і користувачі скаржаться «деякі сайти працюють, великі завантаження падають», позначте MTU як підозрілий.
Завдання 2: Перевірте рукопотискання peer і лічильники байтів
cr0x@server:~$ ssh admin@192.168.88.1 /interface/wireguard/peers/print detail
0 interface=wg0 public-key="<hubkey>" endpoint-address=203.0.113.10 endpoint-port=51820
allowed-address=10.10.0.0/16,10.20.30.0/24 persistent-keepalive=25s
last-handshake=1m12s rx=128.4MiB tx=64.2MiB
Що це означає: Недавнє рукопотискання і збільшувані rx/tx вказують, що тунель живий.
Рішення: Якщо рукопотискання відсутнє або древнє — виправте доступність підмережі (WAN, NAT, фаєрвол з обох сторін) перед тим, як чіпати правила split.
Завдання 3: Перерахуйте списки адрес і підтвердіть контракт split tunnel
cr0x@server:~$ ssh admin@192.168.88.1 /ip/firewall/address-list/print where list="addr-vpn-dsts"
Flags: X - disabled, D - dynamic
0 list=addr-vpn-dsts address=10.10.0.0/16 comment="HQ private networks"
1 list=addr-vpn-dsts address=10.20.30.0/24 comment="Finance app subnet"
Що це означає: Маршрутизатор має явний набір призначень для VPN-шляху.
Рішення: Якщо цей список відсутній, застарів або містить 0.0.0.0/0 — зупиніться. У вас немає split tunneling; у вас «враження».
Завдання 4: Підтвердіть, що існує виділена таблиця маршрутизації
cr0x@server:~$ ssh admin@192.168.88.1 /routing/table/print
Flags: D - dynamic, X - disabled
0 name="main" fib
1 name="rt-vpn" fib
Що це означає: rt-vpn — реальна FIB-таблиця.
Рішення: Якщо ви її не бачите — створіть. Якщо ви бачите п’ять схожих таблиць, у вас проблеми з управлінням, а не технікою.
Завдання 5: Перевірте маршрути всередині VPN-таблиці
cr0x@server:~$ ssh admin@192.168.88.1 /ip/route/print where routing-table="rt-vpn"
Flags: D - dynamic, X - disabled, A - active, c - connect, s - static
0 A s dst-address=10.10.0.0/16 gateway=wg0 distance=1 scope=30 target-scope=10 comment="via WG to HQ"
1 A s dst-address=10.20.30.0/24 gateway=wg0 distance=1 scope=30 target-scope=10 comment="via WG to finance"
Що це означає: Таблиця VPN містить тільки очікувані приватні мережі, і вони активні.
Рішення: Якщо в rt-vpn є default route — ви в одному маршруті від повного тунелю. Видаліть його, якщо ви цього не планували.
Завдання 6: Підтвердіть, що існує рішення політичної маршрутизації (routing rule)
cr0x@server:~$ ssh admin@192.168.88.1 /routing/rule/print detail
0 action=lookup-only-in-table dst-address=10.10.0.0/16 table=rt-vpn comment="Split tunnel: HQ"
1 action=lookup-only-in-table dst-address=10.20.30.0/24 table=rt-vpn comment="Split tunnel: Finance"
Що це означає: Тільки ці префікси звертаються до rt-vpn. lookup-only-in-table запобігає fallback у main, що робить відмови голосними (добре), а не дивними (погано).
Рішення: Якщо правила використовують lookup замість lookup-only-in-table, ви можете випадково пропустити трафік у WAN коли VPN впаде. Обирайте свідомо.
Завдання 7: Перегляньте NAT правила і забезпечте їх обмеженість
cr0x@server:~$ ssh admin@192.168.88.1 /ip/firewall/nat/print
Flags: X - disabled, I - invalid, D - dynamic
0 chain=srcnat action=masquerade out-interface=ether1 comment="WAN internet NAT"
1 chain=srcnat action=masquerade out-interface=wg0 src-address=192.168.88.0/24 dst-address-list=addr-vpn-dsts comment="NAT only LAN to VPN dsts"
Що це означає: Є нормальна WAN-маcкерада, і VPN-маcкерада, яка спрацьовує тільки для LAN → захищених призначень.
Рішення: Якщо ви бачите загальну out-interface=wg0 masquerade без dst-обмеження — ви, ймовірно, ховаєте баги дизайну і ламаєте трейли аудиту на віддаленій стороні.
Завдання 8: Перевірте лічильники forward chain для VPN потоків
cr0x@server:~$ ssh admin@192.168.88.1 /ip/firewall/filter/print stats where chain="forward"
Flags: X - disabled, I - invalid, D - dynamic
0 chain=forward action=accept connection-state=established,related comment="Allow established/related" packets=784221 bytes=812.5MiB
1 chain=forward action=drop connection-state=invalid comment="Drop invalid" packets=23 bytes=1904
2 chain=forward action=accept in-interface=bridge dst-address-list=addr-vpn-dsts out-interface=wg0 comment="LAN to VPN destinations" packets=18214 bytes=21.6MiB
3 chain=forward action=accept in-interface=bridge out-interface=ether1 comment="LAN to internet" packets=512001 bytes=601.2MiB
4 chain=forward action=drop comment="Drop the rest" packets=411 bytes=32244
Що це означає: Правило split для VPN збігається і пропускає трафік. Невеликий лічильник «Drop the rest» — це здорово.
Рішення: Якщо лічильник правила VPN лишається нульовим, а користувачі скаржаться, ваше рішення маршрутизації не обирає очікуваний шлях (або DNS вказує кудись інакше).
Завдання 9: Використайте Torch, щоб побачити, чи трафік до захищеної підмережі йде на wg0
cr0x@server:~$ ssh admin@192.168.88.1 /tool/torch interface=wg0 src-address=192.168.88.50 dst-address=10.10.20.15
# SRC-ADDRESS DST-ADDRESS PROTOCOL PORT TX RX
0 192.168.88.50 10.10.20.15 tcp 443 1.2Mbps 3.8Mbps
Що це означає: У вас живий трафік, що відповідає очікуванням split tunnel.
Рішення: Якщо трафік зʼявляється на ether1 замість wg0, ваші правила маршрутизації/мітки помилкові або призначення не входить у ваш список адрес.
Завдання 10: Виконайте перевірку маршруту для призначення (RouterOS «куди воно піде?»)
cr0x@server:~$ ssh admin@192.168.88.1 /ip/route/check dst-address=10.10.20.15
0 interface=wg0 gateway=wg0 distance=1 routing-table=rt-vpn
Що це означає: Маршрутизатор відправить це призначення через wg0 використовуючи rt-vpn.
Рішення: Якщо воно повідомляє routing-table=main або інтерфейс ether1, політика split не застосована для цього призначення.
Завдання 11: Підтвердьте, що conntrack не «закріпив» потоки на невірному шляху
cr0x@server:~$ ssh admin@192.168.88.1 /ip/firewall/connection/print where dst-address~"10.10."
Flags: S - seen-reply, A - assured, C - confirmed
0 SAC protocol=tcp src-address=192.168.88.50:50122 dst-address=10.10.20.15:443 timeout=23h59m
reply-src-address=10.10.20.15:443 reply-dst-address=192.168.88.50:50122
Що це означає: Існує активне зʼєднання. Conntrack stateful; після встановлення потоку зміна політики маршрутизації може не перемістити його.
Рішення: Якщо ви змінили політику маршрутизації, а поведінка не змінилася — очистіть конкретні зʼєднання в conntrack або зачекайте тайм-аутів. Не перезавантажуйте як перший інструмент.
Завдання 12: Перевірте MTU з реальним розміром payload (з Linux-хоста)
cr0x@server:~$ ping -M do -s 1372 10.10.20.15 -c 3
PING 10.10.20.15 (10.10.20.15) 1372(1400) bytes of data.
1380 bytes from 10.10.20.15: icmp_seq=1 ttl=61 time=42.1 ms
1380 bytes from 10.10.20.15: icmp_seq=2 ttl=61 time=41.7 ms
1380 bytes from 10.10.20.15: icmp_seq=3 ttl=61 time=41.9 ms
--- 10.10.20.15 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
Що це означає: Path MTU підтримує щонайменше це payload без фрагментації. Для тунелів тестуйте з DF, бо фрагментація може приховати реальні проблеми.
Рішення: Якщо це падає, але малі пінги працюють — зменшіть MTU WireGuard (наприклад 1420 або нижче) і/або досліджуйте WAN path MTU та фільтрацію ICMP.
Завдання 13: Перевірте завантаження CPU під час VPN-навантаження (на маршрутизаторі)
cr0x@server:~$ ssh admin@192.168.88.1 /system/resource/print
uptime: 12d3h2m
version: 7.13.5 (stable)
free-memory: 412.3MiB
total-memory: 512.0MiB
cpu: ARM
cpu-count: 4
cpu-frequency: 1400MHz
cpu-load: 86%
Що це означає: CPU на 86% вказує, що ви можете бути на межі, особливо якщо піки доходять до 100% і черги наростають.
Рішення: Якщо CPU високий під час скарг — виміряйте пропускну здатність і розгляньте обмеження апаратного offload, взаємодію з FastTrack або оновлення обладнання.
Завдання 14: Перевірте, чи FastTrack не обходить mangle/маршрутизаційні рішення
cr0x@server:~$ ssh admin@192.168.88.1 /ip/firewall/filter/print where action~"fasttrack"
Flags: X - disabled, I - invalid, D - dynamic
5 chain=forward action=fasttrack-connection connection-state=established,related comment="FastTrack (may bypass policy routing)"
Що це означає: FastTrack може обійти частини обробки фаєрволу/mangle. Залежно від вашого дизайну, це може спричинити невідповідності split tunnel.
Рішення: Якщо ви покладаєтеся на мітки mangle для маршрутизації, зазвичай потрібно вимкнути FastTrack або зробити винятки так, щоб трафік, помічений для VPN, не fasttrack-ився.
План швидкої діагностики
Коли відмова очевидна, вам не дадуть додаткових балів за глибоку діагностику. Ось порядок, що швидко знаходить вузьке місце.
Спочатку: доведіть, чи тунель живий
- Перевірте час останнього рукопотискання WireGuard peer і лічильники байтів.
- Якщо рукопотискання відсутнє: проблема в підмережі, NAT або фаєрволі. Зупиніться на цьому.
- Якщо рукопотискання в нормі: переходьте до маршрутизації/політики.
Далі: доведіть вибір маршрутизації для одного проблемного призначення
- Виберіть одну внутрішню IP, відому як «всередині».
- Запустіть route check / lookup і підтвердіть, що воно обирає
wg0іrt-vpn. - Якщо воно обирає WAN: ваш контракт split tunnel (address list/routing rules) неправильний.
Третє: доведіть, що фаєрвол дозволяє (і NAT не робить хитрощі)
- Подивіться лічильники forward chain для правила LAN→VPN.
- Перевірте лічильники NAT для VPN-maскеради (якщо є).
- Використайте Torch на
wg0, щоб підтвердити, що трафік справді виходить.
Четверте: якщо маршрутизація/фаєрвол в порядку — тестуйте MTU і DNS
- MTU: DF ping з реалістичним розміром payload; знизьте MTU якщо потрібно.
- DNS: підтвердіть, що клієнт резолвить внутрішню назву в внутрішню IP, а не на публічну адресу.
П’яте: тільки тоді ганяйтеся за продуктивністю (CPU, черги, втрата)
- Перевірте завантаження CPU маршрутизатора під час інциденту.
- Шукайте втрати пакетів на WAN або симптоми bufferbloat.
- Підтвердіть, що ви не пропустили себе FastTrack у обході політики маршрутизації.
Оперативна нотатка: якщо тунель піднятий, але «деякі додатки» не працюють, MTU і DNS переможуть «містичні правила фаєрволу» дев’ять разів з десяти.
Поширені помилки: симптом → корінна причина → виправлення
1) Симптом: VPN піднятий, але внутрішні підмережі недоступні
Корінна причина: Маршрути існують у main таблиці, але політична маршрутизація відправляє трафік у таблицю без тих маршрутів (або навпаки).
Виправлення: Покладіть захищені підмережі в rt-vpn і переконайтеся, що routing rules обирають rt-vpn для цих призначень. Перевірте за допомогою /ip/route/check.
2) Симптом: Усе йде через VPN (ненавмисний повний тунель)
Корінна причина: Default route (0.0.0.0/0) присутній у VPN таблиці, або WireGuard AllowedIPs включає 0.0.0.0/0 і ви встановили широкий маршрут.
Виправлення: Видаліть default route з rt-vpn. Звузьте AllowedIPs до захищених префіксів. Регулярно аудіюйте таблиці маршрутів.
3) Симптом: Деякі зʼєднання працюють, інші зависають (особливо великі передавання)
Корінна причина: MTU/PMTUD проблеми; ICMP блокується; не враховано оверхед інкапсуляції.
Виправлення: Зменшіть MTU тунелю (наприклад до 1420 або нижче) і тестуйте DF пінгами. Не гадьте — вимірюйте.
4) Симптом: Внутрішні імена не резолвяться, але пінг внутрішніх IP працює
Корінна причина: DNS не розділений; клієнти все ще використовують публічний DNS для внутрішніх зон.
Виправлення: Забезпечте внутрішній DNS, доступний через VPN, або реалізуйте умовну переспрямування. Документуйте зони і очікувані резолвери.
5) Симптом: Після зміни поведінка не відповідає новим правилам годинами
Корінна причина: Connection tracking закріплює встановлені потоки; зміни застосовуються лише до нових зʼєднань.
Виправлення: Очистіть таргетовані записи conntrack для уражених потоків або зачекайте. Уникайте «перезавантаження для застосування маршрутизації».
6) Симптом: Трафік VPN витікає в інтернет, коли тунель впав
Корінна причина: Політична маршрутизація використовує lookup з fallback на main; коли VPN-маршрут відсутній, він відкочує на WAN.
Виправлення: Використовуйте lookup-only-in-table для захищених префіксів, і опційно додайте явні drop правила для LAN→захищених призначень коли VPN відсутній, щоб «fail closed».
7) Симптом: Політична маршрутизація працює, поки не ввімкнули FastTrack
Корінна причина: FastTrack обходить частини обробки фаєрволу/mangle.
Виправлення: Вимкніть FastTrack або виключіть з нього VPN-повʼязані зʼєднання (проектуйте обережно і перевіряйте лічильники).
8) Симптом: Віддалена сторона бачить усіх клієнтів як WG IP MikroTik
Корінна причина: Надто широка маскарадування на wg0.
Виправлення: Приберіть загальний NAT; якщо NAT потрібен, обмежте його до LAN джерел і списку захищених призначень.
Три корпоративні міні-історії з реальних задач
Інцидент через неправильне припущення: «AllowedIPs — це політика маршрутизації»
Одна середня компанія впровадила WireGuard для внутрішнього інструмента аналітики. У них був хаб у датацентрі і десятки малих сайтів на MikroTik. Мета — split tunnel: тільки 10.60.0.0/16 має йти в датацентр; все інше — напряму.
Інженер на філіях припустив, що WireGuard allowed-address «змусить» ці маршрути і утримає все інше поза тунелем. На деяких роутерах залишився статичний маршрут до старого IPsec-шлюзу датацентру в main — тихенько. Це було неочевидно, бо тунель все ще піднімався і маршрутизатор мав кілька шляхів до тих самих префіксів.
Потім постачальник у підтримці «порадив» додати 0.0.0.0/0 в AllowedIPs «для надійності». Вночі трафік переглядів з кількох філій почав огинати в датацентр, насичуючи канал, розрахований тільки для внутрішніх додатків, а не для стрімінгу чи оновлень ОС.
Корінна причина не в WireGuard; вона в управлінні та припущенні: AllowedIPs не є повною системою політик. Це — частина пазлу, і він не замінює явні таблиці маршрутів, інтенти фаєрволу і перевірки аудиту.
Виправлення було приземленим: прибрати 0/0, визначити адресний список контракту, створити rt-vpn і додати routing rules тільки для захищених префіксів. Також додали пункт у чекліст перед змінами: «grep на default routes у не-main таблицях». Ніхто не святкував, але графіки перестали кричати.
Оптимізація, що відкотилася: FastTrack за «безкоштовну продуктивність»
Інша організація мала розумний split tunnel, але почала стикатися з межами CPU на малих ARM-роутерах. Хтось помітив, що FastTrack зменшить CPU, обходячи частину фаєрволу для established зʼєднань. Вони ввімкнули FastTrack глобально у forward chain і одразу побачили покращення швидкостей інтернет-тестів.
Через два тижні почалися тікети: CRM через VPN працював кілька хвилин, потім сесії скидалися або випадково підключалися з неправильної IP. Користувачі описували це як «VPN нестабільний». Ця етикетка заразна; коли вона зʼявляється, будь-яка проблема стає «винна VPN».
SRE на чергуванні порівняв лічильники і помітив дивину: правило «LAN to VPN destinations» майже не інкрементувалося, хоча Torch показував епізодичні сплески CRM-трафіку в WAN. FastTrack фактично скоротив шлях обробки, який застосовував рішення маршрутизації для деяких встановлених потоків.
Вони виправили це, відключивши FastTrack для трафіку, що міг підпадати під політичну маршрутизацію. Не глобально, не героїчно — тільки стільки, скільки потрібно для забезпечення коректності. CPU виріс, але роутери перестали брехати. Пізніше проблему продуктивності вирішили правильно: кращий вибір апаратного забезпечення і налаштування черг замість покладання на магію обходу фаєрволу.
Сухо, але правильно: перевірка змін по лічильниках врятувала день
У фінансовій компанії (де люблять вікна змін і люди з пристрастью до таблиць) команда стандартизувала конфіги MikroTik. Кожне правило split tunnel мало коментар, і кожне важливе правило перевірялося лічильниками під час валідації. Також вони тримали просту «до/після» знімок: таблиці маршрутів, routing rules, NAT правила і статистику фільтрів.
Одної п’ятниці в HQ додали нову підмережу для білінгового сервісу: 10.77.40.0/24. Інженер додав маршрут на стороні хаба і оновив WireGuard AllowedIPs. Він забув оновити адресний список контракту і routing rules на філіях.
Понеділковий симптом був чистим і вузьким: тільки білінговий додаток не працював; усе інше — ок. Оскільки команда мала практику перевірки лічильників, діагноз зайняв хвилини: лічильники «LAN to VPN destinations» не інкрементувалися при зверненнях до IP білінгового додатку. Це відразу вказало на «призначення не в контракті», а не «тунель упав».
Виправлення — один рядок: додати запис у address-list і маршрут у rt-vpn. Ні простою, ні аварійної перезавантаження, ні звинувачень. Їхня «нудна» практика — ставити лічильники як перший клас сигналів — перетворила інцидент на рутинну зміну. Ось як виглядає зрілість: менше адреналінових подій, більше контрольованих виправлень.
Чеклісти / покроковий план
План побудови (greenfield або очищення)
- Визначте контракт split tunnel: перелік віддалених префіксів, які мають бути доступні через VPN, і тільки їх.
- Створіть адресний список
addr-vpn-dstsз цими префіксами і коментарями про власника/контекст. - Створіть виділену таблицю маршрутизації
rt-vpn. - Додайте маршрути в rt-vpn для кожного захищеного префіксу через
wg0(або VTI для IPsec). - Додайте routing rules для кожного захищеного префіксу: action
lookup-only-in-table→rt-vpn. - Фаєрвол forward chain: accept established/related; drop invalid; явний allow LAN→VPN-dsts; allow LAN→WAN; default drop.
- NAT: додавайте LAN→VPN-dsts masquerade тільки якщо віддалена сторона не може коректно маршрутувати назад.
- DNS рішення: забезпечте внутрішні зони через внутрішній DNS доступний по VPN; задокументуйте.
- Вимкніть або обмежте FastTrack якщо він заважає політичній маршрутизації.
- Валідація: протестуйте по одному IP на кожен захищений префікс; перевірте лічильники; підтвердіть відсутність небажаних default маршрутів.
План змін (додавання нового захищеного підмережі)
- Додайте префікс до
addr-vpn-dstsз коментарем імені власника сервісу. - Додайте маршрут у
rt-vpnдля того префіксу. - Додайте routing rule для того префіксу, що вказує на
rt-vpn. - Підтвердіть, що WireGuard AllowedIPs містить цей префікс (і не ширший ніж потрібно).
- Протестуйте доступність, потім стежте за лічильниками forward/NAT для очікуваних інкрементів.
- Якщо є DNS (нова внутрішня назва), перевірте поведінку резолвера з клієнта.
План відкату (бо ви доросла людина)
- Спочатку вимкніть нові routing rule(и) (швидко повертає скерування трафіку).
- Видаліть/відключіть нові маршрути в
rt-vpn. - Видаліть запис у address list.
- Очистьте таргетовані conntrack записи, якщо клієнти застрягли на старих шляхах.
- Зробіть знімок стану: таблиці маршрутів, статистику правил і інформацію по peer handshake для постмортему.
Одна перефразована ідея варта збереження: «Усе ламається увесь час; будуйте системи, що цього очікують.» — Вернер Вогельс (перефразована ідея)
FAQ
1) Чи реалізовувати split tunneling через mangle marks чи routing rules?
Якщо routing rules в RouterOS v7 покривають ваші умови матчингу — використовуйте їх: вони читабельніші і простіші для аудиту. Використовуйте mangle, коли потрібно матчити складніші атрибути (порти, DSCP, підмережі користувачів), але тримайте це мінімально.
2) Де має зберігатися «істина» про призначення split tunnel?
В одному місці: адресний список контракту (або строго керований список префіксів). Потім routing rules і AllowedIPs повинні узгоджуватися з ним. Якщо дублювати логіку в пʼяти місцях — рано чи пізно вона розійдеться.
3) Чи потрібен NAT через VPN?
Ні, якщо ви можете маршрутувати end-to-end. NAT потрібен, коли не можете: накладені підмережі, віддалена сторона не може додати маршрути або обмеження постачальника. Якщо NAT необхідний — обмежте його до LAN→захищених призначень.
4) Чому працює по IP, але не по імені?
Тому що DNS не є частиною маршрутизації. Ваш тунель може бути ідеальним, але резолвинг імен все одно може бути неправильним. Вирішіть внутрішні зони через внутрішній DNS доступний по VPN або умовне переспрямування.
5) Чому увімкнення FastTrack зламало split tunneling?
FastTrack може обходити частини обробки фаєрволу/mangle. Якщо ваше рішення маршрутизації залежить від тих кроків, FastTrack може змусити потоки пропускати політичний шлях. Або вимкніть його, або виключіть трафік, повʼязаний з VPN.
6) Як запобігти «витоку в WAN», коли VPN впав?
Використовуйте lookup-only-in-table для захищених призначень, щоб не було fallback. Опційно додайте drop у forward-chain для LAN→захищених призначень, коли в VPN таблиці немає активного маршруту, щоб відмовлятися закрито.
7) Як налагоджувати «деякі користувачі вражені, не всі»?
Перевірте, чи у вражених користувачів інша source підмережа/VLAN, чи вони звертаються до інших DNS резолверів, або чи мають кеш DNS. Потім перевірте conntrack: існуючі сесії не будуть слідувати новим рішенням маршрутизації.
8) Чи коли-небудь варто включати 0.0.0.0/0 у AllowedIPs на філіях?
Лише якщо ви свідомо робите повний тунель і спроєктували це (можливості, моніторинг, політика безпеки). Якщо ваша мета — split tunnel, 0/0 — це зброя з придатком для самостійного відстрілу з контрактом на підтримку.
9) Який найчистіший спосіб аудиту змін з плином часу?
Використовуйте послідовні коментарі правил, тримайте контракт split tunnel в address lists і періодично переглядайте: таблиці маршрутів, routing rules, NAT правила і лічильники фільтрів. Аудити мають бути достатньо швидкими, щоб ви їх реально робили.
Висновок: практичні наступні кроки
Якщо ваша настройка MikroTik split tunnel здається крихкою, зазвичай політика розпорошена: частково в AllowedIPs, частково в mangle, частково в «тимчасовому» NAT і частково в чиїйсь памʼяті. Поверніть це до контракту і таблиці.
Зробіть наступне, в порядку:
- Створіть (або очистіть)
addr-vpn-dsts, щоб він містив лише те, що має йти через VPN. - Переконайтеся, що
rt-vpnмістить тільки маршрути для тих префіксів — без default route, якщо ви цього не плануєте. - Використовуйте routing rules (
lookup-only-in-table) щоб скеровувати тільки ті призначення вrt-vpn. - Аудитуйте NAT на
wg0; приберіть загальну masquerade, якщо не можете це виправдати собі у майбутньому. - Запустіть план швидкої діагностики один раз, поки все працює, і зафіксуйте очікувані виводи і лічильники.
Split tunneling може бути чистим. Але воно не буде таким випадково. Зробіть політику явною, тримайте її вузькою і нехай ваші лічильники кажуть вам правду.