Какие возможности Linux нужны вашему процессу VPN?
Настройка интерфейса, маршруты, доступ к устройствам и обычные сокеты — это отдельные привилегии. Назовите операцию, которая не удалась, прежде чем выдавать CAP_NET_ADMIN.
Демону VPN нужны привилегированные сетевые операции, хотя обычные приложения открывают исходящие сокеты вообще без привилегий. Именно в этом разрыве начинается большинство ошибок с возможностями: кто-то видит ошибку прав, выдаёт весь набор, и сервис работает по причинам, которые потом никто не может объяснить. Разбор ниже начинается с неудавшейся операции, сопоставляет её с одним полномочием, а затем проверяет контекст, в котором процесс действительно работает. Работа от имени неограниченного root — допустимый ответ для некоторых развёртываний, но это должно быть решением, а не значением по умолчанию.
Начните с операции, которая не удалась
Прочитайте ошибку, прежде чем читать руководство. «Операция не разрешена» при изменении интерфейса, отказ открыть узел устройства и сбой bind на низком порту — это три разные проблемы с тремя разными разрешениями. Если процесс запускается и срывается только на первом изменении маршрута, это также означает, что создание интерфейса уже удалось, что заметно сужает ответ.
Воспроизведите сбой при остановленном сервисе, затем запустите его на переднем плане под тем же пользователем, если реализация это позволяет. Ошибка, которую вы видите, лучше строки журнала, о которой приходится догадываться, и она делает очевидной разницу между проблемой возможностей и отказом SELinux или AppArmor.
Сопоставьте каждую операцию одному полномочию
Таблица — это отправная карта, а не замена документации реализации:
| Operation | Usual authority | Watch for |
|---|---|---|
| Create or configure tun/tap | CAP_NET_ADMIN in the relevant namespace | Creating the device and opening it are separate steps |
| Add routes, rules, firewall entries | CAP_NET_ADMIN | Same capability, different namespace than you think |
| Open /dev/net/tun | Device permissions, not a capability | Group membership or a udev rule may be enough |
| Raw sockets | CAP_NET_RAW | Needed by some user-space tunnel implementations |
| Bind a port below 1024 | CAP_NET_BIND_SERVICE | Irrelevant 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 в сетевом пространстве имён юнита, нужен для изменений маршрутов после переподключения» — достаточно, чтобы следующий человек не расширил разрешение снова.
Затем перечитывайте действующий набор после каждого обновления. Поставщики добавляют функции, образы меняют значения по умолчанию, и возможность, ненужная в прошлом году, может стать несущей без ведома всех.