Интерфейс числится в нужном пространстве имён, приложение привязано к нему, и всё же трафик туннеля не появляется. Это признак устройства WireGuard в ядре Linux, созданного в одном пространстве имён и перенесённого в другое: интерфейс переехал, а его зашифрованный UDP-сокет — нет. Оба должны находиться на правильном месте, прежде чем внутренний трафик будет иметь значение. Проверка быстрая, как только вы знаете, что смотреть нужно на два контекста, а не на один.

Симптом: правильное пространство имён, но пакетов нет

Внутри пространства имён туннель выглядит здоровым. Устройство существует, адреса назначены, конфигурация партнёра присутствует. Снаружи ожидаемый обмен UDP никогда не появляется на интерфейсе, за которым вы наблюдали, а противоположная сторона сообщает, что рукопожатия не было.

Причина в том, что внутренние пакеты приложения достигают перемещённого устройства, и устройство пытается отправить их через сокет, принадлежащий другому сетевому контексту. Маршрут нижнего уровня, который оно использует, и каждое правило брандмауэра, применимое к нему, относятся к пространству имён, где устройство было создано.

Это не ошибка переноса и не неверная конфигурация партнёра. Так работает реализация ядра, и документация по пространствам имён для WireGuard прямо описывает правило создания.

Почему у сокета есть место рождения

Устройство WireGuard владеет одним UDP-сокетом для своего зашифрованного транспорта, и этот сокет открывается в пространстве имён, где создаётся устройство. Перенос интерфейса командой связи перемещает видимое устройство, но оставляет транспорт там, где он начался. Тогда у двух объектов разные владельцы.

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

Создайте его там, где нужен сокет

Решение — создавать устройство внутри целевого пространства имён, а не создавать его снаружи и переносить. Предполагая, что одобренное пространство имён уже существует и имя не используется:

ip netns exec vpn-apps ip link add wg-demo type wireguard
ip netns exec vpn-apps wg show

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

Относитесь к ним как к командам администрирования сети, а не как к рецепту. Они создают устройство и показывают состояние; ключи, партнёры, адреса и маршруты всё ещё должны поступать из одобренной конфигурации, и существующий производственный интерфейс никогда не должен подставляться в пример.

Читайте обе стороны пути

Когда устройство на месте, проверьте два решения по отдельности. Начните с внутреннего поиска из контекста приложения, затем проверьте внешний путь из контекста, которому принадлежит сокет:

ip netns exec vpn-apps ip route get 10.30.0.9
ip netns exec vpn-apps wg show
tcpdump -ni any udp port 51820

Если внутренний поиск разрешается через туннель и внешняя запись показывает зашифрованный обмен, обе половины согласуются. Если запись пуста, сокет всё ещё в другом месте, либо маршрут нижнего уровня в его пространстве имён не достигает конечной точки.

Ещё одна проверка относится к записи: как устройство создаётся после перезапуска. Менеджер, который пересоздаёт интерфейс с другим контекстом создания, меняет место рождения сокета. Ручной перенос, сработавший однажды, не является доказательством для управляемого пути.

Похожие статьи