为什么从 PHP 运行时 tmux 无法读取会话文件?

问题描述 投票:0回答:1

我想创建一个可以管理多个会话并从中读取内容的 PHP 站点。因此,为了实现这一点,我决定将

tmux
与 PHP
exec()
命令一起使用。

会话将在用户

www-data
下运行,每个会话运行各自的任务。

我使用以下代码来获取 PHP 中所有正在运行的会话的列表:

$command = "tmux -S /tmp/tmux-33/default ls";
$command."<br>";
exec($command . " 2>&1", $output, $result_code);

$output = JSON_Format($output);
echo "$output<br>";

这回响了

tmux -S /tmp/tmux-33/default ls
[ "no server running on \/tmp\/tmux-33\/default" ]

这意味着该文件不存在,对吗? 好吧,不。那是因为如果我打开终端并运行

sudo tmux -S /tmp/tmux-33/default ls

比输出是

0: 1 windows (created Sat Mar  9 18:09:34 2024)
2: 1 windows (created Sat Mar  9 18:16:42 2024) (attached)

甚至用纳米输出读取文件

[ Error reading /tmp/tmux-33/default: No such device or address ]
,这证明文件存在。

我可以确认

tmux-33
对应于
www-data
,因为如果我不提供-S参数,它默认为该文件。

我试图确认

www-data
是否正确配置的另一件事是直接连接到它的 shell,如下所示:

codrut@Linux-Server:/tmp$ sudo -u www-data -s /bin/bash
www-data@Linux-Server:/tmp$ tmux list-s
0: 1 windows (created Sat Mar  9 18:09:34 2024)
2: 1 windows (created Sat Mar  9 18:16:42 2024) (attached)
www-data@Linux-Server:/tmp$

很明显,apache 帐户可以读取这两个会话,但不能使用

exec
从 PHP 读取。我也尝试了
shell_exec
,但结果相同。

似乎用户superfuzzy也有这个问题。对于他们来说,降级到 PHP 7.1 修复了该错误。我正在运行 PHP 8.3.3-1。不幸的是,我无法降级到旧版本,因为我的网站基础设施很大程度上依赖于 PHP 8 中引入的新功能。

用户superfuzzy还注意到以下内容

另一个奇怪的事情:当通过 php 启动 tmux 会话时,终端没有用户,也没有位置 通常它看起来像 user@machinename$ ... 对于 php,它看起来就像 $ ...仅此而已

经过一番挖掘,我发现这是由于 Apache2 使用“/bin/sh”作为 shell 造成的。在 Ubuntu 中,默认不是“/bin/bash”,而是“/bin/dash”,根据我的理解,这是 bash 的更轻量级、更快的版本,功能较少。但根据我的测试,这不会以任何方式影响 tmux。

我还尝试创建一个

test.sh
脚本,然后在该脚本上执行
/bin/bash
。脚本如下:

#/bin/bash
echo "test script"
tmux ls

输出: [“测试脚本”,“/tmp/tmux-33/default 上没有运行服务器”]

那么我能做些什么,或者可能有一些

exec()
功能的替代方案吗?我真的很感激一些建议。

谢谢你。

php linux bash shell tmux
1个回答
0
投票

该问题是由 Linux 中的 systemd 服务管理器允许访问

/tmp/folder
引起的。或者换句话说,它不这样做。

我发现我通过 PHP 在

/tmp/
文件夹中写入的所有文件实际上都被写入到
/tmp/systemd-private-<GUID>-apache2.service-mMSZ8e/tmp

这是一项安全功能,旨在禁止不同服务使用已知文件名窥探

/tmp/
文件夹中的数据。 有关此内容的更多信息,请阅读此处

由于 tmux 使用 /tmp/ 文件夹来存储会话,因此无法读取所需的文件。

这个问题有两种解决方案

推荐的方法

这需要使用

-f
参数将 tmux 指向已知文件。

示例:

tmux -f /home/user1/tmux/knownfile

禁用 Apache2 的 Primate
/tmp
文件夹(不推荐)

这需要编辑 apache2 的 systemd 服务并将 PrivateTmp 设置为 false,不建议这样做,因为它可能会引入 PHP 脚本访问敏感文件或其他程序访问脚本敏感文件的安全问题。

可以通过如下编辑文件来完成:

sudo nano /lib/systemd/system/apache2.service

然后更换

PrivateTmp=true

PrivateTmp=false
© www.soinside.com 2019 - 2024. All rights reserved.