PHP执行的Bash脚本无法列出/var/tmp目录内容或在其中创建文件
PHP执行的Bash脚本无法列出/var/tmp目录内容或在其中创建文件
看起来你已经做了一堆权限相关的排查工作,但偏偏卡在/var/tmp这个特殊目录上——我猜大概率是systemd的PrivateTmp机制在搞鬼,这是Ubuntu 22.04上Apache服务的默认配置,专门用来隔离服务的临时目录。
问题根源:Apache的私有临时目录
Ubuntu 22.04的Apache服务默认开启了PrivateTmp=yes,这会让Apache进程(包括PHP-FPM或mod_php)看到的/var/tmp其实是一个隔离的虚拟目录,和系统真实的/var/tmp完全不是同一个地方。这就解释了为什么你用www-data用户在命令行能正常操作/var/tmp,但通过PHP调用脚本却不行——两种场景下的/var/tmp根本不是一回事!
验证这个猜测
先在你的bash脚本里加几行输出,确认当前进程看到的临时目录:
echo "Current TMPDIR: $TMPDIR" echo "Listing process root var/tmp:" ls -ld /proc/self/root/var/tmp
执行后如果输出的TMPDIR是类似/tmp/systemd-private-xxxxxx-apache2.service-xxxxxx/var/tmp这样的路径,那实锤就是PrivateTmp在作祟。
解决步骤
修改Apache的systemd配置(不要直接修改原服务文件,用override方式更安全):
sudo systemctl edit apache2在打开的编辑器里添加以下内容:
[Service] PrivateTmp=no保存退出。
重新加载systemd配置并重启Apache:
sudo systemctl daemon-reload sudo systemctl restart apache2恢复/var/tmp的默认权限(之前你去掉了sticky位并改成777,这会带来安全风险):
sudo chmod 1777 /var/tmp sudo chown root:root /var/tmp
额外注意事项
- 如果你用的是PHP-FPM而不是mod_php,需要检查PHP-FPM的systemd服务文件(比如
/lib/systemd/system/php8.1-fpm.service),同样看是否有PrivateTmp=yes,如果有也需要用override改成no。 - 尽量避免给
www-data用户过多sudo权限,尤其是NOPASSWD的全局权限,这会带来很大的安全隐患。解决PrivateTmp问题后,应该可以去掉sudoers里相关的配置。
现在再测试你的bash脚本,应该就能正常访问真实的/var/tmp目录了!
备注:内容来源于stack exchange,提问作者Sheikh Muhammed Tadeeb
相关产品推荐
相关产品推荐

