systemd:授予非特权用户更改一项特定服务的权限

systemd:授予非特权用户更改一项特定服务的权限

我在一台无头 Linux 机器上运行一个私人游戏服务器。因为我不是白痴,所以该服务器以自己的非特权用户身份运行,只具有下载更新和修改世界数据库所需的最低访问权限。

我还创建了一个 systemd 单元文件,以便在需要时正确启动、停止和重新启动服务器(例如,对于上述更新)。

然而,为了真正地呼叫systemctlservice <game> start/stop/restart我仍然需要以 root 或有能力的用户身份登录sudo

有没有办法告诉 systemd,对于该<game>服务,非特权用户gamesrv可以运行启动/停止/重启命令?

答案1

我想到两种方法来做到这一点:


一种方法是将服务变为用户服务而不是系统服务。

systemd 单元将放置在服务用户的主目录下,而不是创建系统单元$HOME/.config/systemd/user/daemon-name.service。然后,同一个用户可以管理服务systemctl --user <action> daemon-name.service

允许用户单位开机启动,root 必须为该账户启用 linger,即sudo loginctl enable-linger username。单位也必须是WantedBy=default.target


另一种方法是允许用户通过 PolicyKit 管理系统单元。这需要 systemd 226 或更高版本(JavaScript rules.d 文件需要 PolicyKit >= 0.106 – 请查看pkaction --version)。请注意,Debian 故意将 PolicyKit 保留为近十年前的 0.105 版本,该版本不支持此功能,显然是因为个人观点,并且它以及从其衍生的发行版(例如 Ubuntu)都不能使用此方法。

您将创建一个新的 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

答案2

sudo就是为此而制作的。使用 编辑/etc/sudoers文件以visudo添加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在您的系统上使用。

答案3

您可能将sudo其与提供相当于的访问权限联系起来root,但它也可以用于允许特定用户对特定的、有限的命令集进行根访问。

如何做到这一点已经在 Server Fault 上得到解答了,网址为 [向非 root 用户授予一组命令的访问权限(无需 sudo)非 root 用户无需 sudo 即可访问一组命令)。

sudo使用 PolicyKit 仍然不常见。使用 systemd “用户单元”应该可以正常工作,但从历史上看,通过使用允许用户以 root 身份运行特定命令的功能,您的目标已经多次实现。

相关内容