WireGuard VPN за схемою hub-and-spoke для 3 офісів із доступом за ролями

Було корисно?

Три офіси. Один «швидкий» VPN. Раптом фінансовий директор друкує в лабораторії, а хелпдеск не може дістатися до бази даних заявок, а дзвінки CEO у Zoom звучать як робот, що тоне. Ви не «налаштували тунель». Ви побудували мережу. У мереж є фізика, політика та гострі кути.

Це практичний, орієнтований на продакшн дизайн hub-and-spoke WireGuard VPN для трьох офісів із правилами доступу за ролями. Ми зробимо це з розумною маршрутизацією, явною сегментацією та достатньою спостережливістю, щоб ви могли відлагодити неминуче «вчора працювало» без гадань.

Архітектурні рішення, які не підведуть пізніше

Чому hub-and-spoke для трьох офісів?

При трьох сайтах зручно думати про full-mesh: «просто з’єднаємо всіх з усіма». Це працює, поки ви не додасте ролі, спільні сервіси, майбутні офіси та аудитора з планшетом і очікуваннями. Hub-and-spoke дає єдину точку контролю, де ви можете:

  • послідовно застосовувати політики (фаєрвол, логування, DNS)
  • зробити маршрутизацію передбачуваною (споки відправляють зовнішній трафік в хаб)
  • зменшити операційну складність (одне місце для дебагу міжсайтових проблем)
  • додати четвертий офіс без нових способів страждання

Недолік у тому, що хаб стає важливим компонентом. Це нормально. У продакшні завжди є важливі частини; фокус у тому, щоб знати які саме і ставитись до них відповідним чином.

Визначте ролі ще до визначення правил

«Правила доступу за ролями» — це не фаєрвол-фіча. Це бізнес-рішення, виражене в пакетах. Почніть з ролей, що відповідають патернам трафіку:

  • IT/Admin: може доступатися до підмереж управління, jump-host’ів, моніторингу, можливо — до всього під час інцидентів.
  • Finance: доступ до бухгалтерських систем, файлових шарів, обмежених принтерів, не до тестових мереж R&D.
  • Engineering: доступ до систем збірки, репозиторіїв, staging, не до HR-систем.
  • Guest/Vendor: доступ до однієї-двох аплікацій і нічого зайвого.

Як тільки ваші «ролі» стануть «людьми», ви отримаєте лавину ACL. Тримайте ролі небагато. Прив’язуйте користувачів/пристрої до ролей через VPN IP-пири або окремі інтерфейси, а політику застосовуйте централізовано.

Не використовуйте WireGuard як єдиний рушій політики

WireGuard відмінно виконує свою роль: це невеликий, швидкий зашифрований тунель із простою моделлю ключів. Це не RBAC-система. AllowedIPs у WireGuard — одночасно маршрутизація і дуже грубий admission control. Видавати його за фаєрвол приводить до дивних відмов.

Використовуйте WireGuard для захищеного транспорту і базового обмеження пірів. А для політик доступу застосовуйте nftables (або iptables, якщо вже дуже хочеться) на хабі. Це дає вам аудит і єдине місце для реалізації «Finance може дістатися 10.10.20.0/24, але не 10.10.30.0/24».

Жарт №1: VPN без правил фаєрвола — це просто дуже впевнений LAN-кабель.

Припускайте, що десь є NAT, і плануйте відповідно

Офіси часто за NAT-пристроями. WireGuard працює поверх UDP і добре поводиться за NAT, але NAT впливає на keepalive, MTU і доступність іззовні. Хаб має мати статичну публічну IP, якщо можливо. Якщо ні — потрібен креатив; але для трьох офісів заплатіть за статичну IP і закрийте питання.

Вирішіть: routed чи bridged. Оберіть routed.

Мостіння L2 між сайтами приносить штормів широкомовлення й «таємничих ARP». Використовуйте маршрутизовані підмережі для кожного офісу. Якщо хтось наполягає, що йому «потрібен L2», нехай назве додаток і протокол, а потім цей додаток виправлять.

Цікаві факти та контекст (бо історія повторюється в запитах)

  • Мета дизайну WireGuard — простота: значно менше рядків коду, ніж у традиційних VPN-стеках, що зменшує площу атак і час на відлагодження.
  • Використовує сучасну криптографію за замовчуванням: Curve25519 для обміну ключами, ChaCha20-Poly1305 для автентифікованого шифрування і BLAKE2s для хешування.
  • «Cryptokey routing» — основна ідея WireGuard: ключ, який ви використовуєте, також визначає, до яких IP-префіксів ви можете відправляти трафік для того піра.
  • IPsec старший за багато ваших роутерів: виник у 1990-х, і його складність частково — це викопна рештка старих вимог.
  • Site-to-site VPN колись були тільки апаратними: ранні корпоративні розгортання опиралися на виділені пристрої, бо CPU були повільніші й крипто було дороге.
  • UDP VPN можуть випереджати TCP VPN: тому що «TCP-over-TCP» — це реальна проблема; WireGuard уникає цього класу неприємностей, залишаючись на UDP.
  • Помилки MTU вічні: Path MTU і фільтрація ICMP спричиняли інциденти «все працює, крім однієї аплікації» десятиліттями.
  • Бази політики маршрутизації Linux (декілька таблиць маршрутизації і ip rule) існують тому, що «один маршрут за замовчуванням» перестав бути достатнім у реальних мережах.

Одна переказана ідея, яку варто тримати на моніторі: «надія — не стратегія» — часто приписують генерал-майору Gordon R. Sullivan. Сприймайте це як установку, не як доктринальну перевірку цитат.

IP-план і модель маршрутизації (нудна частина, яка вас врятує)

