Tropic Host

Настройка WireGuard Site-to-Site на KVM VPS: объединение филиалов, офисов и облачных серверов в L3-сеть

33 мин чтения
Tropic

Краткий вывод: Для развертывания производительного Site-to-Site L3-транзита между филиальными офисами через центральный концентратор WireGuard на KVM VPS требуется инстанс минимум с 2 vCPU (без оверселлинга, %st = 0.0%), 2 ГБ RAM, 25 ГБ серверного NVMe (IOPS 4K QD1 $\ge$ 15 000) и сетевым интерфейсом 1 Гбит/с. Ядерный модуль Linux wireguard.ko (ChaCha20-Poly1305, Curve25519) обеспечивает сквозной throughput до 850–920 Мбит/с при задержке p99 < 3 мс, требуя фиксации туннельного MTU на уровне 1420 байт, активации алгоритма congestion control fq + bbr и включения форвардинга пакетов через net.ipv4.ip_forward = 1. Изоляция и маршрутизация трафика локальных подсетей реализуются напрямую через директивы AllowedIPs и таблицы ядра (ip route, policy routing) либо посредством динамической оверлейной маршрутизации BGP (FRRouting) без криптографического оверхенда, характерного для устаревших IPsec/OpenVPN.


Содержание

  1. Топология Site-to-Site сети: Hub-and-Spoke против Full-Mesh через VPS
  2. Подготовка Linux VPS: включение IP Forwarding, BBR и расчет MTU
  3. Генерация ключей и настройка конфигурации wg0.conf на центральном VPS
  4. Настройка офисных шлюзов (MikroTik, Keenetic, Linux) и статических маршрутов
  5. Отказоустойчивость, PersistentKeepalive и обход NAT провайдеров
  6. Мониторинг задержек, аудит безопасности и регламент Disaster Recovery
  7. Часто задаваемые вопросы (FAQ)

Топология Site-to-Site сети: Hub-and-Spoke против Full-Mesh через VPS

Построение отказоустойчивой топологии WireGuard Site-to-Site между офисами через VPS упирается в архитектурные ограничения криптографической маршрутизации (Cryptokey Routing) ядра Linux и физическую топологию каналов последней мили. В отличие от классических протоколов динамической маршрутизации (OSPF, BGP поверх GRE/IPsec), где интерфейс туннеля работает как виртуальный кабель point-to-point, в интерфейсе wireguard.ko маршрутизация жестко привязана к открытым ключам пиров через директиву AllowedIPs. Это фундаментально меняет поведение трафика при масштабировании филиальной сети.

Архитектурные модели: Hub-and-Spoke, Full-Mesh и P2P-координация

При проектировании корпоративной WAN-сети между $N$ филиалами инженер выбирает между тремя схемами транзита:

    HUB-AND-SPOKE (Звезда через VPS)                 FULL-MESH (Полносвязная сеть)

           [ VPS Hub ]                                [ Branch A ]
         (tropic.host KVM)                           /            \
          /      |      \                           /              \
         /       |       \                   [ Branch B ] ──── [ Branch C ]
   [ Spoke A ] [ Spoke B ] [ Spoke C ]              \              /
   (Office 1)  (Office 2)  (Office 3)                \            /
                                                      [ Branch D ]
   Сложность: O(N) туннелей                   Сложность: O(N²) туннелей
   NAT-T: Требуется 1 публичный IP (VPS)      NAT-T: Публичный IP на каждом узле

1. Hub-and-Spoke (Звезда с транзитным узлом)

Центральный облачный сервер выступает маршрутизатором ядра (Core Gateway). Каждый филиальный шлюз (CPE — Customer Premises Equipment на базе Linux, RouterOS или pfSense) поднимает единственный постоянный туннель к VPS. * Механика прохождения NAT (NAT-Traversal): Шлюзам филиалов не требуются статические белые IPv4-адреса. Достаточно директивы PersistentKeepalive = 25, удерживающей сессию в таблицах трансляции провайдерского CGNAT (Carrier-Grade NAT). Единственный статический адрес размещается на VPS. * Трафик между филиалами (Hairpinning/Tromboning): Пакет из сети 192.168.10.0/24 (Филиал А), адресованный в 192.168.20.0/24 (Филиал Б), приходит на сетевой интерфейс wg0 сервера VPS, деинкапсулируется ядром, проходит через цепочку FORWARD межсетевого экрана и повторно шифруется ключом Филиала Б для отправки обратно в сокет через тот же физический интерфейс. * Накладные расходы по задержке: RTT между офисами равен сумме задержек: $$RTT_{A \to B} = RTT_{A \to Hub} + RTT_{Hub \to B} + \Delta_{proc}$$ где $\Delta_{proc}$ — время контекстного переключения и криптографической обработки в софт-прерываниях (ksoftirqd).

2. Full-Mesh (Полносвязная матрица)

Каждый филиал держит прямые туннели со всеми остальными филиалами. * Взрывной рост сложности конфигурации: Число туннелей в сети растет квадратично: $$C = \frac{N(N - 1)}{2}$$ Для 4 офисов требуется 6 соединений, для 12 филиалов — уже 66 независимых пирингов. Изменение подсети за одним из шлюзов требует синхронного обновления AllowedIPs на всех $N-1$ маршрутизаторах. * Проблема симметричного NAT: Если оба филиала находятся за провайдерским Symmetric NAT, прямое P2P-соединение через стандартный UDP Hole Punching невозможно без промежуточного STUN/TURN/DERP-реле, что нивелирует преимущества чистой P2P-архитектуры и возвращает трафик к релейному узлу. * Преимущество: Минимальная сетевая задержка (пакет идет по кратчайшему BGP-маршруту между провайдерами) и отсутствие единой точки отказа (SPOF) для плоскости данных (Data Plane).


Сравнительный анализ топологий для распределенной инфраструктуры

Технический критерий Hub-and-Spoke (Транзитный VPS) Full-Mesh (Чистый P2P) Гибрид (Mesh + VPS Relay/Control)
Количество туннелей на филиал $1$ соединение $N - 1$ соединений Динамически (1 базовый + по требованию)
Общее число соединений в сети $N$ $\frac{N(N - 1)}{2}$ $N$ базовых + $k$ активных прямых
Требования к IP филиалов Серый динамический IP / CGNAT Статический белый IP на каждом CPE Допускается CGNAT (нужен STUN/ICE координатор)
Штраф по задержке (Latency p99) Зависит от RTT до VPS (+5–25 мс) Минимальный (физический RTT провайдеров) Минимальный для P2P, штраф при ретрансляции
Требования к полосе центрального узла $\sum \text{Bandwidth}_{\text{inter-site}} \times 2$ 0 (центральный узел отсутствует) Только сигнальный трафик + fallback релей
Сложность cryptokey routing Низкая (агрегация маршрутов на Hub) Экспоненциальная при росте $N$ Высокая (требуется автоматизация Tailscale/NetBird)
Централизованный инспекшн (IDS/IPS) Нативный (зеркалирование/Suricata на VPS) Невозможен без перенаправления потоков Ограничен только ретранслируемым трафиком
Отказоустойчивость Отказ VPS изолирует межфилиальный обмен Отказ узла изолирует только этот узел Деградация до Hub при сбое P2P-согласования

Реализация Hub-and-Spoke: hairpinning и маршрутизация в ядре Linux

Для корректной работы транзитной схемы на базе VPS требуется исключить дропы пакетов на уровне ядра при прохождении одного и того же сетевого интерфейса (wg0 $\to$ wg0).

1. Системные флаги ядра (/etc/sysctl.d/99-wireguard-hub.conf)

# Разрешение транзитной маршрутизации IPv4 и IPv6
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

# Запрет отправки ICMP Redirects (критично для hairpinning, предотвращает раскрытие топологии)
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.wg0.send_redirects = 0

# Защита от спуфинга с сохранением асимметричной маршрутизации (loose mode)
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.wg0.rp_filter = 2

# Оптимизация очередей сетевого стека для минимизации джиттера при пиковых нагрузках
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.core.netdev_max_backlog = 16384

Применение параметров без перезагрузки:

sysctl --system

2. Конфигурация интерфейса центрального шлюза (/etc/wireguard/wg0.conf на VPS)

На транзитном сервере каждый пир объявляет в AllowedIPs не только свой внутритуннельный адрес /32, но и всю локальную подсеть филиала. Ядро использует эту директиву для наполнения внутренней хэш-таблицы маршрутизации WireGuard.

[Interface]
Address = 10.100.0.1/24
ListenPort = 51820
PrivateKey = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=

# Защита от фрагментации пакетов внутри туннеля (1500 - 20 байт IPv4 - 8 байт UDP - 32 байта WG)
MTU = 1420

# Активация транзитного пакетного фильтра nftables при старте интерфейса
PostUp = nft add table inet wg_filter; \
         nft add chain inet wg_filter forward { type filter hook forward priority 0 \; policy drop \; }; \
         nft add rule inet wg_filter forward ct state established,related accept; \
         nft add rule inet wg_filter forward iifname "wg0" oifname "wg0" accept; \
         nft add rule inet wg_filter forward tcp flags syn tcp option maxseg size set rt mtu

PostDown = nft delete table inet wg_filter

# Филиал 1 (Office MSK: 192.168.10.0/24)
[Peer]
PublicKey = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb=
AllowedIPs = 10.100.0.10/32, 192.168.10.0/24

