我在一台无头 Linux 机器上运行一个私人游戏服务器。因为我不是白痴,所以该服务器以自己的非特权用户身份运行,只具有下载更新和修改世界数据库所需的最低访问权限。
我还创建了一个 systemd 单元文件,以便在需要时正确启动、停止和重新启动服务器(例如,对于上述更新)。
然而,为了真正地呼叫systemctl
,service <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 身份运行特定命令的功能,您的目标已经多次实现。