Підмережі офісів: тримайте їх унікальними й простими

Якщо ваші три офіси всі використовують 192.168.1.0/24, у вас не «проблема VPN». У вас проблема адресації. Виправте це перш за все. Перенумерація болюча, але менше, ніж назавжди жити з NAT в VPN.

Чистий, читабельний план:

  • LAN Офіс A: 10.10.10.0/24
  • LAN Офіс B: 10.10.20.0/24
  • LAN Офіс C: 10.10.30.0/24
  • VPN-транзит (WireGuard): 10.200.0.0/24

IP-адреси інтерфейсів WireGuard живуть у 10.200.0.0/24. Це не «LAN». Це транзитна мережа. Не ставте там принтери. Не ставте людей. Тримайте її священною і трохи нудною.

Де живуть шлюзи?

Кожен офіс отримує маленький Linux-шлюз (фізична коробка, VM або роутер, що може запускати WireGuard). Хаб — також Linux-шлюз у дата-центрі або VPC із стабільною публічною IP.

Приклади імен:

  • hub1 (публічна IP, центральна політика): wg0: 10.200.0.1/24
  • spoke-a: wg0: 10.200.0.11/24, LAN-інтерфейс на 10.10.10.0/24
  • spoke-b: wg0: 10.200.0.21/24, LAN-інтерфейс на 10.10.20.0/24
  • spoke-c: wg0: 10.200.0.31/24, LAN-інтерфейс на 10.10.30.0/24

Модель маршрутизації: споки направляють за замовчуванням у хаб для віддалених мереж

Споки мають маршрутизувати трафік до інших офісів через хаб. Хаб маршрутизуватиме до відповідного споку за призначенням. Це дає централізовану політику і уникає множення «винятків між споками».

Ви все одно матимете локальний вихід в інтернет у кожному офісі. Це не дизайн «відправляти весь трафік до хаба», якщо тільки ви цього свідомо не потребуєте і не любите налагоджувати веб-серфінг через WAN-лінк.

Доступ за ролями: що означає «за роллю» у WireGuard

Три способи реалізації ролей

Ви можете впровадити «ролі» на різних шарах. Виберіть один і дотримуйтеся його.

  1. За вихідною підмережею (рекомендовано): призначайте ролі внутрішнім VLAN/підмережам у кожному офісі (наприклад, VLAN Finance). Фаєрвол на хабі застосовує доступ з цих підмереж.

    Переваги: масштабовано, легко аудитити. Недоліки: вимагає внутрішньої чистоти мережі.
  2. За IP-піром WireGuard: виділіть кожній ролі (або пристрою) VPN-IP і пишіть правила фаєрвола за цими джерелами.

    Переваги: працює, навіть якщо LAN плоский. Недоліки: може стати громіздким; ви кодуєте ідентичність як IP.
  3. За окремими інтерфейсами WireGuard на роль: wg-finance, wg-eng тощо.

    Переваги: дуже явне розділення. Недоліки: більше інтерфейсів, більше рухомих частин; зазвичай зайве для трьох офісів, якщо тільки вимоги комплаєнсу не диктують інакше.

Практична рекомендація

Робіть ролі за вихідною підмережею в кожному офісі й застосовуйте їх на хабі. Якщо Офіс A зараз має одну плоску підмережу — розділіть її. Так, це «мережеві роботи». І це їхня суть.

Приклад VLAN ролей в Офісі A:

  • Офіс A Finance: 10.10.11.0/24
  • Офіс A Engineering: 10.10.12.0/24
  • Офіс A IT/Admin: 10.10.13.0/24

Повторіть для Офісів B і C, або збережіть ролі узгодженими між офісами, якщо можете. Узгодженість — це помножувач сили, коли ви втомлені.

Що WireGuard може і не може для RBAC

WireGuard може гарантувати, що певний пір дозволений лише для певних префіксів призначення через AllowedIPs. Це запобігає випадковим маршрутним витокам і деяким типам спуфінгу. Воно не забороняє пір досягати всього, що доступне після тунелю. Це вже завдання фаєрвола.

Конфіги WireGuard: хаб, споки та що насправді робить AllowedIPs

Конфіг хаба

Хаб термінує всі три споки. AllowedIPs хаба для кожного піра має включати:

  • WireGuard тунельну IP споку ( /32 )
  • LAN-підмережі споку (офісні LAN і VLAN ролей)
cr0x@server:~$ sudo cat /etc/wireguard/wg0.conf
[Interface]
Address = 10.200.0.1/24
ListenPort = 51820
PrivateKey = HUB_PRIVATE_KEY
# Optional but practical:
SaveConfig = false

# Spoke A
[Peer]
PublicKey = SPOKE_A_PUBLIC_KEY
AllowedIPs = 10.200.0.11/32, 10.10.10.0/24, 10.10.11.0/24, 10.10.12.0/24, 10.10.13.0/24

# Spoke B
[Peer]
PublicKey = SPOKE_B_PUBLIC_KEY
AllowedIPs = 10.200.0.21/32, 10.10.20.0/24, 10.10.21.0/24, 10.10.22.0/24, 10.10.23.0/24

# Spoke C
[Peer]
PublicKey = SPOKE_C_PUBLIC_KEY
AllowedIPs = 10.200.0.31/32, 10.10.30.0/24, 10.10.31.0/24, 10.10.32.0/24, 10.10.33.0/24

Конфіг споку

Кожен спок має одного піра: хаб. AllowedIPs споку для хаба має включати:

  • тунельну IP хаба (/32) і будь-які центральні сервіси на стороні хаба
  • всі інші офісні LAN, доступні через хаб

Це означає, що спок маршрутизує інші офіси через хаб. Ніякого спок-до-спок пірингу. Ніяких особливих винятків.