# Филиал 2 (Office SPB: 192.168.20.0/24)
[Peer]
PublicKey = cccccccccccccccccccccccccccccccccccccccccccc=
AllowedIPs = 10.100.0.20/32, 192.168.20.0/24

# Филиал 3 (Office KZN: 192.168.30.0/24)
[Peer]
PublicKey = dddddddddddddddddddddddddddddddddddddddddd=
AllowedIPs = 10.100.0.30/32, 192.168.30.0/24

3. Конфигурация шлюза филиала (/etc/wireguard/wg0.conf на CPE Филиала 1)

Шлюз филиала направляет трафик остальных корпоративных сетей в туннель:

[Interface]
Address = 10.100.0.10/24
PrivateKey = eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=
MTU = 1420

[Peer]
PublicKey = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=
# Публичный статический IPv4 адрес KVM-инстанса в tropic.host
Endpoint = 194.58.112.45:51820
# Маршрутизируем через VPS адресную емкость остальных офисов
AllowedIPs = 10.100.0.0/24, 192.168.20.0/24, 192.168.30.0/24
# Поддержание трансляции адресов в NAT таблице аплинка филиала каждые 25 сек
PersistentKeepalive = 25

Аппаратные требования к транзитному VPS: минимизация Steal Time и сетевой джиттер

В топологии Hub-and-Spoke транзитный узел становится критическим звеном инфраструктуры. Потоки трафика между офисами дважды нагружают физический сетевой интерфейс и стек софт-прерываний процессора (ksoftirqd/X). Шифрование потоков алгоритмом ChaCha20-Poly1305 требует прямого доступа к инструкциям AVX-512 / AVX2 без задержек планировщика гипервизора.

  1. Критерий отсутствия оверселлинга (%st = 0.0%):
    Любые задержки, вызванные переподпиской CPU на гипервизоре, приводят к мгновенному росту вариации задержки (джиттера) и раздуванию очередей сокетов. Если показатель CPU Steal Time в выводе mpstat -P ALL 1 или top превышает 0.1%, пакеты в кольцевых буферах сетевой карты начинают сбрасываться (drop counter в ethtool -S), что приводит к деградации p99 latency с номинальных 10–15 мс до 250–400 мс и падению пропускной способности TCP-сессий из-за постоянного срабатывания алгоритмов контроля перегрузок.
  2. Производительность дисковой подсистемы для логирования и метрик:
    При агрегации логов сетевых соединений (NetFlow, IPFIX, syslog потоков соединений) через ulogd2 требования к случайной записи блоками 4K достигают сотен мегабайт в секунду. Диски потребительского класса вызывают I/O wait блокировки ядра (%wa > 5%), затормаживая сетевой стек.

Развертывание центрального узла на облачной платформе tropic.host гарантирует честную аппаратную виртуализацию KVM с фиксированным выделением ресурсов на процессорах AMD EPYC / Ryzen 9 с нулевым CPU Steal Time (%st = 0.0%). NVMe-накопители корпоративного класса (PCIe 4.0) обеспечивают стабильные показатели свыше 50 000 IOPS на случайных операциях 4K QD1 без термического троттлинга.

Высокоскоростные аплинки 1–10 Гбит/с с активированным по умолчанию алгоритмом BBR и прямым BGP-пирингом на узлах обмена трафиком во Франкфурте, Амстердаме и Стамбуле исключают появление узких мест при транзите межфилиального трафика, а выделенный чистый IPv4 с аппаратной фильтрацией L3/L4 DDoS гарантирует непрерывность шифрованных туннелей между распределенными офисами.


Диагностика транзитного контура и мониторинг очередей

Проверка состояния каналов и прохождения трафика между сегментами выполняется на транзитном VPS:

# 1. Проверка актуального состояния хэш-таблицы маршрутизации WireGuard
wg show wg0

# 2. Мониторинг дропов в очередях софт-прерываний сетевого интерфейса
tc -s qdisc show dev wg0

# 3. Трассировка с фиксацией джиттера и потерь между филиалами
mtr --report-wide --aslookup --show-ips --curses -c 100 192.168.20.1

# 4. Проверка корректности работы Path MTU Discovery и MSS Clamping
tcpdump -nnvv -i wg0 'tcp[tcpflags] & tcp-syn != 0'

При правильно настроенном контуре трансляция пакетов 192.168.10.0/24 $\leftrightarrow$ 192.168.20.0/24 осуществляется ядром Linux без трансляции адресов (SNAT/MASQUERADE), сохраняя исходные IP-адреса хостов для сквозного аудита безопасности в корпоративной сети.

Подготовка Linux VPS: включение IP Forwarding, BBR и расчет MTU

Превращение инстанса Linux в высокопроизводительный транзитный шлюз для топологии Site-to-Site требует перевода сетевой подсистемы ядра из режима терминального узла (host) в режим маршрутизатора (router). По умолчанию дистрибутивы уровня Ubuntu 24.04 LTS и Debian 12 оптимизированы под обработку входящих сокетов локальных процессов: транзитные пакеты между интерфейсами отбрасываются на этапе прохождения цепочки PREROUTING $\rightarrow$ FORWARD, буферы сокетов ограничены дефолтными 212 КБ, а алгоритм контроля перегрузки TCP настроен на консервативный Cubic.

На облачной платформе tropic.host, где виртуализация KVM гарантирует нулевую процессорную задержку (%st = 0.0%), а физические сетевые адаптеры нод подключены к аплинкам 1–10 Гбит/с, узким местом при транзите шифрованного трафика становится исключительно конфигурация сетевого стека гостевой ОС.


1. Ядерный роутинг: IP Forwarding и Loose Reverse Path Filtering

Транзит пакетов между физическим интерфейсом (eth0) и виртуальным туннельным адаптером (wg0) блокируется ядром на уровне L3, если не активирован флаг транзитной пересылки. Для одновременной поддержки протоколов IPv4 и IPv6 активируются соответствующие директивы подсистемы net.ipv4 и net.ipv6.

Критический нюанс при построении Site-to-Site туннелей между филиалами — работа фильтра обратного пути (Reverse Path Filtering, rp_filter). В режиме строгой проверки (rp_filter = 1) ядро сверяет входящий интерфейс пакета с таблицей маршрутизации FIB (Forwarding Information Base). Если лучший обратный маршрут к IP-адресу источника указывает на другой интерфейс (асимметричная маршрутизация, характерная для multi-WAN каналов в офисах), ядро молча отбрасывает пакет со статусом martian destination:

# Проверка счетчика отброшенных марсианских пакетов в ядре
nstat -az IPReversePathFilter

Для исключения дропов транзитного офисного трафика фильтрация переводится в свободный режим (rp_filter = 2, Loose Mode), при котором ядро проверяет лишь принципиальное наличие маршрута к источнику через любой доступный интерфейс. Также отключается генерация ICMP-редиректов, предотвращающая раскрытие внутренней топологии сети и нестабильность внешних BGP/OSPF-демонов:

# Создание конфигурационного файла сетевого ядра
cat <<'EOF' > /etc/sysctl.d/99-wireguard-forwarding.conf
# Включение сквозной маршрутизации пакетов IPv4 и IPv6
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1

# Loose Reverse Path Filtering (защита от дропов при асимметричной маршрутизации)
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.eth0.rp_filter = 2

# Отключение отправки и приема ICMP Redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0

# Защита от спуфинга маршрутов и игнорирование фальшивых сообщений об ошибках
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
EOF

sysctl --system

2. Контроль перегрузки TCP BBR и сайзинг буферов под высокоскоростной транзит

Стандартный алгоритм Reno/Cubic трактует потерю пакетов (packet loss) как признак переполнения буфера промежуточного маршрутизатора и сбрасывает размер окна перегрузки (cwnd) вдвое. На глобальных транзитных WAN-каналах с задержкой $RTT > 30\text{ мс}$ (например, филиал в Стамбуле $\leftrightarrow$ VPS tropic.host во Франкфурте $\leftrightarrow$ филиал в Алматы) периодические случайные потери на L2 приводят к деградации пропускной способности TCP-сессий внутри туннеля до 10–15% от физической емкости линка.

Алгоритм BBR (Bottleneck Bandwidth and RTT) от Google абстрагируется от потерь пакетов, непрерывно вычисляя две физические метрики канала: 1. RTprop (Round-Trip Propagation Time): минимальное время прохождения пакета туда и обратно без учета стояния в очередях. 2. BtlBw (Bottleneck Bandwidth): реальную максимальную емкость самого узкого участка цепи.

BBR удерживает объем данных в полете равным произведению $BDP = BtlBw \times RTprop$, полностью ликвидируя буферблоат (Bufferbloat) и сокращая джиттер (p99 latency). Для работы BBR дисциплина очереди по умолчанию (pfifo_fast) заменяется на Fair Queueing (fq), которая выполняет аппаратный пейсинг (pacing) исходящих пакетов, размазывая пачки TCP по времени:

# Проверка поддержки модуля BBR ядром Linux
modprobe tcp_bbr
lsmod | grep bbr

Для прокачки 1 Гбит/с трафика при задержке $RTT = 50\text{ мс}$ требуется окно BDP:

$$\text{BDP} = \frac{10^9\text{ бит/с}}{8} \times 0.050\text{ с} = 6\,250\,000\text{ байт} \approx 6\text{ МБ}$$

