Capsudo: альтернативный sudo с object-capability для безопасного запуска команд

Представлен capsudo — альтернативный вариант sudo, реализующий модель разделения полномочий на уровне отдельных объектов. Автор проекта — Ариадна Конилл (Ariadne Conill), известная по разработке аудиоплеера Audacious, композитного сервера Wayback, участию в создании протокола IRCv3 и руководству командой безопасности в Alpine Linux. Новый инструмент предназначен для безопасного запуска команд с повышенными привилегиями и опирается на концепцию object-capability. Код написан на C и распространяется под свободной лицензией MIT.

Какие проблемы sudo пытается решить capsudo

Классический sudo исторически сложился как мощный, но громоздкий инструмент, и у него накопилось несколько архитектурных слабых мест, на которые и нацелен capsudo:

- sudo устанавливается как suid-root бинарник, то есть сам исполняемый файл может выполнять код с правами суперпользователя;
- утилита монолитна: вся логика — от парсинга конфигурации до проверки политик и запуска команд — выполняется в одном привилегированном процессе от имени root;
- формат конфигурации сложен, слабо структурирован, не декларативен и плохо масштабируется в крупных инфраструктурах;
- поддержка плагинов реализована так, что сторонний код исполняется прямо внутри привилегированного процесса, что расширяет возможную поверхность атаки;
- база исходного кода значительно разрослась, из-за чего увеличиваются риски ошибок и уязвимостей.

capsudo предлагает иной подход к управлению привилегиями, стремясь минимизировать последствия потенциального взлома и упростить модель безопасности.

Архитектура capsudo: разделение на демон и клиент

Вместо одного suid-бинарника capsudo разделён на две части:

1. capsudod — фоновый демон, работающий с повышенными привилегиями. Он отвечает за непосредственный запуск команд от имени root (или другого системного пользователя).
2. capsudo — непривилегированная клиентская утилита, которой пользуется обычный пользователь. Она связывается с демоном и запрашивает выполнение конкретной операции.

Общение между клиентом и демоном реализовано через файловый сокет (Unix domain socket). Именно этот сокет и становится носителем «полномочия» на выполнение привилегированной операции. Фактически, право запускать ту или иную команду определяется не сложным синтаксисом конфигурации, а правами доступа к конкретному сокету.

Только тот пользователь (или группа), у которого есть возможность обращаться к нужному сокету (чтение/запись), может инициировать привилегированный запуск связанной с этим сокетом команды. Это и есть воплощение object-capability-модели: «объектом» выступает сокет, а «capability» — возможность использовать его для запуска определённого действия.

Пример: предоставление права на reboot конкретному пользователю

Представим задачу: нужно разрешить одному пользователю перезагружать систему, не выдавая ему полный доступ root и не настраивая сложные правила в sudo.

С помощью capsudo это делается следующим образом:

1. Администратор запускает capsudod и создаёт файловый сокет, например в домашнем каталоге пользователя, с названием `reboot-capability`.
2. Этот сокет привязывается к конкретной привилегированной команде — в данном случае к утилите `reboot`.
3. На уровне файловых прав администратор задаёт, что записывать в этот сокет и обращаться к нему может только заданный пользователь.

После такой настройки пользователю достаточно выполнить:

```bash
capsudo -s reboot-capability
```

и capsudo, связавшись через этот сокет с демоном capsudod, инициирует выполнение команды reboot от имени root. Пользователь при этом не получает каких-либо дополнительных полномочий, кроме строго определённого права — перезагрузки системы.

Повторение поведения sudo для группы wheel

capsudo позволяет воссоздать привычную модель sudo, когда все пользователи из определённой группы (часто это `wheel`) имеют возможность запускать произвольные команды с повышенными правами.

Для этого администратор может:

1. Создать каталог для сокетов, например `/run/cap`.
2. Запустить capsudod с созданием сокета, допустим `/run/cap/sudo-capability`.
3. Назначить группой владельцем этого сокета группу `wheel`.
4. Выставить права доступа таким образом, чтобы доступ к сокету был только у членов этой группы.

После этого любой пользователь, входящий в `wheel`, сможет вызывать:

```bash
capsudo -s /run/cap/sudo-capability
```

и использовать этот сокет как универсальный канал для выполнения привилегированных команд, подобно тому, как это делается с `sudo`. Детальная политика того, что именно разрешено запускать через этот сокет, определяется конфигурацией демона capsudod.

Пример настройки для привилегированного запуска mount

Частый сценарий в администрировании — предоставить пользователю или группе право монтировать определённый диск без полного доступа root. С capsudo это делается на уровне одной «возможности»:

- создаётся отдельный сокет, например `/run/cap/mount-sdb1`;
- сокет ассоциируется с командой `/usr/sbin/mount /dev/sdb1`;
- на сокет выдаются права конкретному пользователю или группе.

Далее пользователь просто выполняет:

```bash
capsudo -s /run/cap/mount-sdb1
```

и получает возможность смонтировать `/dev/sdb1`, при этом не имея доступа к запуску других `mount` или любых иных команд с повышенными привилегиями.

Плюсы и минусы предложенного подхода