cr0x@server:~$ sudo cat /etc/wireguard/wg0.conf
[Interface]
Address = 10.200.0.11/24
PrivateKey = SPOKE_A_PRIVATE_KEY

[Peer]
PublicKey = HUB_PUBLIC_KEY
Endpoint = hub1.example.net:51820
AllowedIPs = 10.200.0.1/32, 10.200.0.0/24, 10.10.20.0/24, 10.10.21.0/24, 10.10.22.0/24, 10.10.23.0/24, 10.10.30.0/24, 10.10.31.0/24, 10.10.32.0/24, 10.10.33.0/24
PersistentKeepalive = 25

Чому включати 10.200.0.0/24 у AllowedIPs на споку?

Щоб спок міг досягати інших тунельних IP пірів, якщо потрібно (моніторинг, ping, health checks). Якщо ви хочете суворо закрити доступ, включіть лише 10.200.0.1/32 і покладайтеся на моніторинг, що працює з хаба. Обидва підходи прийнятні; я зазвичай дозволяю транзитний /24 і фаєрволюю його на хабі.

IP-форвардинг: це треба ввімкнути

Це та частина, яку люди забувають, потім звинувачують WireGuard. Тунель піднято, але ніхто нічого не бачить, бо Linux-бокс не маршрутизує.

Застосування доступу через nftables (не на рівні інтуїції)

Принцип: за замовчуванням забороняти між ролями, дозволяти за потребою

Хаб має забезпечувати сегментацію між підмережами ролей офісів і спільними сервісами. Почніть із «заборонити міжофісний трафік за замовчуванням», потім додайте тільки ті потоки, які справді потрібні. Це здається суворим. Але також запобігає інцидентам типу «ноут фінансів сканує всю мережу інженерів».

Напрями трафіку, які важливі

  • Пересиланий трафік через хаб: міжофісний та офіс→центральні сервіси
  • Вхідний трафік до самого хаба: SSH, моніторинг, DNS якщо хаб його надає

Приклад політики nftables на хабі

Це спрощений, але реалістичний патерн: приймаємо established, потім явні дозволи, потім drop. Логуйте дропи помірковано, інакше під час інциденту ви самі DDoS-нете диск.

cr0x@server:~$ sudo cat /etc/nftables.conf
flush ruleset

table inet filter {
  chain input {
    type filter hook input priority 0;
    policy drop;

    iif lo accept
    ct state established,related accept

    # Allow WireGuard
    udp dport 51820 accept

    # Allow SSH from IT/Admin role subnets only
    ip saddr { 10.10.13.0/24, 10.10.23.0/24, 10.10.33.0/24 } tcp dport 22 accept

    # Allow monitoring from IT/Admin
    ip saddr { 10.10.13.0/24, 10.10.23.0/24, 10.10.33.0/24 } tcp dport { 9100, 9182 } accept

    # Optional: ICMP for troubleshooting
    ip protocol icmp accept
    ip6 nexthdr icmpv6 accept
  }

  chain forward {
    type filter hook forward priority 0;
    policy drop;

    ct state established,related accept

    # Allow IT/Admin roles cross-office (jump hosts, mgmt)
    ip saddr { 10.10.13.0/24, 10.10.23.0/24, 10.10.33.0/24 } ip daddr { 10.10.0.0/16 } accept

    # Allow Finance to reach accounting service subnet (central or specific office)
    ip saddr { 10.10.11.0/24, 10.10.21.0/24, 10.10.31.0/24 } ip daddr 10.10.50.0/24 tcp dport { 443, 5432 } accept

    # Allow Engineering to reach build systems
    ip saddr { 10.10.12.0/24, 10.10.22.0/24, 10.10.32.0/24 } ip daddr 10.10.60.0/24 tcp dport { 22, 443, 8080 } accept

    # Allow limited printer access within each office only (example)
    ip saddr 10.10.11.0/24 ip daddr 10.10.10.50 tcp dport { 631, 9100 } accept
    ip saddr 10.10.21.0/24 ip daddr 10.10.20.50 tcp dport { 631, 9100 } accept
    ip saddr 10.10.31.0/24 ip daddr 10.10.30.50 tcp dport { 631, 9100 } accept

    # Log and drop everything else
    limit rate 5/second log prefix "vpn-forward-drop " flags all counter drop
  }
}

Тут ви заробляєте свій хліб. Хаб стає точкою застосування політики. Коли хтось запитає «чому постачальник X не може дістатися Y», ви дасте відповідь з правилом, рядком у логу та записом про зміну — а не легендою.

DNS між сайтами без перетворення на будинок з привидами

Оберіть одну DNS-стратегію і дотримуйтеся її

Мультиофісні VPN найчастіше падають у двох площинах: маршрутизація ламається або DNS ламається. Маршрутизація помітна; DNS ламається повільно, дивно і емоційно виснажує.

Поширені стратегії:

  • Централізований DNS: один внутрішній DNS сервіс, доступний через VPN. Найпростіша політика, одне джерело істини. Забезпечте відмовостійкість.
  • DNS для кожного офісу з умовною передачою: кожен офіс вирішує локальні імена й переадресовує інші зони через VPN. Працює добре, але потребує дисципліни.
  • Чистий IP + hosts: технічно можливо, соціально катастрофічно. Не робіть так.

Рекомендація

Для трьох офісів запускайте центральний DNS на хабі (або два хаби для HA) і налаштовуйте клієнтів офісів використовувати його для внутрішніх зон. Якщо офіси повинні вирішувати локальні імена, використовуйте умовну переадресацію. Тримайте внутрішні зони явними (наприклад, corp.internal, svc.corp.internal).