Дефолтные лимиты памяти сокетов Linux (212 КБ) физически не позволят TCP-сессиям разогнаться свыше 33 Мбит/с на таком линке. Расширяем системные лимиты памяти до 64 МБ, параллельно увеличивая глубину очереди входящих пакетов сетевой карты (netdev_max_backlog) для исключения переполнения кольцевых буферов драйвера при всплесках трафика:

cat <<'EOF' > /etc/sysctl.d/99-network-performance.conf
# Активация алгоритма TCP BBR и дисциплины Fair Queueing
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# Максимальный размер буферов сокетов для всех протоколов (64 МБ)
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576

# Автотюнинг TCP-буферов: min, default, max (макс. 64 МБ)
net.ipv4.tcp_rmem = 4096 1048576 67108864
net.ipv4.tcp_wmem = 4096 1048576 67108864

# Длина очереди софтверных прерываний ksoftirqd при обработке пакетов
net.core.netdev_max_backlog = 16384

# Максимальное число открытых сокетов в очереди backlog ядра
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 16384

# Отключение сохранения метрик старых TCP-сессий в кэше ядра
net.ipv4.tcp_no_metrics_save = 1

# Быстрое повторное использование сокетов в состоянии TIME_WAIT
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
EOF

sysctl --system

Валидация применения параметров планировщика и алгоритма перегрузки:

sysctl net.ipv4.tcp_congestion_control net.core.default_qdisc
# Вывод должен содержать:
# net.ipv4.tcp_congestion_control = bbr
# net.core.default_qdisc = fq

3. Расчет накладных расходов WireGuard и математика MTU

WireGuard работает на сетевом уровне L3 модели OSI и инкапсулирует полезную нагрузку (клиентские IP-пакеты) в стандартные датаграммы протокола UDP. При прохождении через туннель к исходному пакету добавляются заголовки инкапсуляции и криптографическая подпись Poly1305.

