当 acl 显示 rwx 时,权限被拒绝



我更改了我的服务器;旧的运行Centos 8,新的运行Ubuntu 20.4。现在我的 php 脚本在权限方面有问题 - 为什么?

例:

current user: root
script was executed under user: nobody
Message: fopen(/tmp/RebuildCat_sequence.cnt): failed to open stream: Permission denied

实际上这个文件归nobody所有,所以我根本不应该收到这个警告:

CS-1 01:47:22 :/tmp# ls -latr /tmp/RebuildCat_sequence.cnt
--wxrwxrwT+ 1 nobody nogroup 480 Oct 23 00:02 /tmp/RebuildCat_sequence.cnt

这个php文件通常由cron(root)调用,因为我注意到一些类似的cron触发文件归systemd-timesync所有,我发出了

setfacl -m u:systemd-timesync:rwX /tmp
setfacl -m u:nobody:rwX /tmp

甚至

setfacl -R -m u:nobody:rwX /tmp
setfacl -R -m u:systemd-timesync:rwX /tmp

无济于事。我如何理解这一点?

据我了解,systemd-timesyncnobody的用户都应该能够以/tmp读写文件,而不会因acl而出现问题。我认为必须有人在这里教育我。

/tmp驻留在/dev/md2

CS-1 01:32:34 :/tmp# tune2fs -l /dev/md2 | grep "Default mount options:"
Default mount options:    user_xattr acl

我想这里没问题。

CS-1 01:46:09 :/tmp# getfacl /tmp
getfacl: Removing leading '/' from absolute path names
# file: tmp
# owner: root
# group: root
# flags: --t
user::rwx
user:systemd-timesync:rwx
user:nobody:rwx
group::rwx
mask::rwx
other::rwx

对我来说看起来也不错。无能。

补遗

好的,我设置了chmod 777 /tmp,但仍然fopen(/tmp/RebuildCat_sequence.cnt): failed to open stream: Permission denied出现PHP错误,但file_put_contents777一起使用 - 我如何理解这一点?为什么fopen抛出错误,而file_put_contents不会?

唉,控制台中的chmod 777 /tmp不是答案。它比这复杂得多。所以我一点也不傻。

如何繁殖?

就我而言,我有 2 个 dockerPHP容器写入许多特定于案例的日志文件,其中一个使用apache,另一个nginx。两者都有一个 映射/tmp:/tmp,因此我们可以从主机或容器内部查看文件。

从容器内部,如果所有者是在apache容器中创建的,则apache:apachenginx容器中创建nginx:nginx,但从主机的角度来看,在这两种情况下,它都是针对同一文件的systemd-timesync:systemd-journal

当然,apache容器没有用户nginx,反之亦然(主机也没有)。因此,如果我的PHP脚本想要写入由其他容器创建的文件,我已经说权限问题。

修复

如果在创建时将所有者更改为nobody并具有666权限,则补救措施很容易。

如果没有,我们无法从另一个容器更改所有者并获取failed to open stream: Permission denied.请参阅 https://serverfault.com/questions/772227/chmod-not-working-correctly-in-docker(另请参阅下面有关通过system调用从主机更改权限的讨论)。

所以我写了一个包装函数str_to_file来添加这个操作:

function str_to_file($str, $filename= "/tmp/tmp.txt", $mode="a+") {
if (!file_exists($filename)){
touch($filename);           # create file
chmod($filename, 0666);     # the owner can chmod
chown($filename, 'nobody'); # the owner can chown
} # if (!file_exists($filename))
$mode = $mode == 'w'
? LOCK_EX
:  FILE_APPEND | LOCK_EX;
file_put_contents($filename, $str . PHP_EOL, $mode);
} # str_to_file

这适用于apachenginx容器。

解释

我到底是怎么陷入这个烂摊子的?

看起来要么我在CentOS上没有搞砸它,所以在这种情况下很可能与我切换到Ubuntu无关。我不记得我做了什么,但我不记得我在CentOS上有这种权限问题。

或者CentOS处理容器中创建的文件的方式与Ubuntu.我敢肯定我从未见过用户systemd-timesync:systemd-journalCentOS.不幸的是,我无法不费吹灰之力地调查用户CentOS会从主机的角度替换什么以及这会产生什么后果。

哦,等等,我记得我确实有另一台服务器运行PHP并在CentOS上运行nginx.从容器内创建/tmp文件会显示容器内部和主机的所有者nobody。因此,两个Linux版本之间存在显着差异。

更重要的是,这种见解解释了为什么我只有在从CentOS切换到Ubuntu之后才遇到此权限问题,由于我的提供商出于明显的原因不再提供CentOS,我被迫这样做。

顺便说一下,我首先尝试了CentOS替代品AlmaLinuxRockyLinux,结果不同,最终迫使我使用Ubuntu。这种转换反过来揭示了很多问题,这是最后一个,到目前为止,我花了几个星期的时间。我希望这场噩梦现在结束。

cron开始,apache版本是并且曾经是专门使用的,所以这里没有问题。

最近从浏览器进行测试,我偶然且无缘无故地从apache版本切换到nginx版本,反之亦然,从而产生了这些描述的问题。

实际上,我不知道为什么容器代表这些用户编写。在这两种情况下,容器的用户都是root的,这是docker的标准。我想是浏览器引擎引入了这些用户。

有趣的是,如果我没记错的话,当尝试在创建通过system调用更改权限和所有权时,我失败了,尽管用户应该是root的,root应该能够做到这一点。

事实证明,在apachesystem用户[system('whoami)]不是root而是apache,但是文件所有者是apache,而nginx系统用户是nobody,文件所有者是nginx。因此,使用system更改权限应该适用于apache[system("chmod 0666 $filename"); system("chown nobody:nobody $filename");],但不适用于nginx。唉,它也不适用于apache

快速入住apache集装箱:

/tmp # whoami
root
/tmp # ls -la *6_0.ins
-rw-r--r--    1 apache   apache         494 Nov 14 18:25 tmp_test_t6_0.ins
/tmp # su apache chmod 0666 tmp_test_t6_0.ins
This account is not available

对不起,我无法理解这一点。而且对ACL一无所知。

阿帕奇 vs. 恩金克斯

为什么我首先同时使用两个 Web 服务器版本?

好吧,我调用的进程处理随机数据,这可能需要很长时间,所以很可能nginx超时。这是一个众所周知的nginx功能。

尽管我进行了所有的研究和明显的指示,但我无法管理nginx行为。吉兹语!

最后,作为适当的解决方法,我引入了apache,它没有这个问题。当然,对于体面的运行时,这没有什么区别。

嗯,看起来我有点傻。我确定我在WinSCP(1777) 中仔细检查了对/tmp的权限,但我不确定我是否在控制台中这样做了。

现在我在控制台中发布了chmod 777 /tmp,它就在那里!这个问题消失了。chmod 666 /tmp重新引入了这个问题。chmod 676 /tmp也可以。

我用谷歌搜索了很多关于这个话题的教育自己,但坦率地说我不明白。特别是为什么我一开始就会遇到问题,为什么ACL没有解决问题?我希望得到一些启发。

相关内容

  • 没有找到相关文章

最新更新