Ваші три офіси не можуть «просто VPN-ом з’єднатися». Один знаходиться за подвійним NAT, інший має «дружній» роутер від провайдера, до якого вам не дозволено торкатися, а третій — той, в якому серверна кімната ще й зберігає різдвяні прикраси. Але всі очікують спільні сервіси, стабільний VoIP і мережеве сховище, яке не здається розміщеним на тостері.
Модель hub-and-spoke на базі WireGuard дає передбачувану маршрутизацію, не перетворюючи вашу мережу на інтерпретативне мистецтво. Вона залишається передбачуваною лише якщо поважати, як WireGuard фактично працює: це захищений UDP-тунель із прикріпленою таблицею маршрутизації. Якщо ставитися до нього як до магічного «прапорця VPN», він чемно дозволить вам неправильно надсилати пакети до того дня, коли ви в чергуванні.
Виберіть топологію та чесно оцініть обмеження
Hub-and-spoke означає: кожен офіс (спок) будує тунель WireGuard лише до центрального шлюзу (хабу). Хаб маршрутизує трафік між споками. Споки ніколи не повинні стикатися безпосередньо — у цьому вся суть: менше тунелів, простіше керування ключами, менше дір у фаєрволі, менше сюрпризів.
Це не єдина модель. Існує повна mesh-мережа, але вона масштабується як груповий чат, де всі можуть відповісти всім. Для трьох офісів ви можете зробити mesh, але вам все одно знадобиться центральна точка керування політиками, логуванням і питанням «хто з ким може спілкуватися». Hub-and-spoke перемагає в корпоративній реальності: централізований контроль виходу в інтернет, централізоване спостереження і лише одне місце для застосування політик «ні, принтери не повинні зв’язуватися з фінансами».
Яким має бути хаб
- Стабільна публічна кінцева точка (статична IP або стабільний DNS, але відносіться до збоїв DNS серйозно).
- Роутер із Linux IP-форвардингом, фаєрволом і бажано nftables або iptables під вашим контролем.
- Сервер з операційною гігієною: синхронізація часу, логи, бекапи, контроль змін і чіткий власник.
Якими мають бути споки
- Пристрій, який може запускати WireGuard і маршрутизувати LAN (Linux, підтримуване роутерне дистрибутивне ПЗ або невеликий апарат).
- Послідовність: один інтерфейс для WAN, один для LAN, один для WireGuard. Не ускладнюйте.
- Відомі LAN-підмережі (без перекриттів). Перекриття — це спосіб, як «тимчасові фікси» стають постійними аваріями.
Визначте на початку, чи буде хаб також «виходом в інтернет» для споків (споки маршрутизують 0.0.0.0/0 через хаб), або хаб лише маршрутизує між офісами. Для трьох офісів зазвичай спочатку роблять лише міжофісну маршрутизацію; централізований вихід в інтернет можна додати пізніше, коли будете готові нести супорт.
Жарт №1: VPN hub-and-spoke — як корпоративна організаційна схема: усі звітують у центр, а центр усе життя витрачає на маршрутизацію скарг.
Цікаві факти (і чому вони важливі в експлуатації)
- WireGuard навмисно мінімалістичний. Він не узгоджує купу алгоритмів і не підтримує зоопарк шифрів; використовує невеликий сучасний набір, щоб зменшити кількість помилок у конфігурації та поверхню атак.
- Він використовує фреймворк Noise. Це не дрібниця; пояснює, чому рукостискання швидкі і чому стан легший у порівнянні зі старими VPN-стеками.
- WireGuard працює в ядрі Linux. Ось чому продуктивність загалом відмінна і чому вам слід дбати про оновлення ядра та регресії, як про будь-яку іншу зміну в datapath.
- «AllowedIPs» одночасно ACL і маршрути. Багато збоїв виникає через те, що забувають: це поле визначає, які маршрути встановлюються і який трафік приймається від піра.
- Роумінг — це первинна поведінка. Піри можуть змінювати IP/порт відправника; WireGuard вчиться новій кінцевій точці після автентифікованого трафіку, що ідеально для офісів за NAT — аж поки немає keepalive.
- Це UDP. Отже воно проходить через багато мереж, але це також означає, що stateful-фаєрволи і таймаути NAT — ваші проблеми.
- Немає вбудованої «авторизації користувачів». Це ключі між машинами. Якщо потрібен доступ на рівні користувача — робіть це в іншому шарі (або окремою системою).
- WireGuard молодший за IPsec. IPsec має десятиліття шрамів та сумісні проблеми. WireGuard має менше ручок, менше підводних каменів і менше «але постачальник сказав…» зустрічей.
- Малі конфіги — це перевага. Коли всю конфігурацію VPN можна вмістити на одну сторінку, відладка у чергуванні раптово стає терпимою.
Одна перефразована ідея від Werner Vogels (CTO Amazon) досі працює в експлуатації: все рано чи пізно ламається; проектуйте так, щоб відновлення було рутинним і нудним
. Це менталітет для VPN теж: припускайте, що NATи перезавантажуються, лінки флапають, а хтось редагує не той файл о 2:00 ночі.
План адресації та модель маршрутизації
Почніть з плану адресації. Якщо його пропустити, ви заплатите пізніше з відсотками.
Приклад мережевого плану (три офіси + хаб)
- Office A LAN:
10.10.10.0/24 - Office B LAN:
10.10.20.0/24 - Office C LAN:
10.10.30.0/24 - WireGuard transit network:
10.99.0.0/24(лише для IP-адрес інтерфейсів тунелю) - Hub wg0:
10.99.0.1/24 - Spoke A wg0:
10.99.0.11/32 - Spoke B wg0:
10.99.0.12/32 - Spoke C wg0:
10.99.0.13/32
Використовуйте /32-адреси для пірів на інтерфейсі тунелю і тримайте транзитну мережу окремо від офісних LAN. Хочете, щоб «дріт» був окремим всесвітом. І не використовуйте RFC1918 діапазони, які вже застосовані в офісах. Перекриття приватних підмереж — корпоративний еквівалент «ми все вирішимо на ходу».
Намір маршрутизації
Ваш намір у hub-and-spoke простий:
- Споки знають: «щоб дістатися до LAN інших офісів, відправляй трафік у wg0.»
- Хаб знає: «щоб дістатися до LAN кожного офісу, відправляй трафік через wg0 до відповідного піра.»
- Клієнти в LAN кожного офісу знають: «для підмереж інших офісів шлюз за замовчуванням — офісний роутер.»
Ось і все. Немає NAT між офісами, якщо тільки у вас немає перекриттів підмереж, які ви не можете виправити (і якщо не можете — заплануйте час, щоб це виправити). NAT приховує проблеми і ускладнює їх діагностику, бо стирає ідентичність джерела — саме те, що треба зберегти для аудиту й політик безпеки.
Конфігурація хаба: центральний шлюз
Припустимо, хаб — це Linux VM у датацентрі або хмарі з публічною IP. Назвемо його wg-hub-1. Він має:
eth0= публічний/WAN інтерфейсwg0= WireGuard інтерфейс
Встановіть WireGuard
На сучасних дистрибутивах це пакунок і модуль ядра, який уже є. Тримайте все буденно.
Згенеруйте ключі
Робіть це на хабі та на кожному споку; ніколи не копіюйте приватні ключі через чат або коментарі в тікетах. Ставтесь до них як до root-паролів.
Хаб: /etc/wireguard/wg0.conf
Цей приклад маршрутизує три офісні підмережі. Хаб буде єдиною налаштованою кінцевою точкою; споки вкажуть на нього.
cr0x@server:~$ sudo sed -n '1,200p' /etc/wireguard/wg0.conf
[Interface]
Address = 10.99.0.1/24
ListenPort = 51820
PrivateKey = HUB_PRIVATE_KEY_REDACTED
SaveConfig = false
# Enable NAT only if you want spokes to reach the hub's WAN or internet via hub.
# For pure site-to-site, you typically do not NAT between offices.
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = nft add table inet wg; nft 'add chain inet wg forward { type filter hook forward priority 0; policy drop; }'
PostUp = nft add rule inet wg forward iif "wg0" oif "wg0" accept
PostUp = nft add rule inet wg forward iif "wg0" oif "eth0" accept
PostUp = nft add rule inet wg forward iif "eth0" oif "wg0" ct state established,related accept
PostDown = nft delete table inet wg
[Peer]
PublicKey = SPOKE_A_PUBLIC_KEY_REDACTED
AllowedIPs = 10.99.0.11/32, 10.10.10.0/24
PersistentKeepalive = 25
[Peer]
PublicKey = SPOKE_B_PUBLIC_KEY_REDACTED
AllowedIPs = 10.99.0.12/32, 10.10.20.0/24
PersistentKeepalive = 25
[Peer]
PublicKey = SPOKE_C_PUBLIC_KEY_REDACTED
AllowedIPs = 10.99.0.13/32, 10.10.30.0/24
PersistentKeepalive = 25
Примітки, які не варто пропускати:
AllowedIPsна хабі фактично є таблицею маршрутизації хаба для споків. Якщо вона неправильна, хаб або загубить трафік, або доставить неправильно.PersistentKeepaliveна хабі не завжди обов’язковий, але допомагає зберегти NAT-міпінги на віддаленій стороні. У реальності філій таймаути NAT завершуються, коли ви відволікаєтесь.SaveConfig=falseзапобігає запису змін у runtime назад у файл. Це уникає ситуацій «хтось використав wg set і тепер файл бреше».- Правила nftables наведенні вище навмисно суворіші. Багато налаштувань «приймають весь forward», і це нормально, поки VPN не стане неконтрольованим транзитом для всього.
Увімкніть і запустіть
Використовуйте systemd-юнити для послідовності. Потрібне автоматичне відновлення при завантаженні без кастомних скриптів.
Конфігурація споків: кожен офісний роутер
Кожен офіс має роутер/фаєрвол (Linux) з:
eth0= WAN-лінк до роутера/модема ISPeth1= LAN до офісного комутатораwg0= WireGuard тунель до хаба
Spoke A: /etc/wireguard/wg0.conf
cr0x@server:~$ sudo sed -n '1,200p' /etc/wireguard/wg0.conf
[Interface]
Address = 10.99.0.11/32
PrivateKey = SPOKE_A_PRIVATE_KEY_REDACTED
ListenPort = 51820
SaveConfig = false
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = nft add table inet wg; nft 'add chain inet wg forward { type filter hook forward priority 0; policy drop; }'
PostUp = nft add rule inet wg forward iif "eth1" oif "wg0" accept
PostUp = nft add rule inet wg forward iif "wg0" oif "eth1" ct state established,related accept
PostUp = nft add rule inet wg forward iif "wg0" oif "wg0" accept
PostDown = nft delete table inet wg
[Peer]
PublicKey = HUB_PUBLIC_KEY_REDACTED
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.99.0.1/32, 10.10.20.0/24, 10.10.30.0/24
PersistentKeepalive = 25
Spoke B і C ідентичні, крім Address і офісних LAN у AllowedIPs, які мають включати «інші офіси», а не власний LAN. Ви можете також включити адресу wg хаба, щоб пінгувати хаб.
Два правила для споків:
- Не ставте
0.0.0.0/0вAllowedIPs, якщо ви навмисно не примушуєте весь трафік іти через хаб (централізований вихід). Не «тестуйте» це в продакшні і не забувайте. - Не робіть NAT для міжофісного трафіку. Якщо вам потрібен NAT, щоб щось «працювало», швидше за все, ви неправильно маршрутизуєте.
Маршрутизація, NAT і правила фаєрвола без сюрпризів
WireGuard не робить маршрутизацію за вас; він лише шифрує трафік, який ви маршрутизуєте в нього. Linux маршрутизує на основі:
- адрес інтерфейсів (connected routes),
- маршрутів, які додає wg-quick з
AllowedIPs, та/або - ваших явних статичних маршрутів.
Віддавайте перевагу явній маршрутизації над хитрістью
Коли ви піднімаєте wg0 через wg-quick, він зазвичай додає маршрути для AllowedIPs. Це зручно, але ви маєте точно розуміти, які маршрути існують і чому. Зручність перетворюється на таємницю під час аварії.
Форвардинг: три ворота
Щоб пакети пройшли з LAN офісу A до LAN офісу B через хаб, має бути істинним три речі:
- Клієнти офісу A відправляють трафік на свій локальний роутер (шлюз за замовчуванням).
- Роутер спока A форвардить у wg0 і шифрує до хаба.
- Хаб форвардить з wg0 до wg0 (до іншого піра) на основі маршрутизації.
Кожен пристрій потребує:
- увімкнений IP-форвардинг (
net.ipv4.ip_forward=1) - правила фаєрвола, які дозволяють шлях форвардингу
- маршрути для віддалених LAN
Коли потрібен NAT
Є лише кілька причин для NAT у цій архітектурі:
- Централізований вихід в інтернет. Споки маршрутизують
0.0.0.0/0через хаб, хаб робить NAT на публічний інтерфейс. - Перекриття підмереж, які ви не можете перенумерувати. Ви все одно маєте планувати перенумерацію, але іноді бувають злиття, апаратні рішення або системи автоматизації будівлі, які не хочуть рухатися.
- Тимчасова міграція. Використовуйте NAT як допоміжну опору з датою закінчення, а не як архітектурне рішення.
Якщо ви NATите між офісами за замовчуванням, рано чи пізно зламаєте щось, що покладається на IP джерела (ACL, логування, правила SMB, правила VoIP SBC). Гірше: ви втратите здатність відповісти «хто отримав доступ до цієї системи?» без розслідування трансляцій пакетів.
MTU, фрагментація та чому «в мене працює» — не метрика
Проблеми з MTU — найпоширеніша причина «встановлено з’єднання, але щось висне» у site-to-site WireGuard. Тунель додає накладні байти. Якщо ви передаєте пакети, що занадто великі для якогось сегмента шляху, вони фрагментуються або відкидаються, і ви отримаєте помилки, що виглядають як баги в додатках.
WireGuard інкапсулює IP в UDP. Типовий наклад — близько 60 байт (варіюється). Якщо WAN MTU = 1500, безпечний MTU для WireGuard часто 1420. Багато дистрибутивів за замовчуванням ставлять 1420 на wg-інтерфейси з цієї причини.
Але не можна припускати 1500 на WAN. PPPoE часто має 1492. Деякі LTE/5G траси поводяться по-іншому. Деякі провайдери роблять дивні речі з ICMP, що ламає PMTU discovery і робить усе «майже працездатним».
Жарт №2: Помилки MTU — доросла версія натрапляння на LEGO: усе болить, і ви не відразу можете довести причину.
Моя продукційна позиція щодо MTU
- Встановлюйте
MTU = 1420на wg0, якщо немає вимірюваних підстав робити інакше. - Якщо бачите зависання під час великих передавань або деяких сайтів/сервісів, агресивно тестуйте PMTU і налаштовуйте.
- Не вимикайте ICMP глобально. Ви не «підвищуєте захист», ви зав’язуєте очі.
Спостереження: що логувати, що графати
VPN, що «працює», але не піддається відлагодженню, — це майбутня аварія, за яку ви вже заплатили. Для hub-and-spoke інструментуйте хаб як продакшн-маршрутизуючу інфраструктуру — бо так воно і є.
Що стежити на хабі
- Позначки часу рукостискань по кожному пірі. Пір, який не робив handshake годинами — або просто бездіяльний (нормально), або помер (не нормально). Корелюйте з лічильниками трафіку.
- Лічильники RX/TX байтів. Раптове падіння до нуля в робочі години означає, що хтось поламав маршрутизацію або фаєрвол.
- CPU softirq і NIC drops. Рідко для трьох офісів, але якщо VM хаба мала або перевантажена, ви це побачите.
- Лічильники фаєрвола. Якщо ви не рахуєте drop-и, ви будете сваритися з собою о 3 ранку.
- Дрег часу системи. Крипто та час-залежні handshake-и не люблять подорожі в часі.
Логи: будьте вибіркові
WireGuard сам по собі тихий. Це добре. Не намагайтесь «логувати кожен пакет». Замість цього:
- логувати події підняття/опускання інтерфейсу,
- логувати відмови фаєрвола з вибіркою або переглядати лічильники правил,
- зберігати історію змін конфігів і оновлень ядра.
Практичні завдання: команди, виводи й рішення
Це реальні завдання, які ви виконаєте в продакшні. Кожне містить команду, приклад виводу, що це означає і яке рішення прийняти. Використовуйте їх на хабі і на споках. Послідовність рятує від аварій.
Завдання 1: Перевірити стан інтерфейсу WireGuard
cr0x@server:~$ sudo wg show
interface: wg0
public key: 3kN9...REDACTED
listening port: 51820
peer: zZp2...REDACTED
endpoint: 198.51.100.24:60433
allowed ips: 10.99.0.11/32, 10.10.10.0/24
latest handshake: 1 minute, 12 seconds ago
transfer: 1.42 GiB received, 1.87 GiB sent
persistent keepalive: every 25 seconds
Значення: Тунель піднятий настільки, щоб робити handshake; endpoint показує, де зараз пір (очікується NATed порт). Лічильники transfer підтверджують реальний трафік.
Рішення: Якщо latest handshake — «never» або застарілий під час скарг користувачів, одразу переходьте до перевірки доступності firewall/NAT і маршрутів.
Завдання 2: Підняти інтерфейс і підтвердити статус systemd
cr0x@server:~$ sudo systemctl status wg-quick@wg0
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; preset: enabled)
Active: active (exited) since Sat 2025-12-27 10:11:02 UTC; 7min ago
Docs: man:wg-quick(8)
man:wg(8)
Process: 1724 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS)
Значення: wg-quick — одноразовий; «active (exited)» — нормально. Він не зазнав помилки під час створення інтерфейсу.
Рішення: Якщо статус failed, читайте journal на предмет синтаксичних помилок або відсутнього модуля ядра перед тим, як робити інші зміни в мережі.
Завдання 3: Переглянути логи wg-quick на помилки
cr0x@server:~$ sudo journalctl -u wg-quick@wg0 -n 50 --no-pager
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] ip link add wg0 type wireguard
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] wg setconf wg0 /dev/fd/63
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] ip -4 address add 10.99.0.1/24 dev wg0
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] ip link set mtu 1420 up dev wg0
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] sysctl -w net.ipv4.ip_forward=1
Значення: Інтерфейс створено, MTU встановлено, форвардинг увімкнено. Якщо ви не бачите встановлення MTU, можливо, ви покладаєтесь на значення за замовчуванням — це нормально, але майте це на увазі.
Рішення: Якщо логи показують «RTNETLINK answers: File exists» або помилки nft, у вас залишився старий стан. Очистьте і перезапустіть чисто.
Завдання 4: Підтвердьте, що форвардинг дійсно увімкнено
cr0x@server:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
Значення: Ядро буде форвардити IPv4-пакети. Без цього ваш VPN стане дорогим іграшковим ping-ом.
Рішення: Якщо значення = 0, увімкніть його постійно в /etc/sysctl.d/ і не сподівайтесь, що воно «запам’ятається».
Завдання 5: Перевірити, що на хабі існують маршрути до офісних підмереж
cr0x@server:~$ ip route show | egrep '10\.10\.(10|20|30)\.0/24|10\.99\.0\.0/24'
10.10.10.0/24 dev wg0 scope link
10.10.20.0/24 dev wg0 scope link
10.10.30.0/24 dev wg0 scope link
10.99.0.0/24 dev wg0 proto kernel scope link src 10.99.0.1
Значення: Хаб вважає, що всі офісні LAN досяжні через wg0. Це потрібно для маршрутизації хабом.
Рішення: Якщо маршрути відсутні, AllowedIPs для пірів на хабі помилкові або wg-quick не встановив маршрути (можуть втручатися політики маршрутизації).
Завдання 6: Перевірити маршрути на споку
cr0x@server:~$ ip route show | egrep '10\.10\.(20|30)\.0/24|wg0'
10.10.20.0/24 dev wg0 scope link
10.10.30.0/24 dev wg0 scope link
10.99.0.1 dev wg0 scope link
Значення: Spoke A надсилатиме трафік для офісів B і C у тунель.
Рішення: Якщо офісні підмережі маршрутизуються інакше (або не маршрутизуються), виправте AllowedIPs або додайте явні маршрути. Не «виправляйте» це NAT-ом.
Завдання 7: Підтвердити, що хаб може дістатися до кожного wg IP спока
cr0x@server:~$ ping -c 3 10.99.0.11
PING 10.99.0.11 (10.99.0.11) 56(84) bytes of data.
64 bytes from 10.99.0.11: icmp_seq=1 ttl=64 time=18.6 ms
64 bytes from 10.99.0.11: icmp_seq=2 ttl=64 time=18.4 ms
64 bytes from 10.99.0.11: icmp_seq=3 ttl=18.9 ms
--- 10.99.0.11 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
Значення: Існує зашифрована зв’язність до роутера спока.
Рішення: Якщо це не вдається, але handshake є, перевірте фаєрвол спока (INPUT/FORWARD) на ICMP або чи спок присвоїв саме ту wg IP, яку ви очікували.
Завдання 8: Трасування маршруту з хаба до хоста в Office B
cr0x@server:~$ traceroute -n 10.10.20.50
traceroute to 10.10.20.50 (10.10.20.50), 30 hops max, 60 byte packets
1 10.99.0.12 20.112 ms 20.098 ms 20.085 ms
2 10.10.20.50 21.004 ms 20.992 ms 20.980 ms
Значення: Хаб маршрутизує до правильного спока (10.99.0.12), а потім до цільового хоста.
Рішення: Якщо перший хоп неправильний, у вас перекриття AllowedIPs на хабі (два піри претендують на ту ж підмережу) або відсутні маршрути.
Завдання 9: Перевірити перекриття AllowedIPs на хабі
cr0x@server:~$ sudo wg show wg0 allowed-ips
zZp2...REDACTED 10.99.0.11/32 10.10.10.0/24
aPq8...REDACTED 10.99.0.12/32 10.10.20.0/24
mK1r...REDACTED 10.99.0.13/32 10.10.30.0/24
Значення: Кожна офісна підмережа унікально приписана одному пірі. Це те, чого ви прагнете.
Рішення: Якщо два піри вказують ту ж підмережу, виправте це негайно; маршрутизація стане недетермінованою і у вас будуть «час від часу працює» тікети.
Завдання 10: Перевірити UDP доступність порту на хабі
cr0x@server:~$ sudo ss -ulnp | grep 51820
UNCONN 0 0 0.0.0.0:51820 0.0.0.0:* users:(("wireguard",pid=1724,fd=3))
Значення: Хаб слухає UDP/51820.
Рішення: Якщо нічого не слухає, ваш інтерфейс не піднято або ви змінили порт і не перезапустили сервіс.
Завдання 11: Переглянути правила nftables і лічильники
cr0x@server:~$ sudo nft list table inet wg
table inet wg {
chain forward {
type filter hook forward priority filter; policy drop;
iifname "wg0" oifname "wg0" counter packets 18392 bytes 24581231 accept
iifname "wg0" oifname "eth0" counter packets 0 bytes 0 accept
iifname "eth0" oifname "wg0" ct state established,related counter packets 2901 bytes 501832 accept
}
}
Значення: Політика форвардингу — drop за замовчуванням; дозволені специфічні шляхи. Лічильники показують реальний міжофісний трафік (wg0→wg0).
Рішення: Якщо лічильники на wg0→wg0 залишаються нульовими під час скарг, хаб не форвардить — або маршрути неправильні, або трафік не доходить до хаба.
Завдання 12: Захопити трафік, щоб довести, чи пакети прибувають
cr0x@server:~$ sudo tcpdump -ni wg0 host 10.10.20.50 -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:22:18.114331 IP 10.10.10.25.53422 > 10.10.20.50.445: Flags [S], seq 13922311, win 64240, options [mss 1360,sackOK,TS val 2911221 ecr 0,nop,wscale 7], length 0
10:22:19.120482 IP 10.10.10.25.53422 > 10.10.20.50.445: Flags [S], seq 13922311, win 64240, options [mss 1360,sackOK,TS val 2912227 ecr 0,nop,wscale 7], length 0
Значення: Трафік прибуває на wg0 хаба з Office A в напрямку хоста Office B. Якщо немає SYN-ACK, або хост не відповідає, або трафік не пересилається далі коректно.
Рішення: Якщо ви бачите пакети на хабі, але вони не доходять до віддаленого офісу, перевірте маршрути хаба до правильного піра, потім форвардинг спока B і фаєрвол LAN B.
Завдання 13: Перевірити поведінку MTU за допомогою пінгів «не фрагментувати»
cr0x@server:~$ ping -M do -s 1372 -c 3 10.10.20.50
PING 10.10.20.50 (10.10.20.50) 1372(1400) bytes of data.
1372 bytes from 10.10.20.50: icmp_seq=1 ttl=63 time=22.1 ms
1372 bytes from 10.10.20.50: icmp_seq=2 ttl=63 time=22.0 ms
1372 bytes from 10.10.20.50: icmp_seq=3 ttl=63 time=21.8 ms
--- 10.10.20.50 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
Значення: Пакет розміром 1400 байт доходить енд-ту-енд без фрагментації. Це добрий знак для TCP MSS.
Рішення: Якщо це дає «Frag needed», зменшіть MTU для wg (наприклад, до 1380) і повторіть тест, або дослідіть обмеження WAN MTU.
Завдання 14: Перевірити, що політика маршрутизації не підмінює трафік
cr0x@server:~$ ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
Значення: Лише стандартні правила. Це добре, якщо ви свідомо не додавали складну маршрутизацію.
Рішення: Якщо бачите додаткові правила, підтвердьте, що вони потрібні. Політична маршрутизація потужна і також надійний спосіб заплутати Майбутнього Вас.
Завдання 15: Підтвердити, що reverse path filtering не відкидає асиметричний трафік
cr0x@server:~$ sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.wg0.rp_filter
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.wg0.rp_filter = 0
Значення: rp_filter вимкнено тут, щоб уникнути відкидання, коли шлях відповіді відрізняється від очікуваного інтерфейсу. На роутерах строгий rp_filter часто ламає VPN-форвардинг.
Рішення: Якщо значення = 1 або 2 і ви бачите односторонній трафік, встановіть 0 для wg0 (або тонко налаштуйте) і документуйте причину.
Плейбук швидкої діагностики
Це порядок дій, який швидко знаходить вузьке місце, не блукаючи в «можливо це DNS» фантазіях. Починайте з центру назовні, бо хаб — ваш вузол контролю і найкраща точка спостереження.
Перше: тунель живий?
- На хабі:
wg show— перевірте вік handshake і лічильники трафіку по пірі. - На хабі:
ss -ulnp | grep 51820— підтвердьте, що слухає. - На споку:
wg show— підтвердьте, що він бачить хаб, handshake оновлюється і AllowedIPs відповідають наміру.
Якщо handshake — «never»: зазвичай проблема доступності endpoint (UDP блокується), неправильні ключі, неправильний порт або спок за NAT без keepalive і мапінг NAT прострочився.
Друге: чи правильна маршрутизація?
- На хабі і споках:
ip route show— підтвердіть, що віддалені офісні підмережі вказують на wg0. - На хабі:
wg show wg0 allowed-ips— підтвердіть відсутність перекриттів. - Запустіть traceroute з хаба до віддаленого LAN-хоста — підтвердіть, що перший хоп — правильний спок.
Якщо маршрути є, але traceroute хопи неправильні: у вас перекриття AllowedIPs або політична маршрутизація.
Третє: чи фаєрвол/форвардинг блокує транзит?
- Перевірте
sysctl net.ipv4.ip_forwardна хабі і споках. - Проінспектуйте правила nftables/iptables і лічильники на кожному вузлі.
- Запустіть
tcpdumpна хабі wg0 і на споку wg0, щоб побачити, де пакети зупиняються.
Якщо пакети доходять до хаба, але не до дальнього спока: невідповідність маршруту/AllowedIPs на хабі або drop фаєрволом хаба. Якщо пакети доходять до дальнього спока, але не в LAN — це форвардинг спока або фаєрвол LAN.
Четверте: якщо «працює для малого трафіку»
- Тестуйте MTU з
ping -M doна кількох розмірах. - Перевірте TCP MSS clamping (якщо використовуєте) і підтвердіть, що він відповідає ефективному MTU.
- Шукайте блокування ICMP на шляху (PMTU його потребує).
П’яте: скарги на продуктивність (повільні файлообміни, ривки в дзвінках)
- Перевірте CPU хаба і NIC drops:
sar,ethtool -S,ss -s. - Подивіться RTT і втрати (звичайні ping-и підходять; також перевірте джиттер).
- Підтвердьте, що випадково не ввімкнено централізований інтернет-вихід для важкого трафіку.
Поширені помилки: симптом → причина → виправлення
1) «Handshake ніколи не відбувається»
Симптоми: wg show показує latest handshake: (none). Лічильники трафіку не зростають.
Причина: UDP/51820 заблоковано на вході до хаба, неправильний endpoint/порт хаба, неправильний публічний ключ або спок за NAT без keepalive і мапінг NAT прострочився.
Виправлення: Перевірте ss -ulnp на хабі, дозвольте UDP у хмарному фаєрволі, підтвердіть публічний IP/порт хаба, перевірте ключі, встановіть PersistentKeepalive=25 на споках (і за бажанням у записах пірів хаба).
2) «Пінгується, але SMB/RDP/VoIP плаває або висне»
Симптоми: Малі пінги проходять; великі передачі зависають; деякі додатки підключаються, а потім зависають.
Причина: MTU/PMTU blackhole; ICMP блокується; MTU тунелю завеликий для шляху WAN.
Виправлення: Встановіть MTU для wg на 1420 (або нижче), тестуйте ping -M do, уникайте блокування ICMP повідомлень про необхідність фрагментації. Якщо потрібно — обмежуйте TCP MSS на межах.
3) «Офіс A досягає офісу B, але не C»
Симптоми: Одна віддалена підмережа працює; інша — ні. Handshake є.
Причина: Відсутній маршрут/AllowedIPs для непрацюючої підмережі на споку або на хабі.
Виправлення: Додайте відсутню підмережу в потрібний AllowedIPs і підтвердіть маршрути. Перевірте wg show allowed-ips на наявність перекриттів.
4) «Працює тільки в одному напрямку»
Симптоми: Хост в Office A може дістатися Office B, але відповіді не повертаються (або навпаки).
Причина: Reverse path filtering, асиметрична маршрутизація через інший VPN, або фаєрвол LAN, який не знає про віддалені підмережі.
Виправлення: Вимкніть rp_filter для wg-інтерфейсів, забезпечте наявність маршрутів повернення і оновіть правила фаєрвола LAN, щоб дозволити віддалені підмережі.
5) «Вчора працювало, тепер ніхто не може підключитися після «дрібних змін»»
Симптоми: Після перезавантаження або оновлення тунелі не піднімаються або маршрути змінені.
Причина: Зміни в runtime випадково записалися назад, конфлікти імен таблиць nftables або форвардинг не збережений у sysctl.
Виправлення: Використовуйте SaveConfig=false, визначайте правила фаєрвола в призначеній, идемпотентній системі (systemd/CM), встановлюйте sysctl у /etc/sysctl.d/.
6) «Випадково перемикає, який офіс отримує трафік для підмережі»
Симптоми: Сесії йдуть не до тієї цілі; перший хоп у traceroute змінюється; періодична доступність.
Причина: Перекриття AllowedIPs на хабі. Два піри претендують на ту ж підмережу — бо приймають «бій за маршрутизацію».
Виправлення: Зробіть AllowedIPs взаємовиключними і контролюйте це при рев’ю. Ставтеся до них як до таблиці маршрутизації: унікальність — обов’язкова.
7) «VPN піднятий, але клієнти в офісі не можуть дістатися віддалених мереж»
Симптоми: Роутер спока може пінгувати віддалені хости; десктопи офісу — ні.
Причина: Клієнти офісу не мають маршруту до віддалених підмереж (неправильний шлюз за замовчуванням), або фаєрвол спока не форвардить LAN→wg0.
Виправлення: Переконайтеся, що клієнти використовують офісний роутер як шлюз (DHCP), або додайте статичні маршрути на ядровому комутаторі, якщо ви використовуєте L3 всередині; виправте правила форвардингу і перевірте лічильники.
Контрольні списки / покроковий план
Покроковий план розгортання (робіть це в такому порядку)
- Інвентар обмежень. Для кожного офісу: тип WAN, наявність NAT, хто контролює роутер та чи можливий вхідний UDP. Припускайте «ні», поки не доведено.
- Фіксуйте план адресації. Виберіть неперекривні офісні підмережі та виділений діапазон транзиту для WireGuard.
- Побудуйте хаб першим. Закрийте базові ОС: оновлення, NTP, базовий фаєрвол, бекапи
/etc/wireguard. - Згенеруйте ключі для кожного піра. Ведіть публічні ключі в контрольованому місці. Не крутіть ключі без координації.
- Налаштуйте hub wg0. Додайте піри з унікальними AllowedIPs (їх wg /32 та офісні підмережі).
- Налаштуйте один спок (пілот). Увімкніть форвардинг, маршрути і правила фаєрвола. Підніміть тунель.
- Протестуйте з хаба до spoka wg IP. Пінг, потім traceroute до пілотного хоста в офісі.
- Протестуйте з клієнта офісу до іншого офісу. Підтвердьте обидва напрямки і перевірте принаймні один «реальний» протокол (SMB або HTTPS), а не лише ping.
- Підтвердіть MTU. Виконайте DF-пінги біля 1400. Якщо не проходить — відрегулюйте MTU зараз, а не після скарг.
- Додайте інші споки. Повторіть ту саму перевірку для кожного офісу.
- Інструментуйте. Щонайменше — cron/systemd таймер, що знімає знімки
wg show, плюс лічильники фаєрвола. - Контроль змін. Обробляйте зміни конфігурації WireGuard як зміни фаєрвола: рев’ю, стаджинг і відкат.
Операційний чекліст (щотижня, нудно, ефективно)
- Перевіряйте свіжість handshake-ів і лічильники трафіку у робочі години.
- Переконайтеся в дисковому просторі хаба (логи й дампи не питають ваших відчуттів).
- Переглядайте оновлення ядра/мережевого ПЗ, застосовані до хаба або споків.
- Переконайтеся, що бекапи включають ключі та конфіги WireGuard, зашифровані й з контролем доступу.
- Випадкова перевірка лічильників nftables на предмет несподіваних drop-ів.
Чекліст безпеки (практичний, а не показний)
- Обмежте доступ до хаба — вхід лише на UDP/51820 і адміністративний доступ (SSH) з відомих IP керування.
- На хабі — default-drop у форвардингу і явно дозволяйте лише те, що потрібно між споками.
- Тримайте ключі по сайтах; не використовуйте однакові ключі між офісами.
- Документуйте, які офісні підмережі можуть доступатися до яких сервісів; застосовуйте це на хабі.
- Сплануйте ротацію ключів (щоквартально/піврічно) і потренуйте її. Репетиція виявляє приховані залежності.
Три корпоративні міні-історії з реального життя
Міні-історія 1: Аварія через хибне припущення
Вони «уніфікували» три філії, купивши однаковий пакет від провайдера скрізь. Та сама модель модему/роутера. Такий же план. Припущення було, що поведінка NAT теж буде «однакова», тому вони пропустили persistent keepalive. Адже WireGuard сучасний і обробляє роумінг. Що може піти не так?
Через два тижні Office C почав скаржитися: «VPN випадково відпадає». Це не було випадковістю. Пристрій ISP мав агресивний UDP-таймаут і очищував мапінг NAT після короткого простою. Коли офіс був тихим (перерви на обід, ранні ранки), мапінг прострочувався. Наступний пакет з Office C виходив, але вхідна відповідь з хаба поверталася на мертву портову мапу.
На хабі endpoint піра виглядав застарілим. Handshake оновлювався лише після того, як хтось в Office C пробував багато разів, даючи NAT-у достатньо вихідного трафіку, щоб відновити мапу. Команда шукала проблеми з DNS, потім — чи CPU хаба, потім сперечалася, чи повинен UDP бути «більш надійним».
Виправлення було соромно простим: PersistentKeepalive = 25 на споку. Висновок більший: не припускайте, що поведінка NAT однакова лише тому, що пластмасова коробка виглядає однаково. Таймаути NAT залежать від прошивки, конфігурації й настрою.
Міні-історія 2: Оптимізація, що обернулась проти
Інженер мереж вирішив, що правила фаєрвола хаба «занадто строгі». Логіка: якщо тунель зашифрований, навіщо не приймати весь forwarded трафік від wg0? Він замінив явні правила на широке accept, і потім — бо йому подобалась симетрія — дозволив форвардинг wg0→eth0 теж. «Майбутнє на увазі», — так він назвав це.
Працювало місяць. Потім пішла SaaS-міграція. Один офіс мав помилковий маршрут на тестовому VLAN, який спрямував велику частину інтернет-трафіку в VPN. Хаб радо форвардив його в інтернет. Вихід хаба став перевантаженим у робочі години.
Симптоми класичні: джиттер VoIP, повільні файлообміни і розпливчасті тікети «мережа повільна». Оскільки хаб став ненавмисним інтернет-транзитом, проблема виглядала як «продуктивність WireGuard», коли насправді ви перетворили хаб на транзитного провайдера.
Відкат був простим: повернути строгі правила форвардингу і явно блокувати wg0→eth0 для всього, крім відомих управлінських підмереж. Оптимізація — «менше правил» — не заощадила вам часу і створила важко помітний режим відмови. Тримайте хаб чесним: маршрутуйте лише те, що намірено.
Міні-історія 3: Нудна практика, що врятувала день
Інша компанія мала звичку, яка здавалась моторошно нудною: кожна мережева зміна вимагала невеликого «before/after» знімка wg show, ip route і правил фаєрвола. Вони зберігали це поруч з тікетом зміни. Ніяких героїчних вчинків, ніякої таємниці.
Одної п’ятниці офіс втратив доступ до двох внутрішніх сервісів, розміщених в іншій філії. Тунелі були підняті. Пінги проходили до роутерів. Але трафік додатків падав. Інженер на виклику витягнув останній «відомо добрий» знімок і порівняв його з поточним станом.
Різниця була очевидна: підмережа офісу була змінена з 10.10.30.0/24 на 10.10.30.0/23 під час «дрібного розширення», але AllowedIPs хаба все ще вказував тільки /24. Половина хостів офісу опинилась за межами маршрутизованого діапазону. Частина хостів могла ініціювати сесії (залежно від джерела IP), інші — були в чорній діри. Це виглядало випадковим, бо залежало від того, які IP роздавав DHCP.
Виправлення зайняло хвилини: оновити AllowedIPs на записі піра хаба і перезапустити інтерфейс. Порятунок не був геніальним; ним стала історія змін. Нудні практики не отримують оплесків, але вони рятують ваші вихідні.
FAQ
1) Чи потрібна мені повна mesh для трьох офісів?
Ні. Можете, але hub-and-spoke легше в експлуатації. Один хаб для захисту, моніторингу і відлагодження. Mesh перетворюється на «кожен відповідає за доступність кожного».
2) Чи повинен хаб NAT-ити між офісами?
Не за замовчуванням. Маршрутуйте реальні підмережі енд-ту-енд, щоб логи й ACL мали сенс. NAT прийнятний для централізованого виходу в інтернет або тимчасової обробки перекриттів, але не як стандартний шлях.
3) Де ставити PersistentKeepalive?
На споках майже завжди, особливо за NAT. 25 секунд — типове значення. Якщо лінк лімітований чи платний, можна збільшити, але не прибирайте це без вагомих причин.
4) Чи можна використовувати DNS-імена замість статичної IP для endpoint хаба?
Так, але не вірте, що DNS — безпомилковий. Якщо використовуєте DNS-ім’я, забезпечте надійне резолвінг на споках і продумайте, як обробляти зміну IP хаба без людського втручання.
5) Чому використовуються /32-адреси на споках для wg0?
Тому що це зменшує невизначеність. Інтерфейс тунелю не потребує відчуття спільного L2-сегмента; йому потрібен стабільний ідентифікатор для кожного піра. /32 — чисто, а маршрутизація базується на AllowedIPs.
6) Який найкращий MTU для WireGuard site-to-site?
Почніть з 1420. Якщо у вас PPPoE або дивні WAN-шляхи, можливо знадобиться менше. Виміряйте DF-пінгами і перевірте реальним файлообміном (SMB/HTTPS) перед тим, як вважати все в порядку.
7) Чи можу я обмежити, які офіси можуть спілкуватися між собою?
Так, і вам варто це зробити. Застосовуйте це на хабі правилами у forward chain (wg0→wg0), що матчать джерело/цільові підмережі. Не розраховуйте на «вони, мабуть, не будуть».
8) Як впоратися з перекриттям офісних підмереж без перенумерації?
Можна NAT-ити одну сторону або використовувати 1:1-мепінг, але це операційний борг. Ви будете витрачати час на діагностику ідентичності і ACL. Якщо це постійно, заплануйте проект перенумерації.
9) Чи надає WireGuard контроль доступу на рівні користувача?
Ні. Це ключі пірів і AllowedIPs. Для VPN на рівні користувача зазвичай термінують на окремій системі і інтегрують ідентичність, MFA і перевірку стану пристрою.
10) Чи потрібна висока доступність для хаба?
Якщо офіси залежать від нього для ключових операцій — так. Щонайменше: бекапи, автоматизований rebuild і протестований план відновлення (резервний хаб або плаваюча IP в середовищах, що підтримують це). «Ми просто відновимо» — не план, поки ви не поміряєте час відновлення.
Наступні кроки, що реально зменшують тривогу на пейджері
WireGuard hub-and-spoke — надійна архітектура, але лише якщо ви ставитеся до хаба як до інфраструктури, а не як до побочного проєкту. Ось що робити далі, у практичному порядку:
- Запишіть намір. Які підмережі існують, які з них мають маршрутизуватися через WireGuard і які офіси можуть доступатися до яких сервісів.
- Зробіть AllowedIPs підлягаючими рев’ю. Тримайте конфіги у версійній системі, вимагайте рев’ю і забезпечте правило «жодних перекриттів» як пункт чеклісту.
- Кодіфікуйте політику фаєрвола. Default-drop у форвардингу на хабі, потім дозволяйте лише міжофісні потоки, які ви хочете. Рахуйте drop-и.
- Виміряйте MTU один раз, правильно. DF-пінги та реальний тест файлообміну. Потім встановіть MTU і не торкайтеся його, якщо WAN не зміниться.
- Побудуйте повторювану рутину діагностики. Плейбук вище — ваш перший респондент. Роздрукуйте його, прикріпіть і використовуйте.
- Вирішіть, чи потрібен централізований вихід у інтернет. Якщо так — робіть це навмисно з явними маршрутами і NAT, і плануйте пропускну здатність та політики.
Якщо ви зробите ці речі, ваші три офіси перестануть поводитися як три окремі планети. І коли щось ламається — а це трапиться — у вас буде достатньо сигналу, щоб виправити все без ритуальних жертв мережевим богам.