Good

WireGuard — поглиблений гайд

WireGuard — сучасний VPN протокол, що поєднує простоту, швидкість та безпеку. Цей гайд розглядає просунуті аспекти: криптографію, mesh топології, оптимізацію та troubleshooting.

💡 Чому це важливо для UMTC?
WireGuard — основа мережевої інфраструктури UMTC: - **Mesh VPN** між усіма нодами - **Доступ до внутрішніх сервісів** через VPN - **Зв'язок між LTE точками** та центральними серверами

Чому WireGuard?

Порівняння з іншими VPN

Аспект WireGuard OpenVPN IPsec
Код ~4000 рядків ~100000 ~400000
Швидкість Найвища Середня Висока
Криптографія Сучасна, фіксована Налаштовується Налаштовується
Аудит Простий Складний Дуже складний
Handshake 1 RTT 2+ RTT Багато RTT
Statefulness Stateless Stateful Stateful

Переваги WireGuard

mindmap
  root((WireGuard))
    Простота
      Мінімальна конфігурація
      Легкий troubleshooting
      4000 рядків коду
    Швидкість
      Kernel module
      ChaCha20 на ARM
      ~1 Gbps на RPi4
    Безпека
      Сучасна криптографія
      Криптографічна маршрутизація
      Немає legacy алгоритмів
    Roaming
      Auto reconnect
      WiFi ↔ LTE
      Stateless design

Криптографія

Noise Protocol Framework

WireGuard використовує Noise_IK handshake — лише 1 RTT (порівняно з 2+ RTT для TLS):

sequenceDiagram
    participant I as 🔑 Initiator
    participant R as 🔑 Responder

    I->>R: Handshake Initiation
    Note over I,R: ephemeral_pub, encrypted_static,<br/>encrypted_timestamp, MAC

    R->>I: Handshake Response
    Note over I,R: ephemeral_pub, encrypted_nothing, MAC

    Note over I,R: 🔐 Symmetric keys derived<br/>(ChaCha20-Poly1305)

    I->>R: Encrypted Data
    R->>I: Encrypted Data
    Note over I,R: Захищений двосторонній канал

Криптографічні примітиви

Примітив Використання
Curve25519 ECDH для обміну ключами
ChaCha20 Симетричне шифрування
Poly1305 Автентифікація (MAC)
BLAKE2s Хешування
HKDF Деривація ключів
# Всі примітиви — сучасні та швидкі
# Особливо ChaCha20-Poly1305 на ARM без AES-NI

# Benchmark на MikroTik hAP ax3:
# AES-GCM:  ~300 Mbps
# ChaCha20: ~500 Mbps

Ключі

# Генерація ключів
wg genkey > private.key
wg pubkey < private.key > public.key

# Або одним рядком
wg genkey | tee private.key | wg pubkey > public.key

# Pre-shared key (додатковий захист)
wg genpsk > psk.key

Private key — 32 байти Curve25519 scalar
Public key — 32 байти Curve25519 point
Pre-shared key — 32 байти симетричний ключ (опціонально)

Криптографічна маршрутизація (Cryptokey Routing)

Унікальна особливість WireGuard — AllowedIPs працює одночасно як таблиця маршрутизації (для вихідних) та ACL (для вхідних):

flowchart TB
    subgraph outgoing["Вихідний пакет до 192.168.2.100"]
        OUT1["1️⃣ Шукаємо peer<br/>AllowedIPs містить 192.168.2.100"]
        OUT2["2️⃣ Шифруємо<br/>public key peer"]
        OUT3["3️⃣ Відправляємо<br/>на endpoint peer"]
        OUT1 --> OUT2 --> OUT3
    end

    subgraph incoming["Вхідний пакет"]
        IN1["1️⃣ Дешифруємо<br/>визначаємо peer"]
        IN2["2️⃣ Перевіряємо<br/>source IP в AllowedIPs?"]
        IN3{"✅ Так"}
        IN4{"❌ Ні"}
        IN5["ACCEPT"]
        IN6["DROP"]
        IN1 --> IN2
        IN2 --> IN3 --> IN5
        IN2 --> IN4 --> IN6
    end

    style outgoing fill:#dbeafe
    style incoming fill:#fef3c7

Приклад конфігурації

