Когда WireGuard "теряет" AllowedIPs у пира - и почему это не похоже на обычную ошибку конфигурации
Ситуация выглядит буднично: есть WireGuard‑сервер и несколько пиров, всё стабильно шифруется и маршрутизируется. Затем добавляется ещё один клиент - и внезапно `wg show` у части уже существующих пиров печатает `allowed ips: (none)`. При этом сами пиры не "падают": `endpoint` на месте, свежий `handshake` есть, счётчики принятых байт растут почти как у "живых" соседей. Ломается другое: асимметрия трафика. Пакеты от проблемного пира доезжают до сервера, проходят расшифровку, а в обратную сторону не уходит почти ничего - как будто данные "умирают" сразу после криптографии.
Самое неприятное - внешне всё выглядит корректно. Команда, которая привела к поломке, отрабатывает "успешно": код возврата 0, `dmesg` пуст, `wg-quick` не ругается. Именно поэтому проблема легко маскируется под "где-то ошиблись в подсети" или "клиент криво настроен", хотя на диске в конфиге AllowedIPs остаются прежними и вроде бы правильными.
В практике это часто всплывает при сценарии road warrior - когда на сервер добавляют телефоны/ноутбуки. На форумах OpenWrt встречался буквально такой кейс: добавляешь новый мобильный пир - и ранее добавленные перестают нормально работать. Типовая причина: на сервере каждому пиру по ошибке прописывают `0.0.0.0/0` в `allowed_ips`. Это значение должно жить на клиенте (если вы делаете full-tunnel), но не на сервере. В итоге каждый новый телефон "перетягивает" на себя маршрут по умолчанию, а предыдущий становится "немым".
Отдельная ловушка: дело не в том, что префиксы пересекаются "как-то не так" в бытовом понимании. Например, если у одного пира был бы строго адрес хоста `10.100.0.5/32`, а у другого - другая /32, то ничего бы не произошло: обе записи сохранились бы. А вот с более широкими сетями (условный `10.100.0.0/24`) эффект проявляется куда охотнее. В некоторых отчётах по сетевым ОС люди натыкались и на ещё более странный нюанс: с масками `/62`, `/63` и `/64` записи могут применяться все вместе, а при других масках - "исчезать" у части пиров. На уровне наблюдений это выглядит как магия, пока не заглянешь в механику хранения.
Подробный разбор поведения и симптомов, включая то, почему выглядит так, будто WireGuard "не хранит" AllowedIPs у пира, хорошо ложится в формулировку WireGuard AllowedIPs не работает - решение и объяснение механики - именно потому, что проблема часто не в конфиге как тексте, а в том, как эти префиксы устроены внутри.
---
Где на самом деле "лежит" AllowedIPs и почему это важно
AllowedIPs выглядит как свойство конкретного пира: он записан в секции `[Peer]` рядом с `PublicKey` и `Endpoint`, а man‑страница описывает его как список CIDR‑префиксов, откуда входящий трафик "разрешён" и куда исходящий "направляется". Из этого легко сделать неверный вывод, что у каждого пира есть независимый список маршрутов.
В реализации логика обратная: пространство префиксов общее для всего интерфейса. По сути используется единая префиксная структура (trie) на устройство, а у пира хранится не "владение префиксами", а обратные ссылки на узлы этой структуры. Ключевой момент: у узла префикса может быть только один владелец - один `peer`. Пир не "имеет" подсеть; подсеть указывает на пира. Поэтому при добавлении нового пира с префиксом, который "побеждает" в этой структуре, прежняя привязка может быть вытеснена - и тогда в `wg show` у старого пира AllowedIPs превращается в `(none)`, хотя конфиг на диске продолжает выглядеть неизменным.
Из-за этого эффект проявляется "не у всех": записи исчезают именно у тех пиров, чьи префиксы конфликтуют на уровне внутренней структуры интерфейса. Снаружи кажется, что правила должны сосуществовать, но внутри это один общий набор, где некоторые комбинации префиксов приводят к переустановке владельца узла.
---
Почему это встречается повсюду: от домашних роутеров до Kubernetes
Проблема не привязана к одной платформе. Её ловили в сетевых ОС (в духе VyOS и OPNsense), встраиваемых решениях, а в кластерах Kubernetes она особенно токсична: Cilium и Calico используют WireGuard для шифрования трафика между узлами, а AllowedIPs там - машинно сгенерированный список адресов подов. В таких окружениях в `wg show` обычно никто не смотрит каждый день, поэтому симптом один и тот же: "туннель поднят, конфиг правильный, трафика нет", и дальше начинается поиск "ошибки в настройках", хотя корень - в принципе распределения префиксов.
Отдельно стоит помнить, что это поведение воспроизводится сразу в нескольких реализациях WireGuard: в ядре Linux (мейнлайн начиная с 5.6), в userspace‑вариантах и на разных ОС. Это не выглядит как единичная регрессия - скорее как следствие заложенной модели данных.
---
Практика: как не сломать настройку "сервер + много клиентов"
Если у вас типовой сценарий настройка WireGuard сервер несколько клиентов, правило простое: на сервере AllowedIPs должны быть минимально необходимыми и уникальными для каждого пира (обычно /32 для IPv4 и /128 для IPv6), а "маршрут по умолчанию" (`0.0.0.0/0`, `::/0`) следует оставлять клиенту, если вы делаете полный туннель. В противном случае очередной добавленный клиент легко "перепривяжет" самый широкий префикс к себе, и предыдущие начнут принимать трафик без возможности получить ответ.
Если вы пытаетесь настроить WireGuard на Linux сервере и видите странную картину: handshake есть, входящий счётчик растёт, а исходящий почти стоит - первым делом проверьте, не выдаёте ли вы нескольким пирам слишком широкие сети в AllowedIPs. Часто именно это и есть корень того, что "всё поднялось, но не маршрутизируется".
---
Что делать администраторам и интеграторам
В корпоративной среде, где важно администрирование WireGuard VPN для бизнеса, проблему нужно рассматривать не как "редкий баг", а как риск, который появляется из-за автоматизации: веб‑панели, Ansible‑шаблоны, mesh‑контроллеры и CNI‑плагины генерируют AllowedIPs автоматически. Человек, который увидит последствия (пропала связность), обычно не тот, кто "вписал строчку". Поэтому полезны две меры: 1) запрет/валидация слишком широких префиксов на стороне генератора, 2) проверка итоговой таблицы на конфликты перед применением.
Если же требуется поддержка и настройка WireGuard VPN под ключ, стоит заранее договориться о политике адресации (уникальные /32 и /128 на пира) и о том, где именно задаётся full-tunnel. Это дешевле, чем разбирать "призрачные" инциденты, когда интерфейс жив, криптография работает, а бизнес‑сервисы внезапно недоступны с части клиентов.
Дополнительно по теме и по тому, как именно проявляется потеря привязки AllowedIPs на практике, уместно держать под рукой материал настройка WireGuard сервер несколько клиентов без конфликтов AllowedIPs: он помогает быстрее сопоставить симптомы (живой handshake + нулевой обратный трафик) с реальной причиной, а не уходить в бесконечную проверку ключей и фаерволов.
---
Мини-чек: как быстро подтвердить диагноз
1) Сравните конфиг на диске и вывод `wg show`: если в файле AllowedIPs есть, а в статусе у части пиров `(none)`, это уже тревожный маркер.
2) Посмотрите на ширину префиксов: наличие `0.0.0.0/0` на сервере почти всегда означает будущие конфликты при добавлении новых клиентов.
3) Оцените поведение счётчиков: "получаю много, отправляю почти ничего" при живом handshake обычно указывает не на криптографию и не на UDP‑доступность, а на то, что после расшифровки пакетам некуда маршрутизироваться - потому что привязка префикса к пиру перезаписана.
Такой сбой неприятен именно тем, что WireGuard внешне ведёт себя корректно и не сигнализирует ошибкой. Поэтому лучшая стратегия - не надеяться, что "как-нибудь пронесёт", а проектировать AllowedIPs так, чтобы они не могли вытеснять друг друга при росте числа клиентов.
