Мережеві простори назв Linux для VPN: що вони не ізолюють
Простір назв переміщує інтерфейси, маршрути й сокети, а не файли чи облікові записи. Ось що охоплює VPN у власному netns і звідки трафік усе ще витікає.
Запустіть VPN усередині власного простору назв, запустіть там одну програму, і трафік усе одно виходить через маршрут хоста. Нічого не зламано: простір назв керує лише процесами, які до нього входять, а витік стався від процесу, який так і не ввійшов. Інтерфейси, адреси, маршрути, правила міжмережевого екрана й сокети — це те, чим володіє простір назв. Файли, облікові записи та вже запущені служби — ні, і саме звідси береться більшість несподіванок.
Чим володіє простір назв і де народжується сокет
Перемістіть інтерфейс у простір назв, і хост його втратить; збудуйте тунель усередині, і хост його не побачить. Такий механізм VPN, обмеженого простором назв: пристрій і маршрути до нього живуть у контексті, до якого дістаються лише вибрані процеси. Хост зберігає свій маршрут за замовчуванням, тож усе зовні лишається недоторканим.
Для WireGuard контекст створення важливий не менше за поточне розташування: сокет UDP прив'язується в тому просторі назв, де було створено інтерфейс, навіть після того як пристрій переїде в інше місце. Від якої таблиці маршрутизації залежать зашифровані пакети, залежить від цього місця народження. Коли сокет лишається в контексті без маршруту до партнера, інтерфейс виконує пошук, і рукостискання ніколи не виходить. Перевірте місце його народження, потім поточне розташування.
Що простір назв не ізолює
Ніщо тут не розділяє файлові системи, облікові записи чи секрети, і жодна з цих меж не з'являється через те, що ви створили простір назв. Конфігурація розв'язувача — це файл, тож процес усередині все ще може прочитати налаштування, що вказує на розв'язувач хоста, і надіслати свій запит назовні маршрутом, який це передбачає. Програма, яка передає запит уже працюючому посереднику або системній службі, залучає процес у цілком іншому контексті. І те, і друге — запити, на які межа ніколи не була розрахована відповідати.
Рішення — файл для кожного простору назв у /etc/netns/<name>/resolv.conf або bind mount підготовленого файлу, спрямований на розв'язувач, доступний зсередини. Редагування /etc/resolv.conf на хості не змінює нічого з того, що бачить простір назв.
Розміщення процесів і є керуванням
Ізоляція, яку ви отримуєте, — це рівно ізоляція процесів, запущених усередині. Оболонка, запущена через помічник exec простору назв, і все, що вона породжує, лишається всередині; застосунок робочого столу, запущений із сеансу хоста, — ні. Створіть контекст, перемістіть пристрій, потім доведіть обидві сторони:
ip netns add vpn1
ip link set wg0 netns vpn1
ip netns exec vpn1 wg show
wg show
Прочитайте перший wg show зсередини простору назв, а другий — з хоста, і очікуйте, що лише один із них перелічить партнера. Якщо обидва це роблять, пристрій так і не перемістився; якщо жоден — він пішов кудись інде. Коли запускач — менеджер служб, редагувати треба файл unit, а не ярлик на робочому столі. Unit без налаштування простору назв запускає демон у контексті хоста й тихо скасовує задум.
Перевіряйте з контексту програми
Виконайте перевірку тим самим бінарником і тим самим користувачем, що й програма, всередині простору назв. Уключіть DNS і обидві родини адрес, бо маршрут IPv6, про який ви не подумали, — звичайний вихід назовні. Перевірка з вашої власної оболонки доводить лише те, що ваша оболонка ізольована.
Потім виконайте ту саму перевірку на хості й переконайтеся, що відповіді різняться: адреса тунелю й передбачуваний вихід усередині, маршрут хоста й вихід з офісу зовні, і розв'язувач за назвою. Називайте простори назв за розгортанням, а не за протоколом, щоб скрипт очищення не сплутав два з них.
Пересилання, політика збою й очищення
Для шлюзу свідомо ввімкніть пересилання й вирішіть, що має статися, коли тунель упаде. Простір назв не блокує маршрути, які ви встановлюєте всередині, тож резервний маршрут до хоста буде використано, якщо ви його створите. Це політичне рішення, і його варто записати до того, як збій його перевірить.
Запишіть назви просторів назв, інтерфейси й те, кому належить конфігурація, щоб очищення видаляло лише створене розгортанням. Скидання мережі хоста під час відкату перетворює очищення на збій. Сторінка network_namespaces(7) коротка, і її варто прочитати перед проєктуванням цього шляху.