Продуктивність: MTU, реалії UDP і чому «швидко» — це проєктне рішення

MTU — це не необов’язкова дрібниця

WireGuard додає накладні витрати. Якщо ви штовхаєте пакети занадто великі, вони фрагментуються або втрачаються. Якщо ICMP «fragmentation needed» блокується десь по дорозі (часто так і є), ви отримаєте класичні симптоми: SSH працює, а передачі файлів зависають; веб-додатки підвантажуються наполовину; SMB перетворюється на перформанс-арт.

Встановлюйте MTU свідомо. Поширене безпечне значення — 1420 на інтерфейсах WireGuard. Іноді потрібне нижче (1412, 1380) залежно від upstream і інкапсуляцій.

UDP і «стан»

WireGuard — це UDP. Це добре для продуктивності і уникнення TCP-over-TCP, але це означає:

  • таймаути NAT можуть тихо зламати зворотні шляхи, якщо не використовувати keepalives;
  • деякі мережі ставляться до UDP підозріло і можуть його обмежувати;
  • треба моніторити «свіжість» handshake’ів і лічильники трафіку, а не «стан з’єднання».

Жарт №2: проблеми MTU схожі на котів — якщо думаєте, що у вас його немає, він просто ховається під диваном.

Формування пропускної здатності і справедливість

Якщо один офіс насичує лінк хаба, усі ділять біль. Якщо це проблема, використайте traffic control (tc) для шейпінгу по інтерфейсу або за вихідною підмережею. Не робіть цього передчасно. Але зробіть свідомо, якщо бізнес-додатки застрягають за чиїмось офсайт-резервним копіюванням.

Операції: ротація ключів, контроль змін і оновлення

Управління ключами — це не складно, але це важливо

WireGuard використовує статичні публічні/приватні пари для кожного піра. Ключі за замовчуванням не мають терміну дії. Це і сила, і управлінська проблема. Ви маєте:

  • рухати ключі за графіком (наприклад, щорічно) і при звільненні співробітників
  • зберігати приватні ключі безпечно (файли доступні лише root, резервні копії зашифровані)
  • документувати, який ключ належить якому сайту/ролі

Контроль змін, який не зіпсує вихідні дні

Хаб — центральний елемент. Ставтесь до його конфігурацій як до продакшн-коду:

  • тримайте /etc/wireguard та конфігурацію фаєрвола під контролем версій (приватний репозиторій)
  • використовуйте конвенції іменування пір і коментарі поза конфігом, якщо потрібно
  • деплойте зміни через передбачуваний процес (Ansible, Salt або хоча б скриптовий rsync)
  • завжди майте план відкату

Оновлення

WireGuard в ядрі Linux стабільний. Тим не менш, оновлення змінюють ядра, поведінку nftables і драйвери NIC. Не оновлюйте хаб і всі споки одночасно. Рознесіть кроки. Перевіряйте handshake’и і маршрути після кожного кроку.

Практичні завдання: команди, виводи, рішення (12+ команд, які ви справді виконуватимете)

Завдання 1: Перевірте стан інтерфейсу WireGuard

cr0x@server:~$ sudo wg show
interface: wg0
  public key: 1Xh9nR...hubpub...
  private key: (hidden)
  listening port: 51820

peer: rGm8z...spokeA...
  allowed ips: 10.200.0.11/32, 10.10.10.0/24, 10.10.11.0/24, 10.10.12.0/24, 10.10.13.0/24
  latest handshake: 37 seconds ago
  transfer: 2.31 GiB received, 3.02 GiB sent
  persistent keepalive: every 25 seconds

Що це означає: «latest handshake» показує, чи пір живий. Лічильники трафіку показують, чи трафік йде в обидва боки.

Рішення: Якщо handshake-и прострочені (>2 хвилин) для споку за NAT, перевірте keepalive, UDP-доступність і правильність endpoint перед тим, як торкатися маршрутизації.

Завдання 2: Підтвердіть IP інтерфейсу і MTU

cr0x@server:~$ ip -d link show dev wg0
8: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/none
    wireguard version 1.0.20210914

Що це означає: MTU встановлено на 1420; інтерфейс UP.

Рішення: Якщо бачите MTU 1500 і ви на PPPoE або інших лінках з великою накладною, плануйте зменшення MTU і повторне тестування передач файлів.

Завдання 3: Переконайтеся, що IPv4 forwarding увімкнено на хабі та споках

cr0x@server:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

Що це означає: Linux маршрутизація увімкнена.

Рішення: Якщо 0 — увімкніть і збережіть налаштування; інакше ви маєте «VPN, що підключений, але не маршрутує», класична ситуація.

Завдання 4: Перевірте маршрути до офісних підмереж на хабі

cr0x@server:~$ ip route show table main | grep 10.10.
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

Що це означає: Хаб вважає ці підмережі досяжними через wg0.

Рішення: Якщо маршрути відсутні — можливо, AllowedIPs піра хаба неповні або інтерфейс не застосовує їх як маршрути (залежно від того, як ви керуєте маршрутизацією). Почніть із виправлення AllowedIPs.

Завдання 5: Підтвердити, що спок маршрутизує інші офіси через хаб

cr0x@server:~$ ip route get 10.10.20.10
10.10.20.10 dev wg0 src 10.200.0.11 uid 0
    cache

Що це означає: Спок A маршрутизує трафік до Офісу B через wg0.

Рішення: Якщо трафік йде в WAN-інтерфейс, то в AllowedIPs піра хаба відсутні підмережі Офісу B.

Завдання 6: Перевірте, що nftables правила завантажені (хаб)