[Peer]
PublicKey = ABC123...
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24
ℹ️ AllowedIPs = routing + security
- **Routing**: пакети на `10.0.0.2` або `192.168.2.0/24` шифруються цим peer - **Security**: вхідні пакети від peer можуть мати тільки ці source IP

Mesh топологія

Full Mesh

flowchart TB
    A["🖥️ Node A<br/>10.0.0.1"]
    B["🖥️ Node B<br/>10.0.0.2"]
    C["🖥️ Node C<br/>10.0.0.3"]

    A <-->|"WireGuard"| B
    B <-->|"WireGuard"| C
    A <-->|"WireGuard"| C

    style A fill:#dbeafe
    style B fill:#d1fae5
    style C fill:#fef3c7
Metric Full Mesh
З'єднання N(N-1)/2
3 nodes 3 з'єднання
10 nodes 45 з'єднань
💡 Переваги Full Mesh
- **Оптимальна затримка** — напряму між нодами - **Немає SPOF** — відмова одного не впливає на інших
⚠️ Недоліки
- **O(n²) конфігурація** — кожен з кожним - **Не масштабується** — 100 nodes = 4950 з'єднань

Hub and Spoke

flowchart TB
    HUB["🏢 Hub<br/>10.0.0.1"]
    A["📱 Spoke A<br/>10.0.0.2"]
    B["📱 Spoke B<br/>10.0.0.3"]
    C["📱 Spoke C<br/>10.0.0.4"]

    HUB <--> A
    HUB <--> B
    HUB <--> C

    style HUB fill:#ef4444,color:#fff
    style A fill:#dbeafe
    style B fill:#d1fae5
    style C fill:#fef3c7
Metric Hub and Spoke
З'єднання N-1
Масштабування Легке
SPOF Hub
💡 Переваги Hub and Spoke
- **Проста конфігурація** — тільки hub знає всіх - **Масштабується** — додати spoke = 1 peer - **Централізований контроль** — фільтрація на hub
⚠️ Недоліки
- **Трафік через hub** — додаткова затримка - **Single Point of Failure** — hub падає = мережа падає

Приклад mesh на MikroTik

# Node A (Hub): 10.0.0.1, public IP 203.0.113.1

/interface wireguard add listen-port=51820 name=wg0 private-key="<A_PRIVATE>"
/interface wireguard peers
add allowed-address=10.0.0.2/32,192.168.2.0/24 interface=wg0 \
    public-key="<B_PUBLIC>" endpoint-address=203.0.113.2 endpoint-port=51820
add allowed-address=10.0.0.3/32,192.168.3.0/24 interface=wg0 \
    public-key="<C_PUBLIC>" endpoint-address=203.0.113.3 endpoint-port=51820
/ip address add address=10.0.0.1/24 interface=wg0

# Маршрути до мереж за nodes
/ip route add dst-address=192.168.2.0/24 gateway=wg0
/ip route add dst-address=192.168.3.0/24 gateway=wg0

AllowedIPs детально

Як працює

AllowedIPs = 10.0.0.2/32, 192.168.2.0/24

Означає:
1. ВИХІДНІ пакети на 10.0.0.2 або 192.168.2.0/24
   → шифруються цим peer
2. ВХІДНІ пакети від цього peer
   → можуть мати source IP тільки з цих діапазонів

Типові значення

# Тільки peer IP (point-to-point)
AllowedIPs = 10.0.0.2/32

# Peer + мережа за ним
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24

# Весь трафік через peer (VPN gateway)
AllowedIPs = 0.0.0.0/0, ::/0

# Декілька мереж
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24, 172.16.0.0/16

Split Tunnel vs Full Tunnel

flowchart LR
    subgraph split["Split Tunnel"]
        C1["👤 Client"]
        VPN1["🔒 WireGuard<br/>10.0.0.0/24"]
        INET1["🌐 Internet<br/>напряму"]
        C1 -->|"internal"| VPN1
        C1 -->|"youtube, google"| INET1
    end

    subgraph full["Full Tunnel"]
        C2["👤 Client"]
        VPN2["🔒 WireGuard<br/>0.0.0.0/0"]
        INET2["🌐 Internet"]
        C2 --> VPN2 --> INET2
    end

    style split fill:#d1fae5
    style full fill:#dbeafe
