我们如何允许非 root 用户控制 systemd 服务?

Bel*_*dez 91 sudo systemd not-root-user services

使用sysvinit,这样的sudoers条目就足够了:

%webteam cms051=/sbin/service httpd *
Run Code Online (Sandbox Code Playgroud)

这将允许以下命令:

  • sudo service httpd status
  • sudo service httpd restart

现在,使用systemd,服务名称是最后一个参数。即,服务重启将通过以下方式完成:

systemctl restart httpd.service
Run Code Online (Sandbox Code Playgroud)

自然,我认为定义命令systemctl * httpd.service会起作用,但这会允许类似systemctl restart puppet.service httpd.service的效果不是预期的。

考虑到这一点,那么允许非 root 用户控制systemd服务的最佳方式是什么?这不需要是sudoers;也许文件权限更改可能就足够了?

jof*_*fel 60

只需将所有需要的命令sudoers分别添加到:

%webteam cms051=/usr/bin/systemctl restart httpd.service
%webteam cms051=/usr/bin/systemctl stop httpd.service
%webteam cms051=/usr/bin/systemctl start httpd.service 
%webteam cms051=/usr/bin/systemctl status httpd.service
Run Code Online (Sandbox Code Playgroud)

  • status 没有用,因为任何用户都可以这样做 (16认同)
  • 什么是“cms051”? (10认同)
  • @kevin cms501 是主机名或主机名列表别名。见 https://linux.die.net/man/5/sudoers (2认同)
  • 那么,如果我调用 systemctl restart http.service mariadb.service 会发生什么;-) ?可能 mariadb 也会重新启动 (2认同)
  • 这仍然适用于最近的 Linux 系统(例如 Ubuntu)吗?因为如果我这样做,我会收到一个身份验证请求:`需要身份验证才能开始......`。 (2认同)

小智 55

@jofel 的回答正是我获得工作设置所需的。为任何在这个问题上绊倒的人发布这个。capistrano从本地机器部署后,我需要一种方法来重新启动我的 Ruby 应用程序。这意味着我需要无密码访问才能重新启动systemd服务。这就是我所拥有的,而且效果很好!

注意:我的用户和组deployer
在此处称为将代码放入自定义文件中:/etc/sudoers.d/deployer
代码:

%deployer ALL= NOPASSWD: /bin/systemctl start my_app
%deployer ALL= NOPASSWD: /bin/systemctl stop my_app
%deployer ALL= NOPASSWD: /bin/systemctl restart my_app
Run Code Online (Sandbox Code Playgroud)

  • 我需要补充一点,在这种情况下,以用户 `deployer` 登录后,你应该使用 sudo 运行 `systemctl` 命令。 (5认同)
  • 似乎不适用于 Ubuntu 20.04。 (3认同)
  • 这对我来说效果很好,太棒了! (2认同)
  • 如果在 CentOS 上:```deployer ALL=(ALL) NOPASSWD:/bin/systemctl reload httpd,/bin/systemctl status httpd``` (2认同)

小智 10

使用您希望他们有权访问的命令创建命令别名。然后将该组分配给该命令别名:

Cmnd_Alias APACHE-SVC = /usr/bin/systemctl stop httpd, /usr/bin/systemctl start httpd, /usr/bin/systemctl restart httpd

%webteam ALL=APACHE-SVC
Run Code Online (Sandbox Code Playgroud)

将任何编辑放在 /etc/sudoers.d/filename 中而不是直接编辑 sudoers 文件也是一种很好的做法。确保在 sudoers 中指向您的 .d/filename,大多数新发行版都会这样做。将这两行放在你的 sudoers 中应该可以解决问题:

## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
#includedir /etc/sudoers.d
Run Code Online (Sandbox Code Playgroud)

注意:includeir 前面的# 不是注释。它必须保留。


小智 8

在 RHEL8 中:

httpd.service另一种选择是在 webteam 主目录下 有一个文件~/.config/systemd/user,他们可以自己启动/停止/启用等:

systemctl --user enable httpd.service
systemctl --user start httpd.service
Run Code Online (Sandbox Code Playgroud)

验证只要用户有权启动该服务,上述操作就有效。这在开发系统上似乎很有用,允许开发人员使用 devops/ops 手中可用的所有配置有效地执行计时器和管道。

似乎也有利于将其转移到生产环境,并使用构建的 httpd 操作在实际服务器环境中测试整个启动序列,并且开发人员不会说“但它在我的笔记本电脑上工作,当我推送到开发人员时崩溃了” 。但我只是在这里思考和写作。

最好的在线参考,因为 systemd 用户文档并不丰富:

https://wiki.archlinux.org/title/systemd/User


Jan*_*der 7

按照jofel 的建议逐项列出它们是最安全的。

如果我想允许某人使用命令能力的有限子集,我不会相信 sudoers 行中的通配符来做到这一点。即使该语言比 shell glob 更具表现力,也有太多的极端情况需要跟踪。

" service httpd *" 行相对安全,因为 (验证这一点:)service只有一个有用的标志 ( --status-all) 不会做任何特别敏感的事情,并且(也验证一下:)/etc/init.d/httpd将只接受您想要允许的命令行。

如果有太多的组合,列出它们变得尴尬,你可能应该质疑你在做什么。但是您可以让他们访问精心编写的帮助脚本,该脚本为他们运行命令(很像/etc/init.d/http)。即使在这种情况下,您也应该尽可能准确和明确地列出允许的命令和选项,并且不要将任何用户输入直接传递给目标命令。