Служба запускається, журнал скаржиться, що не може відкрити пристрій tun, а маршрути так і не з'являються. Виконайте capsh --print у своїй оболонці, і cap_net_admin опиниться тут же, через що збій здається неможливим. Різниця між вашою оболонкою та юнітом — це перехід привілеїв, а не готовність ядра надати можливість. Пройдіть чотири перевірки нижче по черзі й зупиніться на першій, яка пояснює розрив.

Відокремте відсутню можливість від прихованого пристрою

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

Перш ніж щось змінювати, перевірте, чи існує пристрій у просторі імен служби. PrivateDevices=yes — поширений рядок зміцнення, який повністю видаляє вузол tun, а обмежувальний ProtectSystem може зробити шлях конфігурації лише для читання так, що це читається як помилка прав. Обидва дають рядки журналу, які згадують тунель, тому вину покладають на можливості. Спершу переконайтеся, що вузол наявний і відкривається, потім рухайтеся далі.

Знайте, на який набір можливостей ви дивитеся

Linux тримає набори дозволених, дієвих, успадковуваних, обмежувальних і оточуючих можливостей, і саме оточуючий набір переживає exec від користувача не-root. Файлові можливості на бінарнику можуть передати дозволені й дієві права під час exec, але лише доки ніщо в ланцюгу не блокує цю передачу.

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

Дайте можливість у юніті, а не в обгортці

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

[Unit]
Description=OpenVPN client, office profile
After=network-online.target

[Service]
Type=notify
User=openvpn
Group=openvpn
NoNewPrivileges=yes
AmbientCapabilities=CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_ADMIN
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/office.conf

AmbientCapabilities поміщає право в оточуючий набір до запуску процесу, а CapabilityBoundingSet не дає процесу тримати будь-що поза цим списком. NoNewPrivileges=yes блокує отримання привілеїв через setuid або файлові можливості, а можливість, яку юніт надає явно, усе одно діє. Додавайте CAP_NET_BIND_SERVICE лише коли службі треба зайняти низький порт, і ніколи не додавайте CAP_SYS_ADMIN лише тому, що так зробила тема на форумі.

Якщо юніт обгортає бінарник у sudo, приберіть обгортку. systemd уже застосовує User=, і саме цей зайвий шар — найімовірніша причина порожнього оточуючого набору.

Перевіряйте на живому процесі, а не на файлі юніта

Прочитайте, що менеджер фактично застосував, а потім прочитайте процес, який він породив.

unit=openvpn-client@office
systemctl show -p User -p AmbientCapabilities "$unit"
systemctl show -p MainPID --value "$unit" | xargs -r getpcaps
grep -E '^Cap(Eff|Amb)' /proc/$(systemctl show -p MainPID --value "$unit")/status

Якщо юніт перелічує можливість, а CapEff досі її не має, якийсь drop-in перевизначає налаштування або крок ExecStartPre змінює середовище. Перш ніж вважати основний файл головним, пошукайте ім'я юніта в каталогах drop-in, бо пізніший файл тихо перемагає. Якщо і юніт, і процес показують можливість, а тунель усе одно не працює, поверніться до перевірок пристрою та шляху, а не розширюйте обмежувальний набір. Його розширення приховує справжню причину й залишає службу привілейованішою, ніж вона була.

Волійте скидати привілеї після запуску

OpenVPN може стартувати з привілеями, а потім перейти на непривілейований обліковий запис через власні опції user і group, а persist-key і persist-tun зберігають тунель придатним далі. Така схема звужує вікно, у якому процес тримає права, і часто пасує краще, ніж запуск усього демона без привілеїв із постійними можливостями.

Яку б модель ви не обрали, перезапустіть юніт і повторіть перевірки після перезавантаження, бо служба, яка працює з інтерактивної оболонки root і збоїть під час завантаження, зазвичай відрізняється саме можливістю, пристроєм або правами файлу. Запишіть налаштування юніта поруч із виводом можливостей процесу, щоб наступний рецензент бачив, чи зсунуло межу оновлення пакета або drop-in.

Схожі статті