允许用户在没有密码的情况下运行 systemctl/systemd 服务

yoy*_*oyo 5 linux java

我在 linux 中有一个服务,appSevice 当我使用这些命令启动和停止时,它可以工作:

sudo systemctl start appSevice.service;
sudo systemctl stop  appSevice.service;
Run Code Online (Sandbox Code Playgroud)

但是当我尝试从 JAVA 代码执行这些时,例如:

Runtime.getRuntime().exec(new String[]{"systemctl", "stop", "appService.service"});
Run Code Online (Sandbox Code Playgroud)

...它不起作用,我收到此错误:

>  Failed to stop appService.service: Interactive authentication required
Run Code Online (Sandbox Code Playgroud)

这是我的服务:

[Service]
Type=simple
ExecStart=/opt/soft/v1/launchAppService.ksh start
User=Jms-User
Restart=on-abort
Run Code Online (Sandbox Code Playgroud)

有没有办法避免这个错误并在不提供密码的情况下运行服务?

Ste*_*art 11

有以下三种方法:

  1. 放入appService.service~/.config/systemd/system/取出User=线。然后你可以通过以下方式控制它:
systemctl --user start appService.service
systemctl --user stop appService.service
Run Code Online (Sandbox Code Playgroud)
  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
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 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;
    } });
Run Code Online (Sandbox Code Playgroud)
  1. sudo。我不太喜欢这个,因为sudo不需要依赖NOPASSWD:配置,而且我不认为它被设计为间接调用。这就是 polkit 的设计目的。
/etc/sudoers.d/sysctl
---
youname ALL = NOPASSWD: /bin/systemctl
Run Code Online (Sandbox Code Playgroud)

如果这是您计划分发的软件,我肯定会使用 polkit 解决方案并按组进行(根据链接的答案)。这意味着您不必对用户名进行硬编码,而是将您喜欢的用户添加到该组中以获得该功能。