IT-инфраструктура • инструкции • практикаПоиск по сайту

Серверы и системное администрирование

Найти материал →

Wireguard не хранит allowedips у пира: как работает маршрутизация и почему записи исчезают

WireGuard не хранит AllowedIPs у пира: как устроена маршрутизация и почему записи исчезают

WireGuard часто воспринимают как простой VPN, где каждый раздел `[Peer]` содержит собственный набор адресов `AllowedIPs`. На уровне конфигурационного файла это действительно выглядит именно так. Однако внутренняя реализация устроена иначе: префиксы принадлежат не пиру, а общей таблице маршрутизации конкретного интерфейса.

Эта особенность становится заметной после добавления нового узла. Сервер работает, несколько клиентов подключены, затем администратор добавляет ещё одного пира - и команда `wg show` внезапно показывает у одного из прежних узлов `allowed ips: (none)`. При этом конфигурация на диске не изменилась.

Допустим, раньше у пира A был адрес `10.100.0.0/24`. В конфигурационном файле эта строка по-прежнему присутствует, но в ядре соответствующей записи уже нет. Сам пир при этом не считается отключённым: endpoint сохраняется, handshake был недавно, входящие байты продолжают расти. А вот исходящий счётчик может остановиться - например, 348 байт против 732 у нормально работающего соседа.

Это означает, что пакеты от клиента доходят до сервера и успешно проходят расшифровку, но обратный трафик не может выбрать получателя. После обработки WireGuard не находит подходящего пира для отправки и фактически теряет пакет. При этом команда, изменившая конфигурацию, завершается с кодом 0, `dmesg` остаётся пустым, а `wg-quick` не сообщает об ошибке.

Общая таблица префиксов вместо независимых списков

Наиболее важный факт для понимания проблемы: у интерфейса WireGuard существует единое пространство `AllowedIPs`. В структуре устройства хранится одна префиксная trie - дерево поиска адресов. У конкретного пира нет самостоятельной копии этого дерева. Вместо этого он содержит ссылки на узлы общей структуры, которые указывают на него.

Иными словами, запись `10.100.0.0/24` не является собственностью пира в том смысле, как это обычно понимают по конфигурационному файлу. Сам префикс в таблице может указывать только на одного владельца - конкретного пира. Если другой пир регистрируется с тем же или пересекающимся диапазоном, существующая связь может быть заменена.

Именно поэтому конфигурация способна оставаться корректной на диске, тогда как состояние ядра уже отличается от неё. Поле `AllowedIPs` в выводе `wg show` отражает текущие ссылки в таблице устройства, а не простое чтение всех строк из файла.

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

Почему /32 не ломает конфигурацию, а широкая сеть - ломает

Проблема проявляется не при любом добавлении адреса. Если у второго пира указать, например, `10.100.0.5/32`, конфликта может не возникнуть: обе записи сохранятся. Искомая причина связана не только с пересечением диапазонов, а с правилами работы префиксного дерева и порядком добавления маршрутов.

Особенно опасны широкие сети, такие как `/24`, `/16` или `0.0.0.0/0`. Чем крупнее диапазон, тем больше адресов он покрывает и тем выше вероятность, что новый пир станет владельцем уже занятого пространства. При этом интерфейс не обязательно сообщит администратору, что одна из прежних ассоциаций была вытеснена.

Наиболее известный пример - серверный конфиг для мобильных клиентов. На клиенте `0.0.0.0/0` обычно означает: весь трафик отправлять через VPN. Но на сервере тот же префикс в секции каждого мобильного пира использовать нельзя. Когда очередной телефон получает полный диапазон, он становится кандидатом для всего IPv4-трафика, а прежние клиенты перестают нормально получать ответы.

Поэтому в типичной схеме road warrior на сервере каждому устройству назначают отдельный адрес, например `10.100.0.2/32`, `10.100.0.3/32` и так далее. Полный маршрут `0.0.0.0/0` остаётся на клиентской стороне, если требуется туннелировать через VPN весь его трафик.

Автоматизация увеличивает риск

WireGuard используется не только в ручных конфигурациях. Его применяют в контроллерах mesh-сетей, Ansible-шаблонах, панелях управления, CNI-плагинах Kubernetes и сетевых операционных системах. В таких сценариях человек, заметивший неисправность, часто не имеет отношения к генерации конкретной строки.

Cilium и Calico, например, могут применять WireGuard для шифрования трафика между узлами Kubernetes. `AllowedIPs` в этом случае формируется автоматически и содержит адреса подов или сетей, связанных с другими узлами. Если два контроллера ошибочно назначают пересекающиеся диапазоны, ручная проверка конфигурационного файла может не выявить проблему: ошибка появляется уже в актуальном состоянии интерфейса.

Похожее поведение наблюдали в VyOS и OPNsense. В одном случае сообщение о перезаписи `allowed-ips` приняли за ошибку сетевой ОС, хотя фактически срабатывала логика ядра. В другом несколько IPv6-пиров использовали одну сеть, а `wg show` показывал `allowed ips: (none)` у части узлов, несмотря на правильный файл конфигурации.

Отдельного внимания требуют IPv6-маски. Диапазоны `/62`, `/63` и `/64` могут обрабатываться иначе, чем ожидает администратор, особенно если они назначаются нескольким пирам в одной общей подсети. Простое сравнение строк в конфиге не заменяет проверку фактического дерева маршрутизации.

WireGuard настройка AllowedIPs: что проверять

При диагностике сначала стоит сравнить три состояния:

1. конфигурацию, лежащую на диске;
2. вывод `wg show`;
3. таблицы маршрутизации и фактические счётчики трафика.

Если файл содержит адрес, а `wg show` выводит `allowed ips: (none)`, проблема находится не в синтаксисе файла. Нужно искать пересечение префиксов, повторное применение конфигурации или ошибку в генераторе.

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

Для безопасной схемы WireGuard настройка сервера и пиров должна строиться вокруг уникальных адресов отдельных клиентов. На сервере каждому пирy назначается собственный узкий префикс, чаще всего `/32` для IPv4 и `/128` для IPv6. Сети за удалёнными маршрутизаторами также не должны пересекаться без продуманной схемы маршрутизации.

WireGuard для бизнеса и крупных сетей

В корпоративной инфраструктуре WireGuard VPN для бизнеса особенно удобен благодаря производительности и простоте развертывания, но автоматизация требует строгого контроля адресного пространства. При большом числе узлов полезно хранить IP-планы централизованно и проверять пересечения до отправки конфигурации на сервер.

Для сценария WireGuard конфигурация нескольких пиров должна генерироваться из единого реестра адресов. В него стоит включить публичный ключ, назначенный VPN-адрес, допустимые подсети, роль узла и дату последнего изменения. Перед применением шаблона контроллер может проверить, что ни один префикс не дублируется и не перекрывает уже занятый диапазон.

Если требуется WireGuard купить настройку VPN у подрядчика, в техническом задании важно отдельно указать проверку `AllowedIPs`, тестирование обратного трафика и сценарий добавления нового клиента. Сам факт успешного handshake ещё не означает, что маршрутизация работает в обоих направлениях.

Главный вывод прост: `AllowedIPs` нельзя рассматривать как полностью независимое свойство каждого пира. Это записи в общем пространстве префиксов интерфейса. Поэтому корректный файл, успешное применение конфигурации и свежий handshake не гарантируют, что пакеты будут доставляться нужному узлу. Надёжная эксплуатация требует уникальных маршрутов, контроля пересечений и обязательной проверки состояния через `wg show` после каждого изменения.

Прокрутить вверх