WireGuard у мережевому просторі імен: чому сокет залишився позаду
Переміщення інтерфейсу не переміщує зашифрований UDP-сокет, який залишається в просторі імен, де створено пристрій. Створіть його в цільовому просторі.
Інтерфейс є в потрібному просторі імен, застосунок прив'язаний до нього, і все ж трафік тунелю не з'являється. Це ознака пристрою 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
Якщо внутрішній пошук вирішується через тунель і зовнішній запис показує зашифрований обмін, обидві половини узгоджуються. Якщо запис порожній, сокет усе ще в іншому місці, або маршрут нижнього рівня в його просторі імен не досягає кінцевої точки.
Ще одна перевірка належить до запису: як пристрій створюється після перезапуску. Менеджер, який відтворює інтерфейс з іншим контекстом створення, змінює місце народження сокета. Ручне переміщення, що спрацювало один раз, не є доказом щодо керованого шляху.