systemd: предоставьте непривилегированному пользователю разрешение на изменение одной конкретной службы

20

У меня частный игровой сервер на безголовом ящике Linux. Поскольку я не идиот, указанный сервер работает как собственный непривилегированный пользователь с минимальными правами доступа, необходимыми для загрузки обновлений и изменения мировой базы данных.

Я также создал системный файл systemd для правильного запуска, остановки и перезапуска сервера при необходимости (например, для упомянутых обновлений).

Однако для того, чтобы на самом деле позвонить systemctlили service <game> start/stop/restartмне все еще нужно войти в систему как пользователь root или sudoспособный пользователь.

Есть ли способ сообщить systemd, что для <game>службы непривилегированному пользователю gamesrvразрешено запускать команды start / stop / restart?

Shadur
источник
Какая версия PolicyKit / дистрибутива? Debian (и его производные) находятся на более старой версии, для которой требуется другой формат файла конфигурации .
Герт ван ден Берг

Ответы:

37

Я могу придумать два способа сделать это:


Один из них - сделать сервис пользовательским, а не системным сервисом.

Вместо создания системного блока системный модуль будет помещен в домашний каталог пользователя службы по адресу $HOME/.config/systemd/user/daemon-name.service. Затем тот же пользователь может управлять сервисом с помощью systemctl --user <action> daemon-name.service.

Чтобы устройство пользователя запускать при загрузке , корень должен позволить задерживаться на счет, то есть sudo loginctl enable-linger username. Устройство также должно быть WantedBy=default.target.


Другой способ - предоставить пользователю доступ к управлению системным блоком через PolicyKit. Для этого требуется systemd 226 или выше (и PolicyKit> = 0.106 для файлов JavaScript rules.d - проверьте с помощью pkaction --version).

Вы должны создать новый файл конфигурации PolicyKit, например, /etc/polkit-1/rules.d/57-manage-daemon-name.rulesкоторый проверяет атрибуты, которые вы хотите разрешить. Для примера :

// Allow alice to manage example.service;
// fall back to implicit authorization otherwise.
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        action.lookup("unit") == "example.service" &&
        subject.user == "alice") {
        return polkit.Result.YES;
    }
});

Именованный пользователь может затем управлять именованной службой с использованием systemctlи без использования sudo.

Майкл Хэмптон
источник
Пользовательский режим и loginctlработал.
Шадур
1
Это работает на Ubuntu 16.04? Это нормально, что каталог rules.d не существует? Я не могу заставить его работать. Мои правила игнорируются.
ygoe
3
Нужно ли что-то перезапускать, чтобы включить PolicyKit?
Josir
@MichaelHampton С помощью systemd --user я могу получить все, что хочу, кроме запуска службы при загрузке. Я думаю, что это нормально, так как я читаю это в нескольких местах (например, archlinux wiki), но вы говорите, что это должно работать, вы уверены в этом?
Дакс
@daks Да, это работает. Если у вас все еще есть проблема, задайте новый вопрос.
Майкл Хэмптон
12

sudoсделано для этого. Отредактируйте ваш /etc/sudoersфайл, visudoдобавив a Cmd_aliasдля команд, которые непривилегированный пользователь сможет использовать:

# game server commands
Cmnd_Alias GAME_CMDS = /usr/bin/systemctl start <game service>, /usr/bin/systemctl stop <game service>

и добавьте строку, чтобы позволить непривилегированному пользователю использовать команды, определенные с псевдонимом, например так:

unprivileged_user ALL=(ALL) NOPASSWD: GAME_CMDS

Прочитайте дополнительную документацию по этой теме для различных параметров команды sudo.

Вам может потребоваться установить sudoпакет, чтобы он был sudoдоступен в вашей системе.

Хенрик Пингель Восстановить Монику
источник
Я знаю, как использовать sudo, да. Мне было интересно, есть ли опция, которая позволила бы мне пропустить даже это, поскольку в этом случае первое, что systemdделает файл модуля, это указывает, что его нужно запускать как gamesrv.
Шадур
1

Вы можете ассоциировать sudoс предоставлением доступа, эквивалентного root, но его также можно использовать, чтобы разрешить конкретному пользователю root-доступ для определенного, ограниченного набора команд.

Как на это уже ответили при сбое сервера, в [ Предоставление доступа к набору команд пользователю без полномочий root без sudo полномочий доступа к набору команд для полномочий root без sudo).

Использование PolicyKit все еще редко. Использование системного «пользовательского модуля» должно работать нормально, но исторически ваша цель была достигнута много раз благодаря возможности sudoпозволить пользователю запускать определенные команды от имени пользователя root.

Марк Стосберг
источник