这是我在这个论坛上的第一篇文章,由于这个问题的性质,我不得不来到这里。我和我的老板都对可能发生的事情感到困惑,因此不得不去找这里的专家。
作为前言,我是一家小公司的初级 Web 开发人员,无法直接访问公司的服务器配置。我所有的工作都是在 docker 本地完成的,然后提交给老板批准。如果您需要我们设置的任何具体细节,我很乐意用您需要的任何内容更新帖子。
不管怎样,正如本文的标题所示,我们一直在慢慢地将我们的 Web 应用程序从带有 Apache2 的 Debian Stretch 迁移到带有 Apache 2 的 Debian Bullseye。
我们在此服务器环境中运行 3 个 Web 应用程序,其中 2 个是 PHP,1 个是 Perl。所有 3 个都为我们的用户提供文件上传功能。
为了增加可能的复杂性,我的老板运行了三台网络服务器。 web01 和 web02 正在运行工作 Stretch 版本。然后,他尝试向 web03 启动我们的 Bullseye 更新,以进行软部署和小型用户测试。
现在,作为一名初级开发人员,我在本地 docker 环境中测试时完全忽略了这个错误。我的老板在部署到 web03 后才发现这个上传问题。请注意,这个上传问题同时影响了我们的 PHP 和 Perl Web 应用程序,因此它似乎与配置有关,而不是与代码有关。Bullseye 部署中的其他一切都运行良好,但文件上传和检索是唯一困扰我们的错误,我找不到其他有这个特定问题的人。
下面是 Perl 程序中的一个简单代码片段。它喜欢在这一行失败,并声称它无法修改 /tmp 目录,尽管它已经存在。
open(my $fh, "<", "/tmp/$csvfile") or die "Can't open $csvfile: $!";
这是我老板的直接引述,描述了他所看到的情况。
遇到一个奇怪的问题,找不到上传到 /tmp 的文件。我知道 systemd 对 apache2 /tmp 做了一些奇怪的事情,并将其指向一个单独的私有文件夹,但在stretch中已经是这种情况了。靶心中的某些东西似乎更能打破它。它不是特定于 perl 或 php 的,因为应用程序 1 和应用程序 2 都会受到影响。 jobtracker 给出“找不到文件 /tmp/xxxxx.csv”错误。应用程序 2 抱怨磁盘空间不足,但这只是默认错误,因为它无法确定正在上传的文件大小。
当我上传某些内容时,我可以清楚地看到 /tmp/systemd-..../tmp/ 路径上的时间戳正在更新,因此它正在执行某些操作,我只是不知道它在哪里失败。
我确实已经达到了后端知识的极限,但我真的很想帮助我的老板,并通过拯救世界来获得一些奖励积分。
请告诉我是否有更合适的地方来发布此内容,但我的直觉告诉我,如果两种不同语言的两个应用程序都遇到相同的文件上传问题,那么这是 Debian 或 Apache2 配置问题。
我的老板最初认为这可能是一个负载平衡问题,因为所有三个 Web 服务器都同时运行,但即使 web03 独立于我们的 web01 和 02 环境运行,他也重现了上传问题。我的 docker 环境也遇到了同样的错误,除了数据库访问之外,它应该在自己的本地化环境中运行,对吗?
如果有人需要更多背景信息,请随时询问。我会尽力提供背景信息。
答案1
Debian 11 运行时的 apache 设置systemd
位于/lib/systemd/system/apache2.service
并包含在以下[Service]
部分中:PrivateTmp=true
,即有记录的作为:
PrivateTmp=
采用布尔参数。如果属实,设置新的文件系统命名空间 对于已执行的进程和安装私人
/tmp/
和/var/tmp/
内部不被命名空间外的进程共享的目录。这对于安全访问进程的临时文件很有用,但是/tmp/
通过或 进行进程之间的共享/var/tmp/
不可能。如果为 true,服务停止后,这些目录中由服务创建的所有临时文件都将被删除。默认为 false。
[...]
所以apache2
是/tmp/
隐藏的并且与初始主机的不同/tmp/
。
当然,人们可以覆盖该设置(使用sysctl edit apache2
并添加带有 的服务部分PrivateTmp=false
),但不建议这样做:私人/tmp
是为了额外的安全性,并且其他打包的应用程序很可能也有相同的设置,并且也会必须更改(似乎并非如此php-fpm
)。最好有一个专用目录来共享此目录并相应地重新配置应用程序。
如果只是为了调试或简单地找出这些隐藏文件在哪里,那么有一个快捷方式可以访问进程的挂载命名空间,而无需使用unshare -m
这对于这些情况来说通常很困难。/proc/<pid>/root/
是到此进程挂载的命名空间/挂载点的直接链接。例如,如果pgrep -u root ^apache2$
给出一个 PID 结果(或者如果随机选择任何生成的 apache2 PID),例如 12345,那么ls /proc/12345/root/tmp/
将显示现在隐藏的内容/tmp/
。也可以通过这种方式将文件复制到那里或从那里复制文件,但这不应该用于任何严重的事情。这记录在man proc
。