Если размер суммарного пакета превысит физический MTU (Maximum Transmission Unit) внешнего интерфейса интернет-провайдера (стандартный Ethernet = 1500 байт), произойдет одно из двух деструктивных событий: 1. Фрагментация на уровне L3: внешний шлюз разделит зашифрованный UDP-пакет на две части. Нагрузка на сетевые процессоры маршрутизаторов возрастет втрое, а потеря хотя бы одного фрагмента приведет к дропу всей датаграммы WireGuard. 2. Тихий дроп (Blackhole): если в заголовке исходного пакета выставлен бит DF (Don't Fragment), а промежуточные узлы сети интернет-провайдера блокируют служебные сообщения ICMP Type 3 Code 4 («Destination Unreachable, Fragmentation Needed»), соединение зависнет на этапе передачи крупных данных (TLS Client Hello, передача файлов по SMB, SSH-сессии при выводе больших объемов текста).

Анатомия заголовков WireGuard над IPv4

Слой инкапсуляции Поле заголовка Размер (байт) Назначение
Внешний L3 IPv4 Header 20 Базовый заголовок внешнего IP-пакета (без IP Options)
Внешний L4 UDP Header 8 Порты источника и назначения WireGuard (дефолт: 51820)
WireGuard Type + Reserved 4 Тип сообщения (0x04 для транспортных данных) + нули
WireGuard Receiver Index 4 Идентификатор сессии удаленного пира в хэш-таблице
WireGuard Counter 8 64-битный счетчик пакетов для защиты от атак повтора (Replay)
WireGuard Poly1305 MAC 16 Аутентификационный тэг ChaCha20-Poly1305 (AEAD)
ИТОГО НАКЛАДНЫХ IPv4 Outer Header 56 Минимальный оверхед над чистым IPv4 каналом

Примечание по выравниванию: криптографический протокол Noise в WireGuard выравнивает размер зашифрованного payload до блоков, кратных 16 байтам. С учетом паддинга и безопасного запаса гарантированный оверхед составляет 60 байт для внешней сети IPv4 и 80 байт для внешней сети IPv6 (где базовый заголовок IPv6 фиксирован на уровне 40 байт).

Расчет рабочего MTU

  • При прямом подключении VPS с чистым Ethernet ($MTU = 1500$): $$MTU_{wg} = 1500 - 60 = 1440\text{ байт}$$
  • При подключении одного из офисов через протокол PPPoE (где 8 байт занимает заголовок туннеля провайдера, $MTU_{WAN} = 1492$): $$MTU_{wg} = 1492 - 60 = 1432\text{ байт}$$
  • В гетерогенных сетях со сложным стыком провайдеров (PPPoE + DS-Lite / Dual-Stack IPv6) эталонным промышленным стандартом является: $$MTU_{wg} = 1420\text{ байт}$$

Установка значения MTU = 1420 в секции [Interface] конфигурации wg0.conf исключает фрагментацию даже в случае, если внешний трафик туннеля идет через магистральные IPv6-маршруты.


4. Ликвидация MTU Blackhole через TCP MSS Clamping

Ограничение MTU на интерфейсе wg0 решает проблему только для локально генерируемого трафика. Однако рабочие станции в локальных сетях офисов (192.168.10.0/24 и 192.168.20.0/24) имеют собственные сетевые карты с дефолтным $MTU = 1500$. При инициализации TCP-соединения хосты отправляют пакет SYN, в заголовке которого указывается параметр MSS (Maximum Segment Size) — максимальный размер полезных данных TCP без учета заголовков:

$$MSS = MTU - 20\text{ (IP Header)} - 20\text{ (TCP Header)} = 1460\text{ байт}$$

Когда клиент из офиса A пытается передать серверу в офисе B пакет размером 1460 байт, транзитный VPS оборачивает его в заголовок WireGuard ($1460 + 40 + 60 = 1560\text{ байт}$). Пакет превышает физический MTU внешнего линка VPS ($1500$) и отбрасывается.

Для устранения этой проблемы на транзитном шлюзе настраивается динамическая перезапись заголовков TCP SYN — TCP MSS Clamping. Ядро принудительно перехватывает проходящие пакеты установки соединения и перезаписывает поле MSS, подгоняя его под размер туннеля ($1420 - 40 = 1380\text{ байт}$).

Реализация через современный фреймворк nftables

Начиная с ядер Linux 5.x+, фреймворк nftables является прямым преемником устаревшего iptables, выполняя операции в пространстве ядра с меньшим числом переключений контекста:

# Добавление правила MSS Clamping в таблицу mangle/forward
nft add table inet filter
nft add chain inet filter forward { type filter hook forward priority 0 \; policy accept \; }
nft add rule inet filter forward oifname "wg0" tcp flags syn / syn,rst tcp option maxseg size set rt mtu
nft add rule inet filter forward iifname "wg0" tcp flags syn / syn,rst tcp option maxseg size set rt mtu

Директива tcp option maxseg size set rt mtu динамически считывает значение MTU интерфейса назначения из ядра и вычитает 40 байт (IP + TCP заголовки).

Альтернативная реализация через iptables

Если в инфраструктуре используется legacy-стек правил:

# Автоматический расчет по Path MTU
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

# Либо жесткая фиксация MSS на уровне 1380 байт для интерфейса wg0
iptables -t mangle -A FORWARD -i wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380
iptables -t mangle -A FORWARD -o wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380

Проверка фиксации сегментов в проходящем трафике выполняется утилитой tcpdump:

tcpdump -nn -i wg0 'tcp[tcpflags] & (tcp-syn) != 0' -v
# В выводе значение MSS должно строго соответствовать расчетному:
# IP 192.168.10.15.48290 > 192.168.20.50.443: Flags [S], ... options [mss 1380, ...]

После применения данных настроек транзитный VPS готов к обработке высоконагруженных непрерывных потоков трафика между филиалами без потерь пакетов на пограничных стыках, буферных задержек и фрагментации.

Генерация ключей и настройка конфигурации wg0.conf на центральном VPS

При развертывании топологии WireGuard Site-to-Site между офисами на VPS центральный сервер выступает транзитным узлом (Hub), агрегирующим туннельные соединения от пограничных маршрутизаторов филиалов (Spokes). Архитектура WireGuard принципиально отличается от IPsec или OpenVPN: в ядре Linux модуль wireguard реализует концепцию Cryptokey Routing (маршрутизация по открытым ключам). Каждому открытому ключу пира в ядре жестко сопоставляется список разрешенных IP-адресов и префиксов (AllowedIPs), что объединяет функции криптографической аутентификации, пакетной фильтрации на уровне L3 и табличной маршрутизации.

Для обеспечения детерминированной пропускной способности при агрегации шифрованного трафика филиалов критически важна производительность транзитной ноды. Инфраструктура виртуализации KVM на платформе tropic.host гарантирует отсутствие кражи процессорного времени (CPU Steal Time %st = 0.0%) на процессорах AMD EPYC и Ryzen 9, что исключает микрозадержки при вычислении криптографических примитивов ChaCha20-Poly1305 и обработке очередей сетевых прерываний.


Подготовка криптографических материалов

Аутентификация в WireGuard базируется на асимметричной криптографии Curve25519 (ECDH). Дополнительно для защиты от будущих атак с применением квантовых компьютеров и предотвращения компрометации трафика при возможной утечке долговременных асимметричных ключей протокол поддерживает симметричные постквантовые предобщие ключи (Preshared Keys, PSK), добавляющие уровень симметричного шифрования.

Генерация ключей выполняется строго в изолированном каталоге с правами доступа 0700 для исключения перехвата приватных параметров непривилегированными процессами:

# Установка строгой маски создания файлов для текущей сессии
umask 077

# Создание рабочего каталога конфигураций WireGuard
mkdir -p /etc/wireguard
cd /etc/wireguard

# Генерация закрытого и открытого ключей центрального Hub-сервера
wg genkey | tee hub_private.key | wg pubkey > hub_public.key

# Генерация уникальных симметричных PSK для каждого филиала
wg genpsk > branch_spb.psk
wg genpsk > branch_almaty.psk
wg genpsk > branch_belgrade.psk

# Установка атомарных прав на файлы ключей
chmod 600 /etc/wireguard/*.key /etc/wireguard/*.psk

Публичные ключи филиалов генерируются на локальных шлюзах офисов аналогичным образом и передаются на центральный VPS по защищенному каналу.


Архитектура адресации и логика директивы AllowedIPs

В топологии Site-to-Site директива AllowedIPs на центральном VPS выполняет две неразрывные функции ядра:

  1. Входящая фильтрация (Crypto-Firewalling): При получении инкапсулированного UDP-пакета ядро расшифровывает его открытым ключом пира и сопоставляет внутренний адрес источника (Source IP) со списком AllowedIPs, зарегистрированным за этим ключом. Если Source IP пакета не входит в префиксы AllowedIPs данного пира, ядро немедленно отбрасывает пакет без генерации ICMP-ответов.
  2. Исходящая маршрутизация (Radix-Tree LPM Lookup): Когда ядро передает пакет в интерфейс wg0, модуль драйвера ищет IP-адрес назначения (Destination IP) в префиксном дереве (Longest Prefix Match). Найденная ветка однозначно определяет открытый ключ пира, которым должен быть зашифрован исходящий трафик.
[!IMPORTANT] В префиксном дереве WireGuard на одном интерфейсе префиксы не могут пересекаться между разными пирами. Если назначить одну и ту же локальную сеть (например, 192.168.1.0/24) в AllowedIPs двум филиалам, ядро свяжет маршрут только с тем пиром, который был добавлен последним, вызвав разрыв маршрутизации ко второму офису.

Для наглядного моделирования разберем сетевую схему объединения трех локальных подсетей через центральный KVM-сервер:

  • Инфраструктура Hub (VPS):
  • Внешний статический IPv4: 198.51.100.10
  • Overlay-интерфейс wg0: 10.100.0.1/24
  • Филиал 1 (Санкт-Петербург — branch_spb):
  • Overlay-адрес: 10.100.0.2/32
  • Локальная подсеть офиса: 192.168.10.0/24
  • Филиал 2 (Алматы — branch_almaty):
  • Overlay-адрес: 10.100.0.3/32
  • Локальная подсеть офиса: 192.168.20.0/24
  • Филиал 3 (Белград — branch_belgrade):
  • Overlay-адрес: 10.100.0.4/32
  • Локальная подсеть офиса: 192.168.30.0/24

Для каждого пира в секции [Peer] центрального VPS параметр AllowedIPs обязан содержать как туннельный /32 адрес маршрутизатора филиала, так и всю маршрутизируемую за ним локальную подсеть.


Формирование рабочей конфигурации /etc/wireguard/wg0.conf

Создайте файл /etc/wireguard/wg0.conf. Значения ключей подставляются из ранее сгенерированных файлов:

[Interface]
# Внутренний IP-адрес центрального концентратора в туннельной сети
Address = 10.100.0.1/24

# Фиксированный порт для прослушивания входящих UDP-дейтаграмм
ListenPort = 51820

# Закрытый ключ центрального сервера (содержимое /etc/wireguard/hub_private.key)
PrivateKey = WGlvX0h1YlByaXZhdGVLZXlFeGFtcGxlMTIzNDU2Nzg5MDE=

# Запрет утилите wg-quick перезаписывать файл при выключении интерфейса,
# что защищает ручные комментарии, форматирование и скрипты PostUp
SaveConfig = false

# Правила пакетного фильтра nftables при старте/останове туннеля:
# 1. Разрешение двунаправленного транзитного форвардинга через wg0
# 2. Нормализация TCP MSS под транспортный MTU 1420 байт (clamp-to-pmtu)
PostUp = nft add rule inet filter forward iifname "wg0" oifname "wg0" accept
PostUp = nft add rule inet filter forward iifname "wg0" tcp flags syn / syn,rst tcp option maxseg size set rt mtu
PostDown = nft delete rule inet filter forward iifname "wg0" oifname "wg0" accept 2>/dev/null || true
PostDown = nft delete rule inet filter forward iifname "wg0" tcp flags syn / syn,rst tcp option maxseg size set rt mtu 2>/dev/null || true

# ==============================================================================
# Пир: Филиал Санкт-Петербург (Шлюз офиса 1)
# ==============================================================================
[Peer]
# Публичный ключ шлюза СПб
PublicKey = c3BiX29mZmljZV9wdWJsaWNfa2V5X2V4YW1wbGVfMDEyMzQ1Njc=

# Дополнительный симметричный ключ квантовой защиты (branch_spb.psk)
PresharedKey = c3BiX3ByZXNoYXJlZF9rZXlfZXhhbXBsZV8wMTIzNDU2Nzg5MA==

# Криптографически авторизованные префиксы: туннельный хост + офисная LAN
AllowedIPs = 10.100.0.2/32, 192.168.10.0/24

# ПРИМЕЧАНИЕ: Параметр Endpoint здесь намеренно НЕ указывается. 
# Офисный шлюз находится за NAT провайдера. WireGuard автоматически 
# обновит IP и UDP-порт пира в таблице состояний при получении первого пакета.

# ==============================================================================
# Пир: Филиал Алматы (Шлюз офиса 2)
# ==============================================================================
[Peer]
PublicKey = YWxtYXR5X29mZmljZV9wdWJsaWNfa2V5X2V4YW1wbGVfMDEyMzQ=
PresharedKey = YWxtYXR5X3ByZXNoYXJlZF9rZXlfZXhhbXBsZV8wMTIzNDU2Nzg=
AllowedIPs = 10.100.0.3/32, 192.168.20.0/24

# ==============================================================================
# Пир: Филиал Белград (Шлюз офиса 3)
# ==============================================================================
[Peer]
PublicKey = YmVsZ3JhZGVfb2ZmaWNlX3B1YmxpY19rZXlfZXhhbXBsZV8wMTI=
PresharedKey = YmVsZ3JhZGVfcHJlc2hhcmVkX2tleV9leGFtcGxlXzAxMjM0NTY=
AllowedIPs = 10.100.0.4/32, 192.168.30.0/24

Установите права на созданную конфигурацию:

chmod 600 /etc/wireguard/wg0.conf

Анализ механизма Endpoint Discovery и NAT Traversal

В конфигурации wg0.conf центрального VPS для пиров отсутствует строка Endpoint = IP:PORT. Это ключевое архитектурное решение для взаимодействия филиалов, подключенных через динамические IP-адреса, CGNAT или стандартный офисный NAT:

  1. Центральный сервер на tropic.host имеет выделенный статический белый IPv4-адрес и слушает сокет 0.0.0.0:51820.
  2. Шлюзы филиалов инициируют рукопожатие (Handshake Initiation), отправляя UDP-пакеты на внешний сокет центрального VPS.
  3. Проходя через NAT пограничного роутера филиала, пакет получает динамический транслированный порт (Source NAT mapping).
  4. Получив и успешно расшифровав сообщение инициализации с помощью открытого ключа пира, модуль ядра wireguard на VPS извлекает публичный IP и порт отправителя из внешнего UDP-заголовка и автоматически сохраняет их в оперативной структуре состояния как текущий endpoint пира.
  5. Любой обратный трафик из других офисов, адресованный в эту подсеть, VPS направляет на динамически зарегистрированный сокет. Чтобы трансляция портов в stateful-таблицах промежуточных NAT-роутеров не сбрасывалась по таймауту неактивности, на стороне клиентских шлюзов офисов активируется параметр PersistentKeepalive = 25.

Активация интерфейса и верификация таблиц ядра

Запуск интерфейса выполняется через стандартную службу systemd:

# Включение автозагрузки и немедленный запуск wg0
systemctl enable --now wg-quick@wg0

# Проверка статуса демона
systemctl status wg-quick@wg0 --no-pager

Скрипт wg-quick при подъеме интерфейса считывает все подсети из директив AllowedIPs и автоматически инжектирует соответствующие статические маршруты в основную таблицу маршрутизации ядра (table main).

Проверьте сформированные маршруты в ядре:

ip route show dev wg0

Вывод команды должен содержать прямые связки целевых локальных сетей офисов с интерфейсом wg0:

10.100.0.0/24 proto kernel scope link src 10.100.0.1
192.168.10.0/24 scope link
192.168.20.0/24 scope link
192.168.30.0/24 scope link

Для глубокого инспектирования состояния туннеля и внутренних структур Cryptokey Routing ядра используйте утилиту wg:

wg show wg0

Диагностический вывод отображает рабочий статус интерфейса, криптографические ключи, зарегистрированные сокеты филиалов и объем переданных данных:

interface: wg0
  public key: WGlvX0h1YlB1YmxpY0tleUV4YW1wbGUxMjM0NTY3ODkwMTI=
  private key: (hidden)
  listening port: 51820

peer: c3BiX29mZmljZV9wdWJsaWNfa2V5X2V4YW1wbGVfMDEyMzQ1Njc=
  preshared key: (hidden)
  endpoint: 203.0.113.45:41289
  allowed ips: 10.100.0.2/32, 192.168.10.0/24
  latest handshake: 12 seconds ago
  transfer: 8.42 MiB received, 12.18 MiB sent

peer: YWxtYXR5X29mZmljZV9wdWJsaWNfa2V5X2V4YW1wbGVfMDEyMzQ=
  preshared key: (hidden)
  endpoint: 198.51.100.78:55120
  allowed ips: 10.100.0.3/32, 192.168.20.0/24
  latest handshake: 4 seconds ago
  transfer: 45.10 MiB received, 41.80 MiB sent

peer: YmVsZ3JhZGVfb2ZmaWNlX3B1YmxpY19rZXlfZXhhbXBsZV8wMTI=
  preshared key: (hidden)
  endpoint: 93.184.216.34:39811
  allowed ips: 10.100.0.4/32, 192.168.30.0/24
  latest handshake: 28 seconds ago
  transfer: 2.15 MiB received, 1.94 MiB sent

Если значение latest handshake превышает 2 minutes 30 seconds, либо поле endpoint отображается как (none), это свидетельствует о блокировке UDP-трафика на внешнем файрволе, некорректном публичном ключе или отсутствии инициализирующего трафика со стороны шлюза филиала. При корректных параметрах центральный VPS переходит в состояние прозрачной коммутации пакетов между пограничными маршрутизаторами локальных сетей.

Настройка офисных шлюзов (MikroTik, Keenetic, Linux) и статических маршрутов

Развертывание полносвязной топологии wireguard site to site между офисами через VPS требует разделения зон ответственности: центральный шлюз агрегирует криптографические ключи и маршруты, а филиальные пограничные маршрутизаторы отвечают за удержание трансляции состояний NAT (NAT keepalive), корректную фрагментацию пакетов и бестрансляционную маршрутизацию (No-NAT) между локальными сетями.

Поскольку большинство филиалов подключено через типовые провайдерские каналы без статических публичных IP-адресов либо находится за CGNAT (Carrier-Grade NAT), инициатором сессии всегда выступает локальный шлюз. Общими критическими параметрами для всех филиальных платформ являются:

  1. PersistentKeepalive = 25: отправка пустого аутентифицированного пакета каждые 25 секунд для удержания открытого UDP-сокета в таблице состояний промежуточных межсетевых экранов (conntrack).
  2. Расчет MTU и TCP MSS Clamping: инкапсуляция WireGuard добавляет 32 байта оверхеда (при транспорте IPv4: 20 байт IP + 8 байт UDP + 4 байта заголовок WireGuard Type 4 Data Packet + 16 байт Poly1305 Auth Tag = 60 байт накладных расходов). Для стандартного WAN MTU 1500 расчетный MTU = 1420. Если провайдер филиала использует PPPoE (WAN MTU 1492), значение MTU туннеля принудительно снижается до 1412. Максимальный размер сегмента TCP (TCP MSS) фиксируется на уровне MTU - 40 (1380 байт для MTU 1420), предотвращая отбрасывание фрагментированных пакетов транзитными маршрутизаторами.
  3. Исключение NAT для межфилиального трафика: пакеты между подсетями 192.168.10.0/24, 192.168.20.0/24 и 192.168.30.0/24 должны передаваться с сохранением оригинальных IP-адресов источника (Source IP), чтобы не нарушать сквозную аутентификацию в Active Directory, работу систем инвентаризации и SIEM.

1. Настройка филиального шлюза на базе Linux (Ubuntu / Debian / Rocky)

В сценарии, когда роль пограничного маршрутизатора филиала (например, Санкт-Петербург, LAN 192.168.10.0/24) выполняет сервер под управлением Linux, настройка интерфейса осуществляется через утилиту wg-quick либо systemd-networkd.

Конфигурация интерфейса (/etc/wireguard/wg0.conf)

[Interface]
Address = 10.100.0.2/24
PrivateKey = cHBiX29mZmljZV9wcml2YXRlX2tleV9leGFtcGxlXzAxMjM=
ListenPort = 51820
MTU = 1420

# Активация транзитной маршрутизации при подъеме интерфейса
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = sysctl -w net.ipv4.conf.all.rp_filter=2
PostUp = sysctl -w net.ipv4.conf.wg0.rp_filter=2

# Правила межсетевого экрана nftables: пропуск трафика и MSS Clamping
PostUp = nft add table ip wg_filter
PostUp = nft add chain ip wg_filter forward { type filter hook forward priority 0 \; policy accept \; }
PostUp = nft add rule ip wg_filter forward oifname "wg0" tcp flags syn tcp option maxseg size set 1380
PostDown = nft delete table ip wg_filter

[Peer]
# Центральный хаб на KVM VPS (tropic.host)
PublicKey = WGlvX0h1YlB1YmxpY0tleUV4YW1wbGUxMjM0NTY3ODkwMTI=
PresharedKey = dGhpcy1pcy1hLXNlY3VyZS1wcmVzaGFyZWQta2V5LTEyMw==
Endpoint = 198.51.100.1:51820
# Маршрутизируем адреса туннеля и локальные подсети удаленных филиалов
AllowedIPs = 10.100.0.0/24, 192.168.20.0/24, 192.168.30.0/24
PersistentKeepalive = 25

Параметр net.ipv4.conf.all.rp_filter = 2 (Loose Reverse Path Filter) является строго обязательным. По умолчанию ядро Linux использует строгий режим (rp_filter = 1), который отбрасывает транзитные пакеты из удаленных подсетей 192.168.x.0/24, если маршрут к источнику в FIB (Forwarding Information Base) ядра не ассоциирован жестко с входящим интерфейсом wg0.

Исключение межсетевого трафика из Masquerade в nftables

В основном файле правил /etc/nftables.conf локального шлюза правило маскарадинга для выхода в интернет дополняется исключением для локальных сетей филиалов:

table ip nat {
    chain postrouting {
        type nat hook postrouting priority 100; policy accept;

        # Запрет NAT между корпоративными подсетями
        ip saddr 192.168.10.0/24 ip daddr { 192.168.20.0/24, 192.168.30.0/24, 10.100.0.0/24 } accept

        # Стандартный NAT для клиентского доступа в WAN через eth0
        oifname "eth0" masquerade
    }
}

Активация сервиса и запуск туннеля:

systemctl enable --now wg-quick@wg0

Проверка сформированной таблицы маршрутизации ядра:

ip route show dev wg0
10.100.0.0/24 proto kernel scope link src 10.100.0.2 
192.168.20.0/24 scope link 
192.168.30.0/24 scope link 

2. Настройка шлюза MikroTik под управлением RouterOS v7

Начиная с RouterOS версии 7.1, поддержка WireGuard интегрирована непосредственно в ядро RouterOS. Рассматривается конфигурация шлюза филиала в Алматы (LAN 192.168.20.0/24, IP в туннеле 10.100.0.3/24).

Создание интерфейса и добавление пира

Выполните команды в терминале RouterOS CLI:

# Создание интерфейса WireGuard с корректным MTU
/interface wireguard
add listen-port=51820 mtu=1420 name=wg-tropic private-key="YWxtYXR5X29mZmljZV9wcml2YXRlX2tleV9leGFtcGxlXzAxMjM="

# Назначение туннельного IP-адреса
/ip address
add address=10.100.0.3/24 interface=wg-tropic network=10.100.0.0

# Регистрация центрального хаба
/interface wireguard peers
add allowed-address=10.100.0.0/24,192.168.10.0/24,192.168.30.0/24 \
    endpoint-address=198.51.100.1 endpoint-port=51820 \
    interface=wg-tropic persistent-keepalive=25s \
    preshared-key="dGhpcy1pcy1hLXNlY3VyZS1wcmVzaGFyZWQta2V5LTEyMw==" \
    public-key="WGlvX0h1YlB1YmxpY0tleUV4YW1wbGUxMjM0NTY3ODkwMTI="

Статическая маршрутизация подсетей

В RouterOS v7 механизм Cryptokey Routing требует явного указания маршрутов в системной таблице, направляющих трафик удаленных локальных сетей в созданный интерфейс wg-tropic:

/ip route
add disabled=no distance=1 dst-address=192.168.10.0/24 gateway=wg-tropic pref-src="" routing-table=main scope=30 target-scope=10
add disabled=no distance=1 dst-address=192.168.30.0/24 gateway=wg-tropic pref-src="" routing-table=main scope=30 target-scope=10

Настройка Firewall: No-NAT и MSS Clamping

Чтобы шлюз не применял action=masquerade к пакетам, идущим в сторону офисов в Санкт-Петербурге и Белграде, создается исключающее правило в самом начале цепочки srcnat:

# Исключение корпоративного трафика из трансляции адресов
/ip firewall nat
add action=accept chain=srcnat comment="Site-to-Site No-NAT" dst-address=192.168.0.0/16 place-before=0 src-address=192.168.20.0/24

# Разрешение прохождения транзитного трафика через туннель
/ip firewall filter
add action=accept chain=forward comment="Allow LAN to Site-to-Site" in-interface-list=LAN out-interface=wg-tropic place-before=1
add action=accept chain=forward comment="Allow Site-to-Site to LAN" in-interface=wg-tropic out-interface-list=LAN place-before=2

# Принудительное ограничение MSS для предотвращения фрагментации
/ip firewall mangle
add action=change-mss chain=forward comment="Clamp TCP MSS for WireGuard" new-mss=1380 out-interface=wg-tropic passthrough=yes protocol=tcp tcp-flags=syn tcp-mss=1381-65535

3. Настройка шлюза Keenetic (KeeneticOS)

Для филиала в Белграде (LAN 192.168.30.0/24, IP в туннеле 10.100.0.4/24) на маршрутизаторе Keenetic развертывание выполняется через встроенный CLI (доступный по SSH) либо через модуль веб-интерфейса.

Конфигурация туннеля через CLI KeeneticOS

(config)> interface Wireguard0
(config-if)> description "Hub-Tropic"
(config-if)> ip address 10.100.0.4 255.255.255.0
(config-if)> ip mtu 1420
(config-if)> wireguard listen-port 51820
(config-if)> wireguard private-key YmVsZ3JhZGVfb2ZmaWNlX3ByaXZhdGVfa2V5X2V4YW1wbGVfMDEy
(config-if)> wireguard peer WGlvX0h1YlB1YmxpY0tleUV4YW1wbGUxMjM0NTY3ODkwMTI=
(config-peer)> endpoint 198.51.100.1:51820
(config-peer)> keepalive-interval 25
(config-peer)> preshared-key dGhpcy1pcy1hLXNlY3VyZS1wcmVzaGFyZWQta2V5LTEyMw==
(config-peer)> allow-ips 10.100.0.0 255.255.255.0
(config-peer)> allow-ips 192.168.10.0 255.255.255.0
(config-peer)> allow-ips 192.168.20.0 255.255.255.0
(config-peer)> exit
(config-if)> up
(config-if)> exit

Статические маршруты и политика безопасности

KeeneticOS по умолчанию блокирует транзитный трафик между интерфейсами, если они принадлежат разным сегментам безопасности. Туннельный интерфейс включается в зону Private (Домашняя сеть), либо для него задаются статические маршруты и правила доступа:

(config)> ip route 192.168.10.0 255.255.255.0 10.100.0.1 Wireguard0 auto
(config)> ip route 192.168.20.0 255.255.255.0 10.100.0.1 Wireguard0 auto
(config)> system configuration save

Трансляция NAT для интерфейса Wireguard0 в KeeneticOS отключена по умолчанию при ручном назначении статических маршрутов без флага трансляции, что обеспечивает прозрачное прохождение пакетов с сохранением адресов 192.168.30.0/24.


4. Верификация маршрутизации и валидация сквозной задержки

После развертывания клиентских конфигураций выполняется проверка двусторонней связности между рабочими станциями внутри локальных сетей (минуя туннельные адреса 10.100.0.x).

Тест передачи данных между хостом 192.168.10.50 (СПб) и 192.168.20.100 (Алматы):

traceroute -n -T -p 445 192.168.20.100
traceroute to 192.168.20.100 (192.168.20.100), 30 hops max, 60 byte packets
 1  192.168.10.1  0.312 ms  0.280 ms  0.265 ms
 2  10.100.0.1    18.420 ms  18.390 ms  18.410 ms
 3  10.100.0.3    42.110 ms  42.080 ms  42.105 ms
 4  192.168.20.100 42.450 ms  42.410 ms  42.390 ms

Пакет совершает транзитный скачок через центральный узел 10.100.0.1. Стабильность данной схемы критически зависит от характеристик центрального хаба: если виртуальный сервер подвержен оверселлингу vCPU (%st > 0.0%) или испытывает задержки дисковой подсистемы при интенсивном логировании, возникают микропаузы в обработке софт-прерываний сетевого стека ядра (ksoftirqd), что моментально приводит к джиттеру и росту метрики latency p99.

Использование KVM-ноды от tropic.host с выделенными ядрами AMD EPYC / Ryzen 9 гарантирует строго CPU Steal Time %st = 0.0%, аппаратную изоляцию и симметричный апгрейд полосы до 10 Гбит/с. Это исключает буферблоат (Bufferbloat) и обеспечивает предсказуемую сквозную задержку (p99 latency < 25 мс в пределах европейских маршрутов и < 50 мс для трансконтинентальных направлений) при пиковых нагрузках межфилиального трафика.

Отказоустойчивость, PersistentKeepalive и обход NAT провайдеров

В топологии hub-and-spoke центральный сервер выступает неизменной точкой рандеву, однако филиальные шлюзы практически всегда отрезаны от прямого адресного пространства: они находятся за корпоративными межсетевыми экранами с проверкой состояния (stateful firewall), двойным клиентским NAT или операторским транслятором операторского класса (CGNAT / Carrier-Grade NAT). В этих условиях поддержание устойчивого туннеля требует глубокого понимания механики трансляции адресов ядром Linux и протокола WireGuard.

Жизненный цикл сессий в conntrack и проблема симметричного NAT

WireGuard полностью бесстатусен на транспортном уровне: в отсутствие прикладных пакетов ядро не генерирует служебный сетевой трафик. Криптографический ключ сессии согласуется по протоколу Noise_IK, после чего узел переходит в режим ожидания.

Когда шлюз филиала инициирует исходящий UDP-пакет к центральному хабу, пограничный NAT-маршрутизатор провайдера динамически сопоставляет внутренний адрес src_ip:src_port внешнему сокету ext_ip:ext_port и создает запись в таблице отслеживания соединений (nf_conntrack). Если через этот канал не передаются данные, срабатывает тайм-аут сброса состояния.

В Linux-стеке параметры тайм-аутов отслеживания UDP-сессий регулируются через sysctl:

sysctl net.netfilter.nf_conntrack_udp_timeout
sysctl net.netfilter.nf_conntrack_udp_timeout_stream

По умолчанию значение nf_conntrack_udp_timeout составляет 30 секунд для одиночного пакета и nf_conntrack_udp_timeout_stream — от 120 до 180 секунд для дуплексного потока. Однако на маршрутизаторах интернет-провайдеров и CGNAT-шлюзах мобильных операторов таблицы трансляций агрессивно очищаются уже через 20–30 секунд пассивности.

При использовании симметричного NAT (Symmetric NAT) ситуация усугубляется: транслятор выделяет уникальный внешний сокет под каждый новый адрес назначения и блокирует любые входящие UDP-датаграммы от центрального узла, если в локальной таблице трансляций отсутствует активная сессия, инициализированная изнутри локальной сети. В результате связь между офисами прерывается: центральный VPS не может доставить входящий межфилиальный пакет на филиальный шлюз, так как внешний порт закрыт файрволом провайдера.

Директива PersistentKeepalive: механика и математика трафика

Для предотвращения вытеснения сессии из трансляционных таблиц промежуточных узлов в конфигурацию WireGuard интегрирован механизм периодической отправки аутентифицированных нулевых сообщений — PersistentKeepalive.

[Peer]
# Публичный ключ центрального хаба
PublicKey = hAbc1234567890CentralHubPublicKeyBase64=
Endpoint = 198.51.100.10:51820
AllowedIPs = 10.100.0.0/16, 192.168.10.0/24, 192.168.20.0/24, 192.168.30.0/24
# Интервал отправки keepalive в секундах
PersistentKeepalive = 25

Принцип работы: 1. Если по туннелю в течение заданного интервала (в данном случае 25 секунд) не передавался полезный трафик, интерфейс ядра генерирует специальный служебный пакет данных WireGuard (Type 4) с пустой полезной нагрузкой. 2. Пакет шифруется текущим сессионным симметричным ключом (ChaCha20-Poly1305), получая длину 32 байта полезной нагрузки (16 байт заголовка транспортного сообщения + 16 байт аутентификационного тега Poly1305). 3. С учетом внешнего заголовка IPv4 (20 байт) и UDP (8 байт) суммарный размер датаграммы в физическом канале составляет ровно 60 байт (или 80 байт при транспорте поверх внешнего IPv6).

Интервал в 25 секунд выбран в соответствии с рекомендациями RFC 4787: он гарантированно перекрывает минимальный стандартный 30-секундный тайм-аут большинства аппаратных межсетевых экранов и CGNAT-платформ.

Критически важное архитектурное правило: директива PersistentKeepalive = 25 прописывается исключительно на узлах, находящихся за NAT (на филиальных маршрутизаторах). Задавать этот параметр на центральном VPS в секциях [Peer] клиентских офисов бессмысленно и вредно: если внешний порт на провайдерском NAT уже закрылся, пакеты keepalive от сервера будут отброшены файрволом оператора и не смогут восстановить сессию снаружи.

Динамический роуминг эндпоинтов (WireGuard Roaming)

Одной из сильнейших сторон протокола является встроенный механизм роуминга эндпоинтов (Endpoint Roaming). Если у филиального офиса меняется внешний IP-адрес (разрыв PPPoE-сессии, переключение на резервный LTE-канал, плановая ротация пула провайдером), перенастраивать туннель не требуется.

Как только от филиала на центральный хаб поступает хотя бы один пакет с новым внешним адресом IP:port, ядро Linux: 1. Выполняет проверку криптографической подписи Poly1305 по открытому ключу пира. 2. При успешной валидации мгновенно и атомарно обновляет в таблице маршрутизации интерфейса ассоциацию: Peer (PublicKey) -> New Endpoint (IP:port). 3. Все последующие ответные пакеты отправляются уже на обновленный адрес.

Чтобы при частой смене маршрутов центральный узел не отбрасывал транзитные пакеты из-за асимметричной маршрутизации, на VPS хабе настраивается свободная фильтрация обратного пути (rp_filter):

# /etc/sysctl.d/99-wireguard-routing.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.wg0.rp_filter = 2

Применение параметров без перезагрузки:

sysctl --system

Развертывание центрального узла на облачной платформе tropic.host гарантирует наличие выделенного статического IPv4 без паразитной операторской трансляции и блокировок нестандартных портов. Отсутствие аппаратного оверселлинга сетевого стека в среде KVM обеспечивает немедленную реакцию подсистемы софт-прерываний ksoftirqd на динамическую смену эндпоинтов клиентских офисов.

Автоматический сторожевой таймер (Dead Peer Detection Watchdog)

Несмотря на наличие PersistentKeepalive, в реальной эксплуатации возникают пограничные сбои: зависание сессии в промежуточном оборудовании провайдера, сбой таблицы состояний или рассинхронизация рукопожатий (Handshake Timeout). Если филиал не может завершить рукопожатие в течение 5 минут, туннель переходит в неактивное состояние.

Для обеспечения непрерывной доступности при развертывании схемы wireguard site to site между офисами vps филиальные шлюзы оснащаются скриптом-сторожем (Watchdog) под управлением systemd.

Создаем исполняемый скрипт /usr/local/bin/wireguard-watchdog.sh:

#!/usr/bin/env bash
set -euo pipefail

INTERFACE="wg0"
PEER_PUBKEY="hAbc1234567890CentralHubPublicKeyBase64="
CHECK_TARGET="10.100.0.1"
MAX_HANDSHAKE_AGE=150

# Получение времени последнего рукопожатия в эпохе Unix
LATEST_HANDSHAKE=$(wg show "$INTERFACE" latest-handshakes | awk -v peer="$PEER_PUBKEY" '$1 == peer {print $2}')
CURRENT_TIME=$(date +%s)

if [[ -z "$LATEST_HANDSHAKE" || "$LATEST_HANDSHAKE" -eq 0 ]]; then
    HANDSHAKE_DELTA=$((CURRENT_TIME - 0))
else
    HANDSHAKE_DELTA=$((CURRENT_TIME - LATEST_HANDSHAKE))
fi

# Проверка возраста рукопожатия и доступности шлюза по ICMP
if [ "$HANDSHAKE_DELTA" -gt "$MAX_HANDSHAKE_AGE" ] || ! ping -c 3 -W 2 -I "$INTERFACE" "$CHECK_TARGET" > /dev/null 2>&1; then
    logger -t wg-watchdog "ВНИМАНИЕ: Сбой туннеля $INTERFACE (Handshake age: ${HANDSHAKE_DELTA}s). Перезапуск интерфейса."

    # Принудительный сброс сокета и реинициализация линка
    systemctl restart "wg-quick@$INTERFACE.service"

    # Сброс локальной таблицы conntrack для порта WireGuard
    conntrack -D -p udp --dport 51820 > /dev/null 2>&1 || true

    exit 1
fi

exit 0

Делаем скрипт исполняемым:

chmod 750 /usr/local/bin/wireguard-watchdog.sh

Создаем юнит службы systemd /etc/systemd/system/wg-watchdog.service:

[Unit]
Description=WireGuard Tunnel Health Watchdog
After=network.target [email protected]

[Service]
Type=oneshot
ExecStart=/usr/local/bin/wireguard-watchdog.sh

Создаем юнит таймера systemd /etc/systemd/system/wg-watchdog.timer:

[Unit]
Description=Run WireGuard Watchdog every 60 seconds

[Timer]
OnBootSec=1min
OnUnitActiveSec=60s
AccuracySec=1s

[Install]
WantedBy=timers.target

Активация и запуск таймера:

systemctl daemon-reload
systemctl enable --now wg-watchdog.timer

Коррекция MTU и подавление фрагментации (TCP MSS Clamping)

Передача инкапсулированного трафика неизбежно увеличивает размер пакета. Если рабочий хост в локальной сети офиса отправляет стандартный Ethernet-фрейм размером 1500 байт с установленным флагом DF (Don't Fragment), туннельный интерфейс отбросит его, если размер превышает допустимый MTU с учетом служебных заголовков.

Расчет накладных расходов инкапсуляции WireGuard: * Внешний IPv4-заголовок: 20 байт. * Внешний UDP-заголовок: 8 байт. * Заголовок пакета данных WireGuard: 16 байт (Type + Receiver + Counter). * Аутентификационный тег Poly1305: 16 байт. * Итоговые накладные расходы: $20 + 8 + 16 + 16 = 60$ байт.

При стандартном MTU физического провайдера в 1500 байт максимальный размер туннельного MTU составляет: $$1500 - 60 = 1440 \text{ байт}$$

Если внешний провайдер подключает филиал по протоколу PPPoE (где MTU физического интерфейса уже уменьшен до 1492 за счет 8-байтового заголовка PPPoE), безопасный расчет дает: $$1492 - 60 = 1432 \text{ байта}$$

Для исключения проблем с Path MTU Discovery (PMTUD), когда промежуточные сетевые узлы блокируют контрольные ICMP-сообщения Fragmentation Needed (ICMP Type 3, Code 4), на туннельных интерфейсах wg0 принудительно задается:

[Interface]
MTU = 1420

Дополнительно на всех маршрутизаторах (центральном VPS и филиальных шлюзах) настраивается принудительное усечение максимального размера сегмента TCP (MSS Clamping) через nftables. Это предотвращает зависание HTTPS-сессий и SSH-подключений при передаче крупных пакетов.

Правило для /etc/nftables.conf:

table inet filter {
    chain forward {
        type filter hook forward priority 0; policy accept;

        # TCP MSS Clamping для туннельного интерфейса wg0
        oifname "wg0" tcp flags syn tcp option maxseg size set rt mtu
        iifname "wg0" tcp flags syn tcp option maxseg size set rt mtu
    }
}

Для систем, использующих классический iptables, аналогичная фиксация выполняется командой:

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -o wg0 -j TCPMSS --clamp-mss-to-pmtu
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -i wg0 -j TCPMSS --clamp-mss-to-pmtu

Комплекс из превентивного PersistentKeepalive = 25, сторожевого таймера проверки сбоя рукопожатия и нормализации TCP MSS гарантирует непрерывную работу туннеля через любые типы провайдерских NAT, исключая деградацию пропускной способности и потери транзитных пакетов между филиалами.

Мониторинг задержек, аудит безопасности и регламент Disaster Recovery

Синтетическое профилирование связности и телеметрия туннеля

В продакшен-инфраструктуре топология WireGuard site to site между офисами через VPS требует непрерывного контроля задержек, вариации сетевой задержки (jitter) и целостности передачи пакетов. Поскольку протокол функционирует поверх UDP, стандартные механизмы TCP retransmission не защищают от потерь данных на этапе инкапсуляции. Любые микроразрывы или перегрузка очередей сетевого стека приводят к лавинообразному росту задержек на уровне прикладных протоколов филиалов.

Для первичной оценки задержки в канале и выявления аномалий p99 latency выполняется расширенный ICMP-аудит с высокой частотой дискретизации. Команда генерирует 100 запросов с интервалом 0.1 секунды без ожидания ответа:

ping -c 100 -i 0.1 -q 10.10.0.2

Анализ поля rtt min/avg/max/mdev позволяет изолировать сетевой джиттер (mdev — среднее квадратичное отклонение). Значение mdev > 5 ms при среднем RTT в 20–30 ms свидетельствует о возникновении буферблоата (Bufferbloat) на шлюзах провайдера последней мили или о деградации хост-ноды виртуализации. Использование KVM-инфраструктуры tropic.host с нулевым показателем кражи процессорного времени (%st = 0.0% по данным vmstat 1 или top) гарантирует, что планировщик ядра Linux обрабатывает аппаратные прерывания туннеля ksoftirqd без квантовых задержек виртуализации.

Профилирование пропускной способности и измерение процента потерь датаграмм выполняется утилитой iperf3. Замер проводится строго внутри зашифрованного оверлея с учетом накладных расходов WireGuard. При MTU 1420 байт размер полезной нагрузки UDP задается равным 1372 байтам (1420 - 28 байт IP/UDP заголовков), чтобы исключить фрагментацию тестовых пакетов:

# На стороне филиального маршрутизатора запускается сервер:
iperf3 -s -B 10.10.0.2

# С центрального VPS генерируется UDP-поток со скоростью 100 Мбит/с:
iperf3 -c 10.10.0.2 -u -b 100M -l 1372 -t 30 -R

Ключ -R тестирует обратный канал от филиала к VPS, выявляя асимметрию аплинка. Допустимый уровень потерь (Packet Loss) в корпоративном VPN-контуре не должен превышать 0.1%.

Для автоматизированного сбора метрик в стек Prometheus развертывается prometheus-wireguard-exporter. Сервис опрашивает интерфейс wg0 через Netlink API и экспортирует метрики на порт 9586:

# Установка и запуск экспортера
apt-get install -y prometheus-wireguard-exporter
systemctl enable --now prometheus-wireguard-exporter

Конфигурация метрик Prometheus фиксирует критические параметры туннеля: * wireguard_latest_handshake_seconds — время последней криптографической аутентификации. Если значение превышает 180 секунд, пир считается недоступным. * wireguard_sent_bytes_total и wireguard_received_bytes_total — счетчики трафика для выявления аномалий полосы пропускания.

Пример правила оповещения для Prometheus Alertmanager (/etc/prometheus/alert_rules.yml):

groups:
  - name: wireguard_site_to_site
    rules:
      - alert: WireGuardPeerDead
        expr: (time() - wireguard_latest_handshake_seconds{interface="wg0"}) > 180
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Потеряна связь с филиалом {{ $labels.public_key }}"
          description: "Рукопожатие не обновлялось более 3 минут. Маршрутизация прервана."

Аудит безопасности, сжатие привилегий и ротация Pre-shared Keys

Эксплуатация центрального хаба WireGuard на публичном KVM VPS требует жесткого разграничения доступа к криптографическим материалам ядра и изоляции сетевого демона.

1. Права доступа к конфигурациям

Приватные ключи не должны быть доступны непривилегированным процессам ОС. Проверка и установка прав на стороне хоста:

chown -R root:root /etc/wireguard
chmod 700 /etc/wireguard
chmod 600 /etc/wireguard/*.conf
chmod 600 /etc/wireguard/*.key

2. Песочница systemd и лимиты cgroups v2

Управление интерфейсом через systemd изолируется директивами безопасности ядра. Для сервиса [email protected] создается drop-in файл переопределения конфигурации /etc/systemd/system/[email protected]/override.conf:

[Service]
# Изоляция файловой системы и пространства пользователя
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=no
ProtectKernelModules=yes
ProtectControlGroups=yes
PrivateTmp=yes
MemoryDenyWriteExecute=yes

# Ограничение системных вызовов через cgroups v2 и seccomp
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK

# Контроль потребления ресурсов процессами обвязки
MemoryHigh=128M
MemoryMax=256M
CPUQuota=80%

Применение изменений выполняется перезагрузкой демона:

systemctl daemon-reload
systemctl restart wg-quick@wg0

3. Бесшовная ротация PresharedKey (PFS Layer)

WireGuard обеспечивает Perfect Forward Secrecy на базе протокола Noise IK, однако для защиты от потенциальной ретроспективной расшифровки квантовыми компьютерами внедряется дополнительный симметричный ключ PresharedKey. Ротация этого ключа проводится каждые 90 дней без разрыва туннеля и без перезапуска интерфейса wg0:

# Генерация нового 256-битного симметричного ключа
wg genpsk > /etc/wireguard/psk_office_branch1_new.key

# Применение ключа на лету через вызов ядра
NEW_PSK=$(cat /etc/wireguard/psk_office_branch1_new.key)
PEER_PUBKEY="c2VydmVyX3B1YmxpY19rZXlfZXhhbXBsZTEyMzQ1Njc4OTAxMg=="

wg set wg0 peer "$PEER_PUBKEY" preshared-key /etc/wireguard/psk_office_branch1_new.key

Аналогичная команда выполняется на филиальном шлюзе с тем же ключом. Сессия мгновенно переключается на использование нового секрета со следующего пакета данных. После подтверждения связности новый ключ фиксируется в статическом /etc/wireguard/wg0.conf.


Регламент аварийного восстановления (Disaster Recovery Playbook)

Сценарий Disaster Recovery (DR) регламентирует действия дежурного инженера при катастрофическом отказе центрального узла, аппаратном сбое платформы или компрометации ОС.

Этап 1: Автоматизированное резервное копирование криптографического контура

Резервная копия содержит исключительно конфигурационные файлы /etc/wireguard/, скрипты преднастройки nftables и системные сетевые правила sysctl.d. Создание открытых бэкапов закрытых ключей запрещено.

Скрипт создания шифрованного архива /usr/local/bin/wg-backup.sh:

#!/usr/bin/env bash
set -euo pipefail

BACKUP_DIR="/var/backups/wireguard"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
ARCHIVE_PATH="${BACKUP_DIR}/wg_backup_${TIMESTAMP}.tar.gz"
GPG_RECIPIENT="[email protected]"

mkdir -p "${BACKUP_DIR}"
chmod 700 "${BACKUP_DIR}"

# Сборка конфигураций и скриптов маршрутизации
tar -czf "${ARCHIVE_PATH}" \
    /etc/wireguard/ \
    /etc/nftables.conf \
    /etc/sysctl.d/99-wireguard.conf

# Асимметричное шифрование открытым GPG-ключом безопасности
gpg --batch --yes --trust-model always --encrypt --recipient "${GPG_RECIPIENT}" "${ARCHIVE_PATH}"
rm -f "${ARCHIVE_PATH}"

# Ротация локальных бэкапов старше 14 дней
find "${BACKUP_DIR}" -name "*.gpg" -mtime +14 -delete

# Синхронизация с изолированным S3-совместимым хранилищем
aws s3 cp "${ARCHIVE_PATH}.gpg" "s3://company-dr-storage/vps-wireguard/wg_backup_${TIMESTAMP}.tar.gz.gpg" \
    --endpoint-url https://s3.storage.domain.com

Запуск резервного копирования настраивается через системный таймер systemd ежедневно в 03:00 UTC.


Этап 2: Пошаговый протокол развертывания ноды с нуля (RTO < 7 минут)

При уничтожении инстанса или масштабном отказе ЦОД развертывание запасной ноды осуществляется на чистом инстансе tropic.host с операционной системой Ubuntu 24.04 LTS или Debian 12. Серверные NVMe-диски корпоративного класса обеспечивают случайное чтение 4K QD1 свыше 50 000 IOPS, исключая задержки дискового ввода-вывода при установке пакетов и инициализации базы маршрутов.

Шаг 1. Первичная инициализация сетевого стека ядра
На свежем инстансе задаются необходимые параметры буферизации UDP и маршрутизации пакетов:

cat << 'EOF' > /etc/sysctl.d/99-wireguard.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
EOF

sysctl --system

Шаг 2. Развертывание бинарных пакетов

apt-get update && apt-get install -y wireguard-tools nftables gpg awscli jq

Шаг 3. Извлечение и расшифровка бэкапа
Секретный GPG-ключ инженера монтируется временно через защищенную SSH-сессию (или передается через HashiCorp Vault):

# Получение последнего актуального бэкапа из объектного хранилища S3
LATEST_BACKUP=$(aws s3 ls s3://company-dr-storage/vps-wireguard/ --endpoint-url https://s3.storage.domain.com \
  | sort | tail -n 1 | awk '{print $4}')

aws s3 cp "s3://company-dr-storage/vps-wireguard/${LATEST_BACKUP}" /tmp/restore_backup.tar.gz.gpg \
  --endpoint-url https://s3.storage.domain.com

# Расшифровка архива
gpg --decrypt /tmp/restore_backup.tar.gz.gpg | tar -xz -C /

# Очистка следов расшифровки
rm -f /tmp/restore_backup.tar.gz.gpg

Шаг 4. Валидация прав доступа и структуры сети

chmod 700 /etc/wireguard
chmod 600 /etc/wireguard/*
chown -R root:root /etc/wireguard
nft -f /etc/nftables.conf

Шаг 5. Запуск интерфейса и валидация связности

systemctl enable --now wg-quick@wg0

Проверка состояния каналов выполняется детерминированной командой:

wg show wg0

Критерий успешного ввода узла в строй: 1. Появление сессий со всеми филиалами со статусом рукопожатия latest handshake: 0 minutes ago. 2. Наличие двунаправленного трансфера данных (transfer: > 0 B received, > 0 B sent). 3. Успешное прохождение сквозного ICMP-трафика до корпоративных шлюзов локальных сетей филиалов:

# Проверка пинга до внутреннего роутера Филиала 1 (192.168.10.1)
ping -c 3 -W 1 192.168.10.1

# Проверка пинга до внутреннего роутера Филиала 2 (192.168.20.1)
ping -c 3 -W 1 192.168.20.1

Если узел развернут с новым статическим IP-адресом, на пограничных роутерах филиалов выполняется обновление переменной Endpoint:

wg set wg0 peer "vps_server_public_key=" endpoint "NEW_VPS_IP:51820"

Благодаря алгоритму TCP BBR и прямому BGP-пирингу на узлах Франкфурта, Лондона и Амстердама в облаке tropic.host, транзитный трафик между географически распределенными филиалами восстанавливает расчетную пропускную способность без накопления пакетных очередей. Инфраструктура полностью возвращается в штатный рабочий режим.

Часто задаваемые вопросы (FAQ)

Какой объем оперативной памяти нужен для WireGuard шлюза на 10 офисов?

WireGuard работает в ядре Linux и чрезвычайно экономичен. Инстанса с 1–2 vCPU и 1–2 GB RAM достаточно для прокачки гигабитного трафика между десятками офисов.

Почему критична KVM виртуализация для Site-to-Site VPN?

Для маршрутизации между подсетями требуется прямой доступ к таблицам iptables/nftables, модуль ядра wireguard и системный вызов TUN/TAP, что гарантирует аппаратный KVM.