cr0x@server:~$ sudo nft list ruleset | sed -n '1,80p'
table inet filter {
	chain input {
		type filter hook input priority filter; policy drop;
		iif "lo" accept
		ct state established,related accept
		udp dport 51820 accept
		ip saddr { 10.10.13.0/24, 10.10.23.0/24, 10.10.33.0/24 } tcp dport 22 accept
		ip protocol icmp accept
	}
	chain forward {
		type filter hook forward priority filter; policy drop;
		ct state established,related accept
		ip saddr { 10.10.13.0/24, 10.10.23.0/24, 10.10.33.0/24 } ip daddr 10.10.0.0/16 accept
		limit rate 5/second log prefix "vpn-forward-drop " flags all counter drop
	}
}

Що це означає: Ваша політика існує і застосовується з default-drop.

Рішення: Якщо правила відсутні — ви або не завантажуєте nftables при старті, або інший інструмент перезаписав їх. Виправте порядок сервісів перед додаванням нових правил.

Завдання 7: Знайдіть, чому потік блокується, за допомогою лічильників і логів

cr0x@server:~$ sudo nft list chain inet filter forward
table inet filter {
  chain forward {
    type filter hook forward priority 0; policy drop;
    ct state established,related accept
    ip saddr { 10.10.13.0/24, 10.10.23.0/24, 10.10.33.0/24 } ip daddr 10.10.0.0/16 accept
    limit rate 5/second log prefix "vpn-forward-drop " flags all counter packets 41 bytes 2460 drop
  }
}

Що це означає: 41 пересланих пакета були відкинуті catch-all правилом.

Рішення: Якщо користувачі скаржаться і цей лічильник росте під час їхніх тестів, вам потрібно додати явне правило дозволу (або ви бачите несподіваний трафік, який має залишатися заблокованим).

Завдання 8: Підтвердити доступність UDP 51820 зі споку

cr0x@server:~$ sudo tcpdump -ni eth0 udp port 51820 -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:44:01.102938 IP 198.51.100.22.39422 > 203.0.113.10.51820: UDP, length 148
12:44:01.128440 IP 203.0.113.10.51820 > 198.51.100.22.39422: UDP, length 92

Що це означає: Пакети доходять і відповіді повертаються. Базова досяжність ок.

Рішення: Якщо бачите вхідні, але немає вихідних — підозрюйте фаєрвол на хабі. Якщо нічого не видно вхідного — підозрюйте upstream NAT/port forwarding або неправильний endpoint IP.

Завдання 9: Перевірте, що NAT випадково не застосовується до VPN-трафіку

cr0x@server:~$ sudo nft list table ip nat
table ip nat {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    oifname "eth0" masquerade
  }
}

Що це означає: Все, що виходить через eth0, маскується, і це може торкатися VPN-маршрутизованого офісного трафіку, якщо він еґреситься через хаб.

Рішення: Якщо ви хочете чисто маршрутизований трафік між офісами, переконайтеся, що міжофісний трафік лишається на wg0 і не волоситься на eth0. Якщо ви робите центральний вихід в інтернет — NAT може бути правильним, але тоді плануйте пропускну здатність і логування відповідно.

Завдання 10: Виявити MTU-блекхоли за допомогою ping + DF

cr0x@server:~$ ping -M do -s 1372 10.10.20.10 -c 3
PING 10.10.20.10 (10.10.20.10) 1372(1400) bytes of data.
1380 bytes from 10.10.20.10: icmp_seq=1 ttl=62 time=18.9 ms
1380 bytes from 10.10.20.10: icmp_seq=2 ttl=62 time=18.7 ms
1380 bytes from 10.10.20.10: icmp_seq=3 ttl=62 time=18.8 ms

--- 10.10.20.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms

Що це означає: Пакет 1400 байтів (включно з заголовками) проходить без фрагментації. Добрий знак.

Рішення: Якщо це падає на розмірах значно нижчих за 1400, зменшіть MTU WireGuard і повторіть тести, або перестаньте блокувати ICMP «frag needed» деінде на шляху.

Завдання 11: Підтвердьте, що reverse path filtering не відкидає маршрутизований VPN-трафік

cr0x@server:~$ sysctl net.ipv4.conf.all.rp_filter
net.ipv4.conf.all.rp_filter = 0

Що це означає: Строгий reverse-path filter відключено глобально (0), що часто необхідно для багатошляхових сценаріїв.

Рішення: Якщо rp_filter = 1 або 2 і ви бачите односпрямований трафік, налаштуйте його (обережно) на релевантних інтерфейсах. Не відключайте бездумно без розуміння асиметрії маршрутів.

Завдання 12: Перевірте, що LAN-сторона має маршрути назад до віддалених підмереж

cr0x@server:~$ ip route | grep 10.10.20.0/24
10.10.20.0/24 via 10.10.10.1 dev eth1

Що це означає: Хост в Офісі A знає відправляти трафік в Офіс B через локальний шлюз (10.10.10.1).

Рішення: Якщо клієнти офісу не мають маршруту, або оголосіть статичні маршрути на роутері офісу через локальний VPN-шлюз, або зробіть VPN-шлюз дефолтним шлюзом VLAN. VPN-маршрутизація не працює, якщо лише шлюзи знають шляхи.

Завдання 13: Перевірте conntrack для конкретного потоку

cr0x@server:~$ sudo conntrack -L -p tcp --dport 443 2>/dev/null | head
tcp      6 431999 ESTABLISHED src=10.10.11.22 dst=10.10.50.10 sport=53422 dport=443 src=10.10.50.10 dst=10.10.11.22 sport=443 dport=53422 [ASSURED] mark=0 use=1

Що це означає: Хаб бачить встановлений TCP-потік між клієнтом Finance і сервісом бухобліку.

