Контейнер не відкривав свій тунель, тож додали привілейований прапорець, і тепер усе працює. Ця послідовність довела лише те, що бракувало принаймні одного дозволу, і нічого не каже про те, якого саме. Привілейований режим надає набір можливостей і доступ до пристроїв значно ширший, ніж потрібно інтерфейсу тунелю.

Що насправді змінює прапорець

Привілейований контейнер отримує широкі можливості й доступ до пристроїв хоста, що є значно більшим дозволом, ніж вимагає мережевий шлях. Точний набір документує середовище виконання, а не визначає переказ, і документація Docker про запуск контейнерів описує доступні параметри привілеїв. Одного прочитання достатньо, щоб побачити: тунель — мала частина цілого.

Дві вужчі вимоги покривають більшість контейнерів VPN. Налаштування інтерфейсу потребує можливості адміністрування мережі, а відкриття пристрою тунелю потребує доступу саме до того вузла пристрою. Це окремі дозволи, і навіть обидва разом вони вужчі за загальний варіант. Решта привілейованого набору не має нічого спільного з тунелем. Він існує для навантажень, яким справді потрібен доступ на рівні хоста, а контейнер VPN зазвичай не належить до них.

Зіставте кожну помилку з однією передумовою

Повідомлення про помилку каже, якої передумови бракує, якщо прочитати його до придушення. Повідомлення про вузол пристрою називає пристрій, повідомлення про недозволену операцію називає можливість, а повідомлення про модуль або sysctl називає підтримку ядра. Кожне з них має інше виправлення, і лише одне з них є можливістю.

Відсутній файл конфігурації залишається відсутнім після надання всіх можливостей, тому привілейований режим інколи не змінює геть нічого. Контейнер запускається, тунель усе ще не працює, а справжня помилка ніколи не стосувалася дозволів. Підтримка ядра — це третій випадок і той, який найлегше прочитати неправильно. Модуль, не завантажений на хості, не можна завантажити зсередини непривілейованого контейнера, а надання більшої кількості можливостей усередині контейнера не змінює стану хоста.

Перевіряйте вимогу, а не симптом

Почніть із мінімального виклику, який документує образ, запустіть його й збережіть точний текст збою. Потім додавайте по одному дозволу й зазначайте, яке додавання змінило результат.

ls -l /dev/net/tun
docker run --rm --cap-add NET_ADMIN --device /dev/net/tun image:tag
ip -br link show type tun

Контейнер, який бачить пристрій і має можливість, але все одно зазнає невдачі, каже, що проблема в іншому місці. Це корисний результат, і привілейований режим приховав би його.

Перевірте також права на пристрій на хості, адже правильно наданий вузол пристрою з неправильним власником групи дає ту саму помилку, що й відсутній дозвіл.

Запишіть найвужчий дозвіл, який працює

Запишіть кожен пристрій і кожну можливість, потрібні розгортанню, разом з помилкою, що їх виправдала. Саме цей запис дає змогу наступній людині безпечно щось прибрати, і саме його запитає аудитор, коли контейнер буде оголошено привілейованим.

Перегляньте й навколишній контекст, адже мережа хоста, монтування хоста та параметри середовища виконання можуть кожен розширити вплив наданого дозволу. Ізольований лабораторний виклик, що поєднує все це, не є виробничою конфігурацією, хоч би як добре він працював. Перевірте застосунок, його поведінку в DNS і збій тунелю, перш ніж оголосити розгортання завершеним. Дозвіл створити інтерфейс не є політикою виходу, і контейнер, який ідеально тунелює, усе одно маршрутизує все, що надсилає застосунок.

Схожі статті