PHP: 获取真实 /tmp 路径的方法?

PHP: way to get the true /tmp path?

我正在将我的网络应用程序从 CentOS 5 转移到 CentOS 7,有关 /tmp 目录的新安全功能正在破坏我的代码。我想知道如何最好地处理它。

我有 PHP 创建 LaTeX 文件的代码,然后执行命令将其转换为 PDF,然后使用适当的 headers 将其提供给用户。以下是目前的一些相关代码行:

$fileroot = "/tmp/addr".getmypid();
ob_start();
/* echo all the LaTeX stuff */
file_put_contents($fileroot.".tex",ob_get_contents());
ob_end_clean();
exec("cd /tmp;uplatex -interaction=batchmode --output-directory=/tmp $fileroot", $output, $return);

/usr/lib/systemd/system/php-fpm.service 中的设置包括 PrivateTmp=true,这导致 PHP 函数调用中的 /tmp 实际上是 /tmp/systemd-private-6898f2d665d64b998981bc479ddc2306-php-fpm.service-KU8XML/tmp。哎呀!这对于安全性来说很好,但是 exec() 按字面意思使用 /tmp 路径,因此它找不到 file_put_contents() 刚刚创建的文件。 PHP 函数 sys_get_temp_dir() 只是 returns /tmp,我找不到任何包含该路径的环境变量。有没有办法以编程方式获取该路径?或者我需要关闭 PrivateTmp 吗?或者有更好的方法来做我需要做的事情吗?是的,我可以用 wide-open 权限创建我自己的特殊位置,但似乎只使用普通的临时目录应该更干净。

在我看来,只有两个选择:

  1. 不要使用 /tmp,而是使用您在应用程序配置文件中预定义的不同目录。我最近做了类似的事情,我使用 /var/run/myapplication 目录而不是 /tmp。 (我还必须添加一个 cron 作业来清理它。)

  2. 在 php-frm 服务中禁用 PrivateTmp。这是执行此操作的一种方法:

    # mkdir  /usr/lib/systemd/system/php-fpm.service.d
    # echo -e "[Service]\nPrivateTmp=no" > /etc/systemd/system/php-fpm.service.d/privatetmp.conf
    # systemctl daemon-reload
    # systemctl restart php-fpm
    
    # systemctl show php-fpm | grep PrivateTmp
    PrivateTmp=no
    

我遇到了同样的问题(在 CentOS 上)并通过以下步骤修复它。

nano /usr/lib/systemd/system/httpd.service

查看文件并 PrivateTmp=falsePrivateTmp=true

systemctl daemon-reload
service http restart

准备就绪

我刚刚遇到了类似的问题。这是一种使用 PrivateTmp(在本例中为 apache2)找出系统服务的 "real" 临时路径的方法:

 grep -oP ' /tmp/systemd-private-[^/]+-apache2[^/]+/tmp(?= /tmp)' /proc/`pgrep apache2 -o`/mountinfo

它的作用:

  • 搜索最早的 apache2 进程的进程 ID:pgrep apache2 -o
  • 读取 /proc/PID/mountinfo 文件,其中包含此进程看到的挂载信息
  • 使用 grep
  • 使用正则表达式提取私有 tmp 文件夹

可能是以后的systemd版本或者设置不同,正则表达式需要调整,如果命名不同。您也可以只使用 ' /tmp[^ ]+(?= /tmp)' 作为正则表达式。

请注意,了解路径可能对您没有多大帮助。私人临时文件夹有严格的权限,只允许 root 访问。

Aleks G 是正确的方法,但如果您仍然遇到问题,请尝试此方法。

我尝试了 "multi-user.target.wants" 解决方案,它有效,但在重新启动后,但在某些时候,PrivateTmp 返回 true。 就像我对 Apache2 的主要用途是 PHP,我最终编辑了 php.ini 并取消了 sys_temp_dir.

行的注释

默认情况下,系统使用函数 sys_get_temp_dir 分配的临时目录。函数 sys_get_temp_dir 将 return "/tmp" 但事实是您的 tmp 文件存储在某些路径,例如 /tmp/systemd-private-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-apache2.service-YYYYYY//tmp/*。所以,对我来说工作是:

编辑 php.ini(路径可以在 PHP 个版本之间更改)

sudo nano /etc/php/7.2/cli/php.ini

然后取消注释 sys_temp_dir 行

; Directory where the temporary files should be placed.
; Defaults to the system default (see sys_get_temp_dir)
sys_temp_dir = "/tmp"