Рішення: Якщо користувачі скаржаться на скидання/тайм-аути, але conntrack ніколи не показує ESTABLISHED, підозрюйте фаєрвол, маршрутизацію або MTU. Якщо ESTABLISHED є, але аплікація повільна — дивіться на затори/втрати пакетів.

Завдання 14: Переконайтеся, що час правильний (handshake-и не люблять подорож у часі)

cr0x@server:~$ timedatectl status | sed -n '1,8p'
Local time: Sun 2025-12-28 10:25:44 UTC
Universal time: Sun 2025-12-28 10:25:44 UTC
RTC time: Sun 2025-12-28 10:25:44
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no

Що це означає: Годинник синхронізований. Добре.

Рішення: Якщо час відстає — виправте NTP перш за все. Дивні проблеми з handshake-ами і кореляцією логів гарантовані при дрейфі годин.

Швидка діагностика — план дій

Коли дзвонять і кажуть «VPN впав», зазвичай мають на увазі «аплікація не працює». Не починайте з дебагу аплікації. Діагностуйте шлях.

Спочатку: чи тунель живий?

  • На хабі: wg show — перевірте latest handshake для ураженого споку.
  • На споку: wg show — підтвердіть, що він говорить з endpoint хаба і лічильники зростають під час тесту.
  • Якщо handshake прострочений: перевірте UDP-доступність, IP/порт endpoint’а, NAT keepalive і нещодавні зміни у провайдера/роутері.

По-друге: чи маршрути правильні з обох боків?

  • На споку: ip route get <remote-ip> — повинен обрати wg0.
  • На хабі: ip route get <destination> — переконайтесь, що вказує на правильний пір через wg0.
  • Перевірте офісний LAN: чи клієнти мають маршрути назад через локальний шлюз?

По-третє: чи фаєрвол робить те, що ви йому сказали?

  • На хабі: nft list chain inet filter forward — спостерігайте лічильники під час відтворення.
  • Шукайте дропи, що відповідають релевантним підмережам/портам.
  • Тимчасово додайте вузьке allow-правило (джерело+призначення+порт) щоб підтвердити гіпотезу. Відкатайте, якщо нічого не дає.

По-четверте: чи це проблема MTU/фрагментації?

  • Використовуйте ping -M do -s тести через VPN.
  • Якщо маленькі пакети працюють, а великі падають або зависають — налаштуйте MTU WireGuard і/або виправте фільтрацію ICMP.

По-п’яте: чи це DNS?

  • Якщо користувачі можуть пінгувати IP, але не імена — не чіпайте маршрути.
  • Перевірте резолвери, conditional forwarders і налаштування split-DNS. Переконайтесь, що DNS-сервер досяжний з підмережі ролі.

Суть швидкості: тунель → маршрут → фаєрвол → MTU → DNS. У такому порядку. Кожного разу.

Типові помилки: симптом → причина → виправлення

«Тунель піднятий, але нічого не доступно»

Симптом: wg show показує handshake-и; pings до віддаленої LAN не проходять.

Причина: Вимкнений IP forwarding на хабі або споку, або відсутні маршрути на LAN-стороні.

Виправлення: Увімкніть net.ipv4.ip_forward=1. Переконайтесь, що клієнти офісу мають маршрути до віддалених підмереж через локальний шлюз; не чекайте, що вони самі їх дізнаються.

«Офіс A може дістатися Офісу B, але не навпаки»

Симптом: Односпрямований зв’язок; TCP сесії зависають.

Причина: Асиметрична маршрутизація або rp_filter; також можливі проблеми зі станом фаєрвола.

Виправлення: Перевірте маршрути з обох боків і на хабі. Налаштуйте rp_filter на багатошляхових шлюзах. Переконайтесь, що forward правила хаба дозволяють обидва напрями або використовують established/related обробку.

«Лише деякі аплікації падають; передачі файлів зависають; SSH працює»

Симптом: Маленькі пакети проходять; великі тайм-аутяться.

Причина: MTU-блекхол / проблеми фрагментації, часто через блокування ICMP upstream.

Виправлення: Встановіть mtu 1420 (або нижче) на wg0. Тестуйте за допомогою ping -M do. По можливості виправте фільтрацію ICMP.

«Встановили новий офісний роутер і тепер VPN флапає»

Симптом: Handshake-и періодично застарілі; лічильники трафіку замерзають, потім ривком зростають.

Причина: Змінився таймаут NAT або обробка UDP; відсутній keepalive.

Виправлення: Встановіть PersistentKeepalive = 25 на споках за NAT. Перевірте, що порт хаба доступний і не перемаплено.

«Finance може доступатися до інженерних сервісів (ой)»

Симптом: Користувачі бачать те, чого не повинні; немає явних deny-правил.

Причина: Занадто широке allow-правило або покладання на AllowedIPs як на «політику».

Виправлення: Впровадьте default-drop у forward ланці хаба і додайте явні allow-правила за ролями. Тримайте дозволи вузькими: джерело, призначення, порти.

«Після перезавантаження нічого не маршрутується, поки хтось не виконає команду»

Симптом: Працює після ручного втручання.

Причина: Порядок запуску сервісів: WireGuard піднімається раніше за sysctl/nftables, або nftables не завантажені.

Виправлення: Забезпечте персистентність sysctl, увімкніть службу nftables і зробіть підняття WireGuard залежним від готовності мережі. Тестуйте холодний старт, а не тільки теплий рестарт.

«DNS повільний між сайтами»

Симптом: Перший запит займає секунди; потім все добре.

Причина: Резолвер пробує недосяжні DNS-сервери першими (неправильний порядок) або UDP-фрагментація відповідей DNS.

Виправлення: Налаштуйте клієнтів використовувати досяжний внутрішній DNS першим. Розгляньте TCP-фолбек для DNS і виправте MTU за потреби.

