позволить пользователю запускать службы systemctl/systemd без пароля

Вопрос или проблема

У меня есть сервис в Linux под названием appSevice. Когда я запускаю и останавливаю его с помощью этих команд, он работает:

sudo systemctl start appSevice.service;
sudo systemctl stop appSevice.service;

Но когда я пытаюсь выполнить их из JAVA-кода, например:

Runtime.getRuntime().exec(new String[]{"systemctl", "stop", "appService.service"});

…это не работает, и я получаю ошибку:

>  Failed to stop appService.service: Interactive authentication required

Вот мой сервис:

[Service]
Type=simple
ExecStart=/opt/soft/v1/launchAppService.ksh start
User=Jms-User
Restart=on-abort

Есть ли способ избежать этой ошибки и запускать сервис без ввода пароля?

Есть три способа сделать это:

  1. Поместите appService.service в ~/.config/systemd/system/ и удалите строку User=. Затем вы можете контролировать это с помощью:
systemctl --user start appService.service
systemctl --user stop appService.service
  1. Добавьте правило polkit. Думаю, этот вопрос близок к тому, что вы ищете: systemd start as unprivileged user in a group. Если вы используете debian/ubuntu (polkit < 106), то подойдет следующее:
/etc/polkit-1/localauthority/50-local.d/service-auth.pkla
---
[Allow yourname to start/stop/restart services]
Identity=unix-user:youname
Action=org.freedesktop.systemd1.manage-units
ResultActive=yes

Если вы используете Arch/Redhat (polkit >= 106), то подойдет следующее:

/etc/polkit-1/rules.d/service-auth.rules
---
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        subject.user == "yourname") {
        return polkit.Result.YES;
    } });
  1. sudo. Я не большой фанат этого, потому что sudo не должен полагаться на конфигурацию NOPASSWD:, и я считаю, что он не предназначен для косвенного вызова. Для этого предназначен polkit.
/etc/sudoers.d/sysctl
---
youname ALL = NOPASSWD: /bin/systemctl

Если это для программного обеспечения, которое вы планируете распространять, я бы, конечно, выбрал решение с polkit и делал бы это по группе (как указано в приведенном ответе). Это означает, что вам не нужно жестко кодировать имя пользователя, вместо этого добавьте любых пользователей, которые вам нравятся, в эту группу, чтобы получить функциональность.

Может быть, вам стоит создать юнит от пользователя?

systemctl edit --user --force --full myNewUnit

Новым файлом откроется редактор ~/.config/systemd/user/myNewUnit.service. Вставьте содержимое, сохраните и работайте с ним без прав root.

systemctl enable --user myNewUnit
systemctl start --user myNewUnit
systemctl status --user myNewUnit

Если нужно редактировать, откройте без --force

systemctl edit --user --full myNewUnit

Надеюсь, я ничего не перепутал и это будет полезно.

Ни одно из этих решений мне не подходит, у меня все еще появляется запрос пароля… (systemd на CentOS 7.9) Единственным решением на данный момент является добавление полного пути для запуска и остановки службы в sudoers и использование его напрямую вместо команды systemctl. Я пытался настроить sudoers с полным путем, с теми же параметрами, без ввода пароля, используя Cmnd_alias, также пробовал вариант с polkit и “systemctl –user” без успеха. Также пытался изменить права user:group на разных systemd или исполнить стартовые файлы и прочее, но это не помогло.

У кого-нибудь есть другие идеи? Или решения, случайно?
Спасибо

Ответ или решение

Разрешение пользователя на запуск служб systemctl/systemd без ввода пароля является распространенной задачей, сталкиваться с которой приходится многим администраторам Linux. Причины для этого могут включать автоматизацию процедур, упрощение доступа конечным пользователям или интеграцию с другими системами, такими как, в вашем случае, Java-приложение. Рассмотрим три основных подхода, которые могут помочь в решении этой задачи.

Теория

При вызове команд systemctl для управления системными службами, такими как appService, необходимо подтверждение прав администратора, так как эти действия могут изменять состояние системы. Таким образом, необходимо предоставить пользователям соответствующие права доступа, чтобы они могли выполнять эти команды без авторизации. Для достижения этой цели можно использовать несколько методов:

  1. Локальные пользовательские единицы systemd: Перемещение ваших служб в пользовательское пространство (подкаталог ~/.config/systemd/user/) позволяет управлять ими без административных привилегий.

  2. Политики доступа polkit: Политики polkit позволяют настроить правила, которые управляют доступом к действиям systemd в зависимости от конкретных пользователей или групп.

  3. Использование файла конфигурации sudoers: Настройка файла sudoers для предоставления конкретного действия systemctl без пароля.

Примеры

Пользовательские единицы systemd

Переместите appService в пользовательское пространство таким образом, чтобы не нужно было указывать пользователя в файле системной службы. Это позволит использовать команды управления службами от имени пользователя:

systemctl --user start appService.service
systemctl --user stop appService.service

Создайте или переместите файл службы в ~/.config/systemd/user/. Таким образом, вы сможете управлять этой службой без административных привилегий. Это наиболее простой способ в случае, если ваш рабочий процесс и подходы к безопасности это позволяют.

Политики polkit

Для настройки polkit на Debian/Ubuntu (до версии 106) создайте файл /etc/polkit-1/localauthority/50-local.d/service-auth.pkla, используя следующую конфигурацию:

[Allow yourname to start/stop/restart services]
Identity=unix-user:yourname
Action=org.freedesktop.systemd1.manage-units
ResultActive=yes

Для Arch/Redhat (версии после 106) используйте следующий шаблон в /etc/polkit-1/rules.d/service-auth.rules:

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" && subject.user == "yourname") {
        return polkit.Result.YES;
    }
});

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

Файл sudoers

И, наконец, добавьте следующую строку в файл /etc/sudoers.d/sysctl, чтобы разрешить выполнение команды systemctl без пароля:

yourname ALL = NOPASSWD: /bin/systemctl

Это решение может быть полезно, если другие методы не сработают. Однако стоит отметить, что этот подход не всегда безопасен, если ваш сервер предоставлен большому числу пользователей.

Применение

Каждое из решений имеет свои плюсы и минусы в зависимости от вашего конфигурационного окружения и административных политик. Хорошим стилем считается использование polkit благодаря его гибкости и возможности работы с конкретными группами пользователей. Организация управления службами через пользовательское пространство с использованием --user также часто используется в сценариях, где риск небезопасного развертывания минимален.

Как только вы определили предпочтительное решение, интеграция с Java может быть улучшена за счет выполнения команд через Java с использованием сложившейся конфигурации прав:

Runtime.getRuntime().exec(new String[]{"systemctl", "--user", "start", "appService.service"});

Это позволит приложению Java взаимодействовать с systemd без необходимости запрашивать пароли, обеспечивая гладкую интеграцию в вашей инфраструктуре.

Выбирая подход, ориентируйтесь на ваши операционные задачи и уровни безопасности. Пользовательские рабочие пространства и политики polkit представляют наибольшую гибкость, а настройки sudoers, хотя порой и работающие полностью, могут представлять риск, если не организованы должным образом.

Оцените материал
Добавить комментарий

Капча загружается...