我在 RedHat 8.8 中有一个由 systemctl 运行的服务。服务本身比较简单:
cat /etc/systemd/system/myservice.service
[Unit]
Description=My service
After=network-online.target
[Service]
Type=forking
User=myuser
Group=mygroup
Restart=no
TimeoutSec=60
ExecStart=/usr/lib/myapp/service.sh start
ExecStop=/usr/lib/myapp/service.sh stop
[Install]
WantedBy=multi-user.target
设置 Sudoers 文件,以便“mygroup”的所有成员都能够以“myuser”的名称执行此服务:
%mygroup ALL = (ALL : myuser) NOPASSWD: /usr/bin/systemctl start myservice
问题出在 service.sh 文件中。序言是#!/bin/sh
。它尝试启动 JBoss 实例,并执行一些操作,例如:
cat /dev/null > $JBOSS_CONSOLE_LOG
START_FILE="${JBOSS_HOME}/start_user"
ACCESS_USER="$(who am i | awk '{print $1}')"
echo "${ACCESS_USER}" > ${START_FILE}
现在,当我通过 SSH 使用“myuser”登录并通过 启动此服务时sudo systemctl start myservice
,我收到上述命令的一堆权限被拒绝错误:
当尝试将 devnull 放入 JBOSS_CONSOLE_LOG 时:
/usr/lib/myapp/service.sh: line 82: /opt/myapp/home/domain/log/console.log: Permission denied
当尝试打印到 START_FILE 时:
/usr/lib/myapp/service.sh: line 92: /opt/myapp/home/start_user: Permission denied
据我所知,文件权限设置正确,所有内容均由“myuser”和“mygroup”拥有:
ll /opt/myapp
drwrwxr-x+ 11 myuser mygroup 4096 Nov 14 20:56 home
ll /opt/myapp/home
drwxrwxr-x+ 10 myuser mygroup 4096 Nov 14 20:29 domain
ll /opt/myapp/home/domain
drwxrwxr-x+ 10 myuser mygroup 4096 Nov 14 20:29 log
当我直接从终端执行相同的命令时,它工作正常。当我制作一个简单的 test.sh 文件并将命令放在那里时,它再次运行正常。因此,运行服务脚本时必须更改一些内容,但我不确定为什么。我还注意到该脚本尝试确定 ACCESS_USER 变量,如下所示:
ACCESS_USER="$(who am i | awk '{print $1}')"
它得到一个空结果。但是当我在终端上运行相同的命令时,它会正确打印“myuser”。它也适用于我的 test.sh 文件。
我应该从哪里开始?这是我正在使用的某种产品,所以我一定会联系他们的支持人员,但也许我也会从这里得到一些想法。
编辑:感谢您的评论,我会尽力回答。
@Chris Davies:$JBOSS_CONSOLE_LOG 是 /opt/myapp/home/domain/log/console.log,$JBOSS_HOME 是 /opt/myapp,我已经在原来的问题中共享了所有者。还要感谢“whoami”和“我是谁”之间的解释,我以前读过它们,但现在很明显我需要一个终端来让“我是谁”工作。
@waltinator 和 @muru:这个脚本不是从 crontab 运行的,它是在我启动提到的服务时执行的:sudo systemctl start myservice
,请参阅我原来问题中的服务描述。 “myuser”用户被添加到 sudoers 文件中,以便它可以启动服务。
@rivimey:我正在打印“id”命令和“whoami”命令的输出,它显示了正确的用户:
echo "id = $(id), whoami = $(whoami)
id = uid=1001(myuser) gid=1001(mygroup) groups=1001(mygroup) context=system_u:system_r:unconfined_service_t:s0, whoami = myuser
此外,当我检查“ps -ef”输出中正在运行的脚本时,它还显示执行它的正确用户。
编辑 2:啊,这是 SELinux...当我输入之前的编辑内容时,我想到禁用它,现在该服务可以正常工作了。奇怪的是,因为我尝试手动检查审计日志并使用audit2allow命令检查审计日志,所以我得到了一些“缺失类型强制”规则,但与我的应用程序没有任何关系。如果我没有得到更好的解决方案,我会将其作为答案发布。