Три корпоративні міні-історії з практики

Міні-історія 1: Інцидент через хибне припущення

Середня компанія з’єднала три офіси новим WireGuard хабом. Діаграма мережі виглядала чисто. План запуску був простий: встановити шлюзи, додати маршрути, святкувати.

Припущення було того роду, що помічаєш тільки після удару: «клієнти самі навчаться маршрутів». Шлюзи мали правильні маршрути. Хаб мав правильні AllowedIPs. Handshake-и свіжі. Пінги між шлюзами працювали. Але користувачі не могли дістатися нічого через VPN, якщо вони не були на підмережі, де шлюз був дефолтним маршрутом.

Хелпдеск ескалював до «VPN впав». SRE на виклику перевірив WireGuard першим, знайшов його здоровим і марно годину гонявся за примарними проблемами в фаєрволі, бо «тунель піднятий» зазвичай означає «шляхи існують». У цьому випадку — ні.

Виправлення було буденне: оновити офісні роутери, щоб анонсувати статичні маршрути до інших офісів через локальний VPN-шлюз (або зробити VPN-шлюз дефолтним шлюзом для VLAN ролей). Після цього все «магічно» запрацювало, що й є мережевою магією, коли зроблено правильно.

Урок: коли ви розгортаєте маршрутизований VPN, ваш LAN має брати участь. Якщо крайовий роутер офісу не знає, де знаходиться 10.10.20.0/24, не знають і клієнти. Мережі не читають думки.

Міні-історія 2: Оптимізація, що відкотилася

Інша організація захотіла зменшити латентність між Офісами B і C і додала прямий спок-до-спок тунель «тільки для важкого трафіку». Хаб залишився офіційним шляхом. Прямий тунель був «швидкою лінією».

Це гарно працювало в лабораторії. У продакшні створило другу істину маршрутизації. Деякі підмережі віддавали перевагу прямому тунелю; інші йшли через хаб. Політики фаєрвола жили на хабі, тож тепер трафік або обходив політику, або його відкидало залежно від того, яким шляхом пішов пакет сьогодні.

Потім стався найбільш дивний збій: шарінги файлів працювали з B у C, але не навпаки, і тільки для користувачів в одній VLAN. Вони випадково створили асиметричну маршрутизацію: запит ішов прямим шляхом, відповіді поверталися через хаб. Станові фаєрволи не люблять такої творчості.

«Оптимізацію» прибрали. Повернулися до hub-and-spoke, а продуктивність покращили нудними, але правильними речами: налаштували MTU, виправили QoS на WAN-краю і припинили бекапи в робочий час. Латентність покращилася, і, що важливіше, повернулась передбачуваність.

Урок: у мультисайт мережі «ще один тунель» майже ніколи не є «ще одним тунелем». Це ще один світ маршрутизації.

Міні-історія 3: Нудна, але правильна практика, що врятувала день

Третя компанія ставилася до хаба як до справжнього продакшн-сервісу. Вони тримали конфіги в контролі версій. Кожна зміна мала короткий опис і очікуваний вплив. У них також була односторінкова «швидкої діагностики VPN» прямо в блокноті on-call, як ніби це 2004 рік і принтери ще були важливі.

Одного дня Офіс A втратив доступ до аплікації в Офісі C. Тунель був піднятий. Аплікація була працююча. Почалися звинувачення в бік «VPN» і «фаєрвола», ніби це настрої.

On-call інженер пройшовся по рукописному плану: перевірив handshake-и (свіжі), маршрути (коректні), лічильники nftables forward (падіння лічильників збільшуються на default drop). Це звузило проблему до політики. Остання зміна була звуження allow-правила для Engineering, яке випадково виключило підмережу, що використовувала аплікацію.

Вони відкотили правило за хвилини, відновили сервіс, а потім повернули виправлене правило з тест-планом. Інцидент залишився маленьким, бо зміни були трасовані й порядок діагностики був детермінований.

Урок: нудна гігієна — версійовані конфіги, вузькі зміни і детермінований порядок діагностики — перемагає героїзм. Кожного разу.

Контрольні списки / покроковий план

Покроковий план побудови (робіть це саме в такому порядку)

  1. Виправте IP-перекриття: переконайтесь, що кожен офіс має унікальні підмережі. Якщо ні — перенумеруйте зараз. Не дозволяйте «тимчасовому NAT» стати постійною мукою.
  2. Визначте підмережі ролей: створіть VLAN/підмережі для ролей де можливо. Почніть з IT/Admin і Finance; додавайте інші лише за потреби.
  3. Підготуйте хаб: стабільна публічна IP, Linux, WireGuard, nftables, NTP, логування, агент моніторингу.
  4. Підготуйте три споки: кожен з WireGuard і здатністю маршрутизувати між LAN і wg0.
  5. Згенеруйте ключі: одна пара ключів на шлюз (і опціонально на роль або пристрій, якщо розширюватимете).
  6. Налаштуйте WireGuard: хаб має піри для кожного споку з правильними AllowedIPs; споки вказують на endpoint хаба з віддаленими офісними підмережами в AllowedIPs.
  7. Увімкніть форвардинг і базові sysctl: ip_forward, налаштування rp_filter за потреби.
  8. Встановіть маршрути на LAN: офісний роутер анонсує маршрути до інших офісів через локальний шлюз, або VPN-шлюз стає шлюзом VLAN.
  9. Реалізуйте фаєрвол на хабі: default drop для forward, явні дозволи за ролями. Тримайте тимчасовий «break-glass» набір правил для серйозних інцидентів.
  10. DNS-план: вирішіть центральний DNS чи conditional forwarding. Тестуйте розв’язання імен з кожної VLAN ролі.
  11. Перевірка MTU: встановіть MTU wg (почніть з 1420), тестуйте великі пакети і реальні навантаження (копіювання файлів, HTTPS, бази даних).
  12. Моніторинг: стежте за віком handshake, швидкостями передач, лічильниками падінь (nft), помилками інтерфейсів, CPU і пропускною здатністю.
  13. Документуйте: IP-план, правила ролей, власність ключів і порядок швидкої діагностики. Ваш майбутній я — зацікавлений стейкхолдер.