Преимущества capsudo по сравнению с классическим sudo:

- Жёсткое разделение привилегий. Привилегированный код работает только в демоне, а клиент — обычная программа без suid-флагов.
- Минимизация поверхности атаки. Нет необходимости исполнять плагины внутри root-процесса; каждая capability-«точка входа» более узко заточена под конкретную задачу.
- Прозрачность модели безопасности. Права выражены через права доступа к сокетам: видно, кто и что может сделать, достаточно посмотреть на файловую систему и уровни доступа.
- Гибкость привязки. Легко выдать отдельный «жетон» на конкретную операцию: перезагрузка, монтирование, управление сервисами и т.д.

Однако у подхода есть и очевидный недостаток, о котором прямо заявляет автор:

- для координации каждой привилегированной операции требуется работа отдельного фонового процесса (демона capsudod), а также управление его жизненным циклом;
- администратору приходится следить за тем, чтобы нужные сокеты были созданы, корректно привязаны к командам и имели правильные права доступа;
- некоторые сценарии, легко решаемые в sudo одной строчкой в конфигурации, могут потребовать в capsudo создания множества отдельных сокетов и соответствующей «разметки» прав.

Object-capability в администрировании: зачем это нужно

Модель полномочий на уровне объектов (object-capability) давно применяется в проектировании безопасных систем, но не так часто встречается в повседневном системном администрировании. В контексте capsudo это означает, что:

- полномочия не формулируются в формате «пользователь X может делать операции Y от имени Z где-то в системе»;
- вместо этого существуют объекты (сокеты), обладание которыми уже само по себе даёт конкретное право — например, запуск только одной жёстко предопределённой команды.

Такой подход особенно интересен в следующих сценариях:

- контейнеры и изолированные окружения, где нужно чётко выдать минимум прав для выполнения определённой задачи;
- инфраструктуры с большим количеством автоматизации, где отдельным сервисам или скриптам нужно выдать строго ограниченный набор действий с правами root;
- системы с высоким уровнем требований к аудиту и соответствию политикам безопасности: легче показать, что каждому действию соответствует конкретный, физически существующий объект-«ключ».

Сравнение с doas и другими минималистичными инструментами

Помимо sudo в мире Unix есть и другие инструменты для делегирования привилегий, например doas. Он решает часть проблем sudo за счёт более простого и компактного кода, а также сильно упрощённой конфигурации. Пример записи в doas:

```bash
permit user1 as root cmd reboot
```

Однако и sudo, и doas остаются в парадигме «правил»: конфигурационный файл описывает, кто и что может сделать. capsudo смещает акцент к материальным объектам — сокетам, владение которыми уже становится разрешением на действие. Это не обязательно «лучше» или «хуже», но по-другому структурирует политику безопасности и может оказаться удобнее там, где легко управлять файловой системой и правами, но не хочется держать сложную логику в одном конфиге.

Практические сценарии использования capsudo

Некоторые типичные случаи, где capsudo может раскрыть свои сильные стороны:

1. Раздача узких прав разработчикам. Например, дать право перезапускать только один конкретный сервис, не предоставляя возможности выполнять произвольные команды от имени root.
2. Инфраструктура CI/CD. Конвейеры сборки могут получать сокеты-«ключи» для выполнения строго определённых privileged-операций (например, обновлений пакетов или перезапуска демонов) без доступа к полноценному sudo.
3. Рабочие станции с высоким уровнем безопасности. Пользователям не выдают общий доступ к sudo, а вместо этого создают набор capability-сокетов: один для монтирования флешки, другой — для перезагрузки, третий — для управления VPN.
4. IoT и встраиваемые системы. Там, где система ограничена по ресурсам и важна предсказуемость поведения, capsudo даёт возможность чётко задать, какие именно привилегированные действия вообще существуют и кто может к ним обращаться.

Особенности администрирования и внедрения

При внедрении capsudo администратору стоит учитывать несколько моментов:

- первоначальная настройка потребует продумать модель: какие команды действительно нужны с повышенными привилегиями, а что можно выполнить без root;
- важно аккуратно управлять каталогами с сокетами (например `/run/cap`), обеспечивая корректные права и очистку неиспользуемых объектов;
- логирование операций через capsudod может стать отдельной точкой контроля и аудита — стоит сразу продумать интеграцию с системным журналированием;
- нужно следить, чтобы пользователи не могли подменить исполняемые файлы, к которым привязаны capability-сокеты (например, не позволять им перезаписывать бинарник `reboot` или скрипт, вызываемый через capsudo).

Итог

capsudo предлагает альтернативное видение того, как должны предоставляться привилегии в Unix-подобных системах. Вместо громоздкой конфигурации и единого suid-бинарника он использует архитектуру «демон + непривилегированный клиент» и опирается на object-capability-модель через файловые сокеты. Это позволяет точечно выдавать права на конкретные операции, уменьшать поверхность атаки и повышать предсказуемость поведения системы. Взамен администратору приходится управлять отдельным фоновым процессом и следить за жизненным циклом множества capability-сокетов. Для сред, где безопасность и контроль важнее удобства классического sudo, такой подход может оказаться особенно привлекательным.

Прокрутить вверх