systemctl service systemd-notify 不适用于非 root 用户

Posted

技术标签:

【中文标题】systemctl service systemd-notify 不适用于非 root 用户【英文标题】:systemctl service systemd-notify not working with non-root user 【发布时间】:2019-11-25 08:38:16 【问题描述】:

我有一个在 Red Hat Enterprise Linux 7 上使用 Type=notify 的服务单元和 bash 脚本的简单示例,我正在尝试开始工作。

当服务单元配置为以 root 身份启动脚本时,一切都会按预期进行。添加User=testuser 时失败。虽然脚本最初启动(如进程列表所示),systemctl 服务从未收到指示就绪的通知消息,因此它挂起并最终超时。

[Unit]
Description=My Test
[Service]
Type=notify
User=testuser
ExecStart=/home/iatf/test.sh
[Install]
WantedBy=multi-user.target

Test.sh(由具有执行权限的testuser拥有)

#!/bin/bash

systemd-notify --status="Starting..."
sleep 5
systemd-notify --ready --status="Started"

while [ 1 ] ; do
  systemd-notify --status="Processing..."
  sleep 3
  systemd-notify --status="Waiting..."
  sleep 3
done

当以 root 身份运行时 systemctl status test 会显示从我的 test.sh bash 脚本发送的正确状态和状态消息。当User=testuser 服务挂起然后超时,journalctl -xe 报告:

Jul 15 13:37:25 tstcs03.ingdev systemd[1]: Cannot find unit for notify message of PID 7193.
Jul 15 13:37:28 tstcs03.ingdev systemd[1]: Cannot find unit for notify message of PID 7290.
Jul 15 13:37:31 tstcs03.ingdev systemd[1]: Cannot find unit for notify message of PID 7388.
Jul 15 13:37:34 tstcs03.ingdev systemd[1]: Cannot find unit for notify message of PID 7480.

我不确定这些 PID 是什么,因为它们没有出现在 ps -ef 列表中

【问题讨论】:

【参考方案1】:

这似乎是notify 服务类型中的已知限制

从pull request 到systemd 手册页

    Due to current limitations of the Linux kernel and the systemd, this
    command requires CAP_SYS_ADMIN privileges to work
    reliably. I.e. it's useful only in shell scripts running as a root
    user.

我尝试了一些与sudo 和朋友一起使用的hacky 解决方法,但它们不会像systemd 那样工作——通常以失败告终

No status data could be sent: $NOTIFY_SOCKET was not set

这是指systemd-notify 尝试向其发送数据的套接字 - 它在服务环境中定义,但我无法将其可靠地暴露在 sudo 环境中

您也可以尝试使用here 中描述的 Python 解决方法

python -c "import systemd.daemon, time; systemd.daemon.notify('READY=1'); time.sleep(5)"

它基本上只是一个不可靠的睡眠,使用notify 的重点是可靠的服务。

在我的情况下 - 我只是重构为使用 root 作为用户 - 实际服务作为所需用户的主要服务下的子服务

【讨论】:

在手册页中找不到这个了。这个问题解决了吗? @adrelanos 我昨晚的研究表明,这已在 systemd 246 中修复(但尚未在 ubuntu 20.04 中登陆)。特别是修复了问题的this PR,首先登陆了246-rc1。 @djsavvy systemd 246 很可能永远不会登陆 20.04 - 鉴于 systemd 是它在操作系统生命周期内基本上锁定的初始化系统。如果这是您想要的东西,我会考虑更新的操作系统 我不明白为什么 python 解决方法中有time.sleep(5)。我删除了它,我注意到有时通知不起作用,因为发生超时。如果删除 sleep 对此负责,我会感到困惑。 sleep真的有必要吗?【参考方案2】:

sudo -u USERACCOUNT_LOGGED 通知发送“你好”

【讨论】:

以上是关于systemctl service systemd-notify 不适用于非 root 用户的主要内容,如果未能解决你的问题,请参考以下文章

systemd和systemctl详解

CentOS7+Nginx设置Systemctl restart nginx.service服务

linux 下的 service 和systemctl 服务管理方式

自定义 systemctl 管理服务

CentOS7 systemctl添加自定义系统服务

如何编写systemctl自启动服务 service文件