Перевірка перед зміною (кожного разу, коли торкаєтесь політик)

  • Чи знаю, які підмережі/ролі постраждають?
  • Чи маю тест-кейс (джерельна IP, цільова IP, порт) для валідації?
  • Чи перевірив поточні лічильники/логи, щоб встановити базу?
  • Чи зміна вузька (найменший привілей) і відкатна?
  • Чи маю консольний доступ, якщо я відріжу себе від хаба?

Перевірка після зміни (доведіть, не припускайте)

  • wg show на хабі: усі піри ще handshaking
  • Ping та один тест аплікації для кожної ролі (Finance, Eng, IT)
  • Перевірте лічильники nftables: очікуйте зростання дозволених правил; лічильник drop стабільний
  • Підтвердіть розв’язання DNS для внутрішніх зон
  • Запишіть зміну і спостережуваний вплив

Поширені питання

1) Чи робити full-mesh замість hub-and-spoke?

Для трьох офісів можна, але ви пошкодуєте, коли додасте рольові правила і захочете послідовного застосування політики. Hub-and-spoke централізує політику і спрощує відлагодження.

2) Чи можна реалізувати ролі лише за допомогою AllowedIPs?

Не надійно. AllowedIPs грубе і насамперед про маршрутизацію і scoping пірів. Використовуйте nftables на хабі для реалізації доступу за ролями — там можна виразити «Finance може дістатися цих портів на тих підмережах».

3) Де мають жити правила доступу: на хабі чи на споках?

Зробіть канонічну політику на хабі. Можна додати локальні egress-правила на споках для defense-in-depth, але не робіть політику розподіленою головоломкою, якщо не хочете неконсистентної поведінки.

4) Чи потрібні BGP/OSPF для трьох сайтів?

Ні. Статична маршрутизація підходить і часто краща для передбачуваності. Динамічна маршрутизація може знадобитися пізніше, але вона додає другий контрольний рівень для дебагу. Заслужіть цю складність.

5) Як впоратися з перекриттям підмереж, якщо перенумерація політично неможлива?

Ви можете використовувати NAT (1:1 або masquerade) на споках, але розглядайте це як технічний борг з відсотками. Документуйте трансляції, чекайте крайових випадків додатків і плануйте проект перенумерації.

6) Де запускати хаб: у хмарі чи на локальному обладнанні?

Хмара часто простіша для стабільної публічної IP, гарної пропускної здатності і віддаленого обслуговування. Он-прем може бути підходящим, якщо у вас є резервний інтернет і живлення. Рішення має базуватись на операційній зрілості, а не на ідеології.

7) Як додати віддалених користувачів пізніше, не зламаючи site-to-site модель?

Додайте окремий інтерфейс WireGuard або групу піров для віддалених користувачів, призначте їм виділену підмережу (наприклад, 10.200.10.0/24) і застосовуйте рольові правила на хабі так само. Уникайте змішування road-warrior клієнтів з тими ж адресними пулами, що й шлюзи.

8) Що робить «PersistentKeepalive» і коли він потрібний?

Він посилає періодичні пакети, щоб зберегти NAT-мапінги живими. Використовуйте його на споках за NAT (поширено) і на мобільних клієнтах. На хабі з публічною IP зазвичай не потрібен, якщо немає конкретної причини.

9) Як зробити це високодоступним?

Запустіть два хаби і або використайте anycast/BGP (складніше), або DNS + інструменти фейловеру (простішe), плюс подвійні тунелі від кожного споку. Тримайте мінімальний стан (WireGuard статeless-ish), але ваш фаєрвол і DNS також мають бути відмовостійкими.

10) Що логувати, не потопивши себе в даних?

Логуйте відкинуті forwards з rate limit на хабі, стежте за віком handshake і лічильниками трафіку, а також фіксуйте зміни конфігурацій. Не логируйте кожен прийнятий пакет; ваша система зберігання заслуговує кращого.

Наступні кроки, які зроблять понеділок спокійнішим

Якщо ви хочете VPN, що поводиться як інфраструктура, а не як фокус, будуйте його як інфраструктуру: унікальні підмережі, маршрутизована архітектура, централізована політика і спостережливість. Hub-and-spoke WireGuard — надійний патерн для трьох офісів, особливо коли потрібен доступ за ролями, а не «всі все бачать».

Практичні наступні кроки:

  • Запишіть IP-план і підмережі ролей, потім забезпечте унікальність у всіх офісах.
  • Підніміть хаб з WireGuard + nftables з default-drop для forward.
  • Підключіть один спок, валідуйте маршрути end-to-end, потім клонujte шаблон на інші два.
  • Реалізуйте рольові правила як явні дозволи, спостерігайте лічильники і майте готовність до відкату.
  • Додайте моніторинг віку handshake, пропускної здатності і лічильників падінь; тримайте порядок швидкої діагностики під рукою.

Квитків все одно буде багато. Але вони стануть тими розв’язуваними, а не надприродними.

← Попередня
Чипи тегів і панелі фільтрів: обробка переповнення, обгортка, прокрутка, стани вибору
Наступна →
Bendgate: коли «тонкість» перетворилася на гарантійний кошмар

Залишити коментар