Демону VPN потрібні привілейовані мережеві операції, хоча звичайні застосунки відкривають вихідні сокети взагалі без привілеїв. Саме в цій прогалині починається більшість помилок із можливостями: хтось бачить помилку прав, надає весь набір, і сервіс працює з причин, які потім ніхто не може пояснити. Розбір нижче починається з невдалої операції, зіставляє її з одним повноваженням, а потім перевіряє контекст, у якому процес справді працює. Робота від імені необмеженого root — слушна відповідь для деяких розгортань, але це має бути рішенням, а не типовим значенням.

Почніть з операції, яка не вдалася

Прочитайте помилку, перш ніж читати посібник. «Операція не дозволена» під час зміни інтерфейсу, відмова відкрити вузол пристрою і збій bind на низькому порту — це три різні проблеми з трьома різними дозволами. Якщо процес запускається і зривається лише на першій зміні маршруту, це також означає, що створення інтерфейсу вже вдалося, що помітно звужує відповідь.

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

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

Таблиця — це відправна карта, а не заміна документації реалізації:

OperationUsual authorityWatch for
Create or configure tun/tapCAP_NET_ADMIN in the relevant namespaceCreating the device and opening it are separate steps
Add routes, rules, firewall entriesCAP_NET_ADMINSame capability, different namespace than you think
Open /dev/net/tunDevice permissions, not a capabilityGroup membership or a udev rule may be enough
Raw socketsCAP_NET_RAWNeeded by some user-space tunnel implementations
Bind a port below 1024CAP_NET_BIND_SERVICEIrrelevant for most modern tunnel ports

Два рядки в цій таблиці — ті, які люди плутають. Відкрити /dev/net/tun — це питання прав на файл; попросити ядро налаштувати те, що ви відкрили, — це питання можливостей. Надання CAP_NET_ADMIN не виправляє вузол пристрою, який користувач сервісу не може прочитати, а виправлення вузла не дає вам прав на маршрути. Перевірте і те, і те, перш ніж щось змінювати.

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

Прочитайте контекст: сервіс, контейнер чи оболонка

Можливість у мережевому просторі імен хоста може вплинути значно сильніше, ніж та сама операція в навмисно ізольованому стеку. Середовище виконання контейнерів зазвичай стартує зі зменшеним набором обмежень; додати NET_ADMIN контейнеру, який ділить мережу хоста, — це значно більший дозвіл, ніж контейнеру з власним мережевим простором імен і без монтувань хоста.

Для юнітів systemd читайте те, що реально застосовується, а не те, що нібито каже файл юніта: systemctl show -p CapabilityBoundingSet -p AmbientCapabilities повідомляє чинні значення, які могли бути встановлені забутим drop-in. Питайте чинне значення, ніколи — передбачуване. Можливості ambient важливі, бо сервіс не від root втрачає можливості під час exec без них.

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

Спостерігайте, що відбувається після падіння привілеїв

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

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

Реалізації, які тримають тунель відкритим під час зміни користувача, зазвичай поєднують це з опціями збереження тунелю й ключів. На боці systemd еквівалентне питання — чи переживає набір можливостей юніта налаштовану вами зміну користувача.

Запишіть наданий дозвіл і його причину

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

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

Схожі статті