尽管使用 PHP 获得了适当的权限,但权限被拒绝

Posted

技术标签:

【中文标题】尽管使用 PHP 获得了适当的权限,但权限被拒绝【英文标题】:Permission denied despite appropriate permissions using PHP 【发布时间】:2011-10-19 22:55:46 【问题描述】:

我正在尝试用 php 读取一个文件,但我收到了一个权限被拒绝的错误,尽管每个人都有对该文件的读取权限。

PHP 代码:

$config=file_get_contents('/opt/jenkins/home/config.xml');

错误:

Warning: file_get_contents(/opt/jenkins/home/config.xml): failed to open stream: Permission denied in [...]

文件系统权限:

有一个符号链接将/opt/jenkins/home/ 指向/var/lib/jenkins,并且每个人都对该符号链接、实际文件夹和文件具有读取权限。

$ ls -lh /opt/jenkins/
lrwxrwxrwx 1 sysadmin sysadmin   16 2011-08-04 08:12 home -> /var/lib/jenkins

$ ls -lh /var/lib/ | grep jenkins
drwxr-xr-- 6 jenkins adm     4.0K 2011-08-04 10:04 jenkins

$ ls -lh /var/lib/jenkins/config.xml
-rwxr-xr-- 1 jenkins adm 3.9K 2011-08-04 10:05 /var/lib/jenkins/config.xml

Apache 配置

配置为遵循符号链接 (Options All)。为/var/lib/jenkins/ 添加Directory 指令没有区别。

<Directory /opt/jenkins/home/>
        Options All
        AllowOverride All
        Order Allow,Deny
        Allow from All
</Directory>

其他信息

无论我使用通过符号链接的路径 ("/opt/jenkins/home/config.xml") 还是真实路径 ("/var/lib/jenkins/config.xml") 我都有同样的问题。

apache2 version=2.2.14-5ubuntu8.4
php version=5.3.2-1ubuntu4.9

知道我为什么会收到错误吗?

【问题讨论】:

is_writable() 返回FALSE? Apache 是否配置为遵循符号链接? afaik 有一个 SymLink 选项 感谢 cmets,但请仔细阅读问题(我想阅读文件,是的,apache follow 配置为遵循符号链接)。 【参考方案1】:

您的目录需要execute 权限才能工作。它似乎没有执行世界,并且由于jenkins 可能不是apache 用户,并且apache 用户不在adm 组中,所以它不起作用:

$ ls -lh /var/lib/ | grep jenkins
drwxr-xr-- 6 jenkins adm     4.0K 2011-08-04 10:04 jenkins

举例:

netcoder@netcoder:~$ mkdir foo
netcoder@netcoder:~$ echo hello > foo/bar
netcoder@netcoder:~$ chmod 777 foo/bar
netcoder@netcoder:~$ ls -lsah foo/bar 
4.0K -rwxrwxrwx 1 netcoder netcoder 6 2011-08-04 08:22 foo/bar
netcoder@netcoder:~$ chmod 444 foo/
netcoder@netcoder:~$ ls -lsah | grep foo
4.0K dr--r--r--  2 netcoder netcoder 4.0K 2011-08-04 08:22 foo
netcoder@netcoder:~$ cat foo/bar 
cat: foo/bar: Permission denied

虽然foo/bar0777权限,但如果目录没有执行权限,则拒绝读取其内容。

您需要为目标目录和符号链接设置权限。

【讨论】:

所以他需要在真实目录或符号链接上设置执行权限? 必须设置在两者上,或者设置在他在file_get_contents() 中使用的那个上? /opt/jenkins/home/ 是符号链接,必须有执行权限。 /var/lib/jenkins/ 是符号链接目标,它也必须有执行权限。由于他正在阅读/opt/jenkins/home/config.xml(它在/opt/jenkins/home/ 目录中),因此目标和符号链接都需要执行权限。如果他直接从/var/lib/jenkins/ 读取,他显然不需要符号链接的执行权限。 我必须设置整个目录树的权限包含目标文件才能工作。【参考方案2】:

您需要在层次结构中的所有目录上设置执行位,直到该文件。

chmod o+x /var/lib/jenkins

应该可以解决问题。

(注意:ls -lhd /var/lib/jenkinsls -lh ...|grep jenkins 好一点)

【讨论】:

【参考方案3】:

许多现代机器(数字海洋、机架空间等)都带有用于 RedHat 兼容操作系统(如 CentOS)的 SELinux(安全增强 Linux)。这会给您需要牢记的工作带来另一个麻烦。你可以完美地设置你的权限,它仍然会说权限被拒绝。你需要为 SELinux 定义一个可写的上下文:

sudo chcon -t httpd_sys_rw_content_t /data/www/html/sites/mysite -R

【讨论】:

【参考方案4】:

很可能您的 apache 用户不允许读取或访问 Web 文件

    检查 apache 以什么用户身份运行:

    $ ps aux | grep [a]pache
    root     40283  0.0  0.2 472548 21116 ?        Ss   14:38   0:00 /usr/sbin/apache2 -k start
    www-data 40287  0.0  0.1 472760  8800 ?        S    14:38   0:00 /usr/sbin/apache2 -k start
    www-data 40288  0.0  0.1 472760  8540 ?        S    14:38   0:00 /usr/sbin/apache2 -k start
    www-data 40289  0.0  0.1 472776  8540 ?        S    14:38   0:00 /usr/sbin/apache2 -k start
    

    检查您的网络文件的路径所有权:

    $ namei -mol /home/john/app2/
    f: /home/john/app2/
    drwxr-xr-x root root  /
    drwxr-xr-x root root  home
    drwx------ john john  john         # <== Ahaa, no access for apache user!
    drwxr-xr-x john john  john app2
    

    相应地调整权限:

好吧,在这一步中,我将由您自己决定,您可以(a) 在此示例中将 apache 用户设置为 'john'强>。或者,您可以(b) 将网络文件夹移至家外。在不破坏安全良好实践的情况下,可以向组甚至其他人授予执行访问权限。

一个。让 apache 成为用户 john(仅适用于开发站点或如果您知道自己在做什么)

sudo vi /etc/apache2/envars 
# replace 
export APACHE_RUN_USER=www-data 
export APACHE_RUN_GROUP=www-data
# with
export APACHE_RUN_USER=john 
export APACHE_RUN_GROUP=john

b.把那个文件夹移出家门……它到底在做什么?

sudo mv /home/john/app2 /var/www/

记得更改站点以匹配此目录并重新启动 apache 服务器。

以下是一些参考资料:

https://wiki.apache.org/httpd/13PermissionDenied

http://wiki.apache.org/httpd/FileSystemPermissions

【讨论】:

以上是关于尽管使用 PHP 获得了适当的权限,但权限被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

尽管获得了完全许可,但 aws iam 用户访问被拒绝

尽管有权限,但 mongod 权限被拒绝

尽管获得许可,但写入外部存储的权限被拒绝

Laravel 权限被拒绝 bootstrap/cache/packages.phpkC7P4V 无法打开流:权限被拒绝

Django Rest:为啥访问被拒绝,尽管 AccessAny 被设置为权限?

PHP mkdir:权限被拒绝问题