Аспект Split Tunnel Full Tunnel
AllowedIPs 10.0.0.0/24, ... 0.0.0.0/0
Інтернет Напряму Через VPN
Навантаження Менше Більше
Приватність Часткова Повна
UMTC рекомендація Для спец. випадків

PersistentKeepalive

Навіщо потрібен?

sequenceDiagram
    participant A as 📱 Peer A<br/>(за NAT)
    participant NAT as 🔀 NAT Router
    participant B as 🖥️ Peer B<br/>(public IP)

    A->>NAT: Пакет до B
    Note over NAT: Створює запис<br/>в NAT table
    NAT->>B: Forward
    B->>NAT: Відповідь
    NAT->>A: Forward (є запис)

    Note over NAT: ⏰ 60-300 сек без трафіку
    Note over NAT: ❌ Запис видалено!

    B--xNAT: Не може достукатись
    Note over B: Зв'язок втрачено
⚠️ Проблема NAT
NAT таблиця очищається через 60-300 секунд без трафіку. Якщо Peer B захоче відправити пакет — NAT його заблокує.

Рішення: PersistentKeepalive = 25 — кожні 25 секунд відправляється keepalive пакет, NAT запис оновлюється.

Коли використовувати?

# Потрібен якщо:
# - Peer за NAT
# - Peer ініціює з'єднання ззовні (сервер хоче достукатись до клієнта)
# - Нестабільна мережа

# НЕ потрібен якщо:
# - Обидва peer з public IP
# - Клієнт завжди ініціює з'єднання сам
# - Постійний трафік в обидва боки

# MikroTik
/interface wireguard peers set [find] persistent-keepalive=25

# Linux
[Peer]
PersistentKeepalive = 25

MTU оптимізація

Проблема фрагментації

flowchart LR
    subgraph overhead["WireGuard Overhead"]
        IP["IPv4: 20 bytes"]
        UDP["UDP: 8 bytes"]
        WG["WireGuard: 32 bytes"]
        TOTAL["Total: 60 bytes"]
    end

    ETH["Ethernet MTU<br/>1500 bytes"] --> WG_MTU["WireGuard MTU<br/>1500 - 60 = 1440"]
    WG_MTU --> PPPOE["З PPPoE<br/>1440 - 8 = 1432"]

    style overhead fill:#fee2e2
Сценарій MTU
Ethernet 1500
WireGuard 1440
WireGuard + PPPoE 1432
Safe default 1420
🚨 Що буде якщо MTU занадто великий?
flowchart LR
    PKT["📦 1500 byte packet"]
    WG["🔒 WireGuard<br/>+60 bytes"]
    BIG["📦 1560 bytes"]
    FRAG["⚠️ Fragmentation"]
    DROP["❌ DROP (DF=1)"]

    PKT --> WG --> BIG
    BIG --> FRAG
    BIG --> DROP
**Симптоми:** - Ping працює, але великі файли не передаються - SSH підключається, але висить - Веб-сторінки завантажуються частково

Рішення

# MikroTik — встановити MTU на WireGuard інтерфейсі
/interface wireguard set wg0 mtu=1420

# Linux
ip link set wg0 mtu 1420

# Або в конфізі
[Interface]
MTU = 1420

# Визначити оптимальний MTU
ping -M do -s 1400 10.0.0.1  # Збільшувати поки не буде fragmented

MSS Clamping (альтернатива)

# MikroTik — змінювати MSS в TCP пакетах
/ip firewall mangle add chain=forward protocol=tcp \
    tcp-flags=syn in-interface=wg0 \
    action=change-mss new-mss=clamp-to-pmtu

# Або фіксоване значення
action=change-mss new-mss=1380

NAT Traversal

Проблема подвійного NAT

flowchart TB
    A["📱 Peer A<br/>192.168.1.x"]
    NAT_A["🔀 NAT A"]
    INET["🌐 Internet"]
    NAT_B["🔀 NAT B"]
    B["📱 Peer B<br/>192.168.2.x"]

    A --- NAT_A
    NAT_A --- INET
    INET --- NAT_B
    NAT_B --- B

    A -.->|"❓"| B

    style A fill:#fee2e2
    style B fill:#fee2e2

Проблема: Жоден не має public IP — як з'єднатись?

