Публічна IP-адреса кожного VPS видима всьому інтернету, і порти баз даних, Redis та внутрішніх API доводиться закривати правилами firewall вручну на кожному сервері. WireGuard mesh вирішує це інакше: сервери отримують приватні адреси в окремій підмережі 10.x.x.x, трафік між ними шифрується на льоту, а порти внутрішніх сервісів можна взагалі не відкривати назовні.
Навіщо потрібна приватна мережа між VPS
Коли застосунок і база даних живуть на різних серверах, з'єднання між ними за замовчуванням іде через публічний інтернет. Навіть із паролем і TLS це зайва поверхня атаки: сканери знаходять відкритий порт 5432 чи 6379 за хвилини. Приватна мережа прибирає цю проблему — сервіс слухає тільки адресу 10.10.0.x, а публічний інтерфейс порт узагалі не відкриває.
Другий привід — об'єднати сервери в різних дата-центрах і навіть у різних провайдерів в одну логічну мережу. WireGuard працює поверх звичайного UDP, тому йому байдуже, розташовані вузли в одному дата-центрі Hetzner чи в різних країнах: важлива тільки доступність порту 51820 між ними.
Mesh чи hub-and-spoke: яку топологію обрати
Повнозв'язна mesh-мережа
Кожен вузол зберігає публічні ключі всіх інших і тримає з ними прямий тунель. Трафік між будь-якими двома серверами йде найкоротшим шляхом, без проміжних вузлів. Ціна — конфігурація зростає квадратично: для 5 серверів потрібно налаштувати 10 пар ключів, для 10 — уже 45.
Топологія hub-and-spoke через один вузол
Усі сервери підключаються тільки до одного центрального вузла, а він маршрутизує трафік між ними. Конфігурація кожного peer однакова і не змінюється при додаванні нових вузлів, але центральний сервер стає точкою відмови і вузьким місцем за пропускною здатністю.
| Критерій | Mesh | Hub-and-spoke |
|---|---|---|
| Затримка між вузлами | Мінімальна, напряму | Через центральний вузол |
| Точка відмови | Немає єдиної точки | Центральний вузол — SPOF |
| Складність конфігурації | Зростає квадратично | Постійна для будь-якого числа вузлів |
| Підходить для числа серверів | До 10-15 | Більше 15 |
Встановлення WireGuard на серверах
Модуль WireGuard входить до ядра Linux починаючи з версії 5.6, а пакет wireguard-tools встановлюється однією командою на всіх сучасних дистрибутивах.
apt update && apt install -y wireguard
umask 077
wg genkey | tee privatekey | wg pubkey > publickey
cat privatekey
Пару ключів потрібно згенерувати на кожному вузлі окремо — приватний ключ ніколи не залишає свій сервер, між вузлами передаються тільки публічні ключі.
Конфігурація mesh на трьох вузлах
Файл /etc/wireguard/wg0.conf на першому вузлі описує власну адресу в приватній підмережі і по одній секції [Peer] на кожен інший вузол мережі.
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = <приватний ключ вузла 1>
[Peer]
PublicKey = <публічний ключ вузла 2>
Endpoint = 203.0.113.2:51820
AllowedIPs = 10.10.0.2/32
PersistentKeepalive = 25
PersistentKeepalive обов'язковий, якщо хоча б один із вузлів сидить за NAT — без нього тунель розривається через декілька хвилин простою. Після правки конфігурації на всіх трьох вузлах інтерфейс піднімається однією командою.
systemctl enable --now wg-quick@wg0
wg show wg0
Маршрутизація і firewall для приватної підмережі
Щойно інтерфейс wg0 піднято на всіх вузлах, сервіси можна перевести на прослуховування приватної адреси замість 0.0.0.0. Postgres, Redis і внутрішні API налаштовуються на bind-адресу 10.10.0.x, а правило firewall відкриває порт тільки для підмережі 10.10.0.0/24, а не для всього інтернету.
Сервери для mesh-мережі зручно піднімати одразу з потрібним набором мережевих інтерфейсів — наприклад, через API Hetzner Cloud, де приватна мережа між VPS налаштовується на етапі створення. Поверх готового mesh-тунелю вже можна ставити Consul для service discovery — агенти спілкуватимуться за адресами 10.10.0.x, не залежачи від зміни публічних IP.
Діагностика: перевірка з'єднання між вузлами
Коли пінг між приватними адресами не проходить, порядок діагностики майже завжди однаковий.
- wg show wg0 — перевірити, що в обох вузлів ненульовий latest handshake, а не тільки налаштований peer.
- Чи відкритий порт 51820/udp у firewall провайдера і в iptables/nftables на самому сервері.
- Чи збігаються публічні ключі в конфігурації peer із реальними ключами сусіднього вузла — помилка в ключі не дає жодної помилки програми, просто handshake не проходить.
- AllowedIPs вказує саме на потрібну підмережу, а не перекриває 0.0.0.0/0 і не веде через себе весь трафік вузла.