所以我想在 systemd 服务中运行 screen,这样我就可以在进程运行时(在守护进程内部)发出命令。请参阅问题末尾的示例,了解我希望能够做什么。
我目前拥有的:
ExecStart=/usr/bin/java -someArguments -jar server.jar
一个以-running 作为守护进程
启动的 java 应用程序,其中 user:group 设置为“server”:“server”,以及“ProtectSystem=full”和类似的强化参数。这运行良好,没有问题。
但是,我想要:
与上面相同,但它在屏幕实例中运行。像这样的东西:
ExecStart=/usr/bin/screen -DmS aServer /usr/bin/java -someArguments -jar server.jar
后者拒绝启动,输出journalctl -xe
告诉我:“无法执行命令:权限被拒绝”。但是,如果我自己在终端中执行此操作(与 ExecStart 中的命令相同),我可以从同一用户(服务器:服务器)启动屏幕会话。
我在网上找到了一个解决方案,上面写着:
# Uncomment this to fix screen on RHEL 8
ExecStartPre=+/bin/sh -c 'chmod 777 /run/screen'
但我本能地不喜欢 777 部分,我也不明白为什么每次守护程序启动时都需要运行它。
我基本上要问的是:如何让屏幕在 systemd 守护进程中工作?上述解决方案是个好主意,还是有更好的方法?
我希望能够做的例子:
- 有一个 systemd 计时器,
ExecStartPre=/screen -p 0 -S -X eval 'stuff "save-all"\\015'
其序列中有一个(或类似的)。 - ExecStop 期间的一系列命令,如上面的命令。
- 当我手动连接到 Linux 服务器(连接到屏幕实例)时,能够与进程交互。
要在 Linux 中将基于 Java 的服务器作为守护程序运行,您可能需要查看 Apache Tomcat 之类的配置。
它从一个名为的服务开始
/etc/systemd/system/tomcat.service
请注意,您的服务器将由脚本中的命令启动
/opt/tomcat/bin/startup.sh
然后您可以执行以下命令:
很抱歉回复晚了,我实际上已经找到并解决了这个问题。
此问题源于基于 RHEL8 的操作系统上的 SELinux 配置。
由于其安装位置,守护程序内部的屏幕被 centos8(可能还有 Rocky Linux 或 RHEL 8 的其他衍生版本)上的 SELinux 阻止。有一些 SEL 策略阻止守护进程在 /usr/bin/ 中执行程序 - 如果我理解正确的话。不幸的是,我不记得我在哪里偶然发现了这些信息。
一种解决方案是在安装屏幕后将其复制到其他位置,例如
/usr/local/bin
. 复制可执行文件后,确保将其所有权root:screen
和权限设置为-rwxr-xr-x (chmod 755)
.然后只需从新位置执行屏幕:
不需要(不要)任何
chmod 777
或ExecStartPre=+ ...
类似的安全性降低解决方案。另一种解决方案是使用 SEL 的 audit2allow 功能,首先找到屏幕被阻止的报告,
/var/log/audit/audit.log
然后使用条目的标识名称(如name=something
),然后将其发送到 audit2allow,如下所示:这应该创建一个允许设置工作的 SELinux 策略。通过运行验证:
semodule -l | grep screen-inside-daemon
并通过测试服务。我没有测试后一种方法,并且我不再有任何实例会包含此问题的日志,因此 audit.log 条目的名称未指定。