Рішення

  1. Один peer з public IP (рекомендовано)
    Peer A (NAT) → Peer B (public) — працює

  2. UDP Hole Punching (складно)
    Потрібен STUN сервер для координації Не завжди працює (symmetric NAT)

  3. Relay сервер
    Peer A → Relay (public) → Peer B Завжди працює, але затримка

Моніторинг та дебаг

Linux

# Статус інтерфейсу
wg show

# Детальніше
wg show wg0

# interface: wg0
#   public key: ABC...
#   private key: (hidden)
#   listening port: 51820
#
# peer: XYZ...
#   endpoint: 203.0.113.1:51820
#   allowed ips: 10.0.0.2/32
#   latest handshake: 15 seconds ago
#   transfer: 1.5 MiB received, 2.3 MiB sent

# Перевірити handshake
# "latest handshake" має бути < 2 хвилини
# Якщо "never" — peer недоступний

MikroTik

# Статус peers
/interface wireguard peers print detail

# Rx/Tx лічильники
/interface wireguard peers print stats

# Моніторинг в реальному часі
/interface wireguard peers monitor [find]

# Логи
/system logging add topics=wireguard action=memory
/log print where topics~"wireguard"

Типові проблеми

Проблема: "latest handshake: never"
Причина:
- Неправильний endpoint
- Firewall блокує UDP
- Неправильні ключі
Рішення:
- Перевірити ping до endpoint
- Відкрити UDP port
- Перегенерувати ключі

Проблема: Handshake є, але немає трафіку
Причина:
- AllowedIPs не включає потрібні мережі
- Немає маршрутів
- Firewall на peer
Рішення:
- Перевірити AllowedIPs
- Додати маршрути
- Перевірити firewall

Проблема: Періодичні обриви
Причина:
- NAT timeout
- Нестабільний endpoint
Рішення:
- Додати PersistentKeepalive=25
- Перевірити мережу

MikroTik особливості

Firewall для WireGuard

# Дозволити WireGuard (UDP 51820)
/ip firewall filter add chain=input protocol=udp dst-port=51820 action=accept \
    comment="WireGuard"

# Дозволити трафік з wg інтерфейсу (якщо потрібно)
/ip firewall filter add chain=input in-interface=wg0 action=accept \
    comment="WireGuard tunnel traffic"

# Forward між WireGuard та LAN
/ip firewall filter add chain=forward in-interface=wg0 out-interface=bridge-lan action=accept
/ip firewall filter add chain=forward in-interface=bridge-lan out-interface=wg0 action=accept

DDNS (динамічний endpoint)

# Якщо peer не має статичного IP
# Використовувати доменне ім'я в endpoint

# MikroTik Cloud DDNS
/ip cloud set ddns-enabled=yes

# Отримати ім'я
/ip cloud print
# dns-name: abc123.sn.mynetname.net

# На іншому peer:
endpoint-address=abc123.sn.mynetname.net

Резервування (failover)

# Створити два WireGuard інтерфейси
/interface wireguard add name=wg-primary ...
/interface wireguard add name=wg-backup ...

# Налаштувати routing з distance
/ip route add dst-address=10.0.0.0/24 gateway=wg-primary distance=1
/ip route add dst-address=10.0.0.0/24 gateway=wg-backup distance=2

# Netwatch для перевірки
/tool netwatch add host=10.0.0.1 interval=10s \
    down-script="/ip route disable [find gateway=wg-primary]" \
    up-script="/ip route enable [find gateway=wg-primary]"

Безпека та hardening

# 1. Використовувати PSK для постквантової безпеки
wg genpsk > psk.key
# Додати до обох peers

# 2. Обмежити AllowedIPs
# НЕ використовувати 0.0.0.0/0 якщо не потрібно

# 3. Firewall — дозволяти тільки потрібний трафік
/ip firewall filter add chain=forward in-interface=wg0 \
    dst-address=192.168.1.0/24 dst-port=22,80,443 protocol=tcp action=accept

# 4. Приховати private key
# Ніколи не показувати в логах
# Зберігати в захищеному місці

# 5. Регулярно оновлювати RouterOS
/system package update check-for-updates

Пов'язані теми

Шлях: networking/vpn/wireguard-advanced.md

UMTC Wiki © 2026 | Ukrainian Military Tactical Communications