Nginx:浏览时 stat() 失败(13:权限被拒绝)

Nginx: stat() failed (13: Permission denied) when browsing

我想使用网络浏览器列出服务器上的目录。 目录是/srv/downloads/

我安装了 nginx 服务器来做到这一点。这是配置文件:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

并且 conf.d 目录中的 .conf 文件是:

server {
    listen       80 default_server;
    server_name  example.org;
    root     /srv;

    client_max_body_size 64M;

    location /downloads/ {
    autoindex on;
        alias /srv/downloads/;
    allow 192.168.0.0/24;
    allow 10.212.116.0/23;
    deny all;
    }
}

但是当我尝试访问 http://192.168.0.2/downloads/ 时,我能够列出目录,但不能列出所有内容。下面是发生的事情:

2015/04/21 17:08:54 [crit] 12839#0: *1 stat() "/srv/downloads/fix_kernel_doc.patch.done" failed (13: Permission denied), client: 192.168.0.26, server: example.org, request: "GET /downloads/ HTTP/1.1", host: "192.168.0.2"

如nginx.conf所示,nginx服务器是运行用户"nginx"。所以我做了以下事情:

[root@srv]# su -l nginx -s /bin/stat /srv/downloads/fix_kernel_doc.patch.done
Last login: mar. avril 21 17:30:19 CEST 2015 on pts/0
  File: '/srv/downloads/fix_kernel_doc.patch.done'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 85524762    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/    is)   Gid: ( 1000/    devs)
Context: system_u:object_r:var_t:s0
Access: 2015-04-21 17:22:48.393259661 +0200
Modify: 2015-04-21 17:22:48.393259661 +0200
Change: 2015-04-21 17:22:48.393259661 +0200
 Birth: -

我的用户 nginx 在 "devs" 组中。我也尝试使用用户 www-data 来确定,但它也不起作用。

有什么想法吗? 谢谢

根据 Context: system_u:object_r:var_t:s0,我猜您正在使用 SELinux。

SELinux 可能会阻止访问。要验证这是一个 SELinux 问题,请尝试 运行ning setenforce 0 暂时禁用 SElinux,然后重试加载目录。或者,如果确实发生了拒绝,/var/log/audit/audit.log 应该记录拒绝。

如果可行,您将不得不更改目录的上下文以允许 nginx 读取它,或者尝试 运行ning audit2allow 看看是否有 SELinux 布尔值可以更改以允许 nginx 访问。

编辑:由于它是 SELinux,并且只有一个文件夹,因此解决此问题的最简单方法应该是 运行 semanage fcontext -a -t httpd_sys_content_t "/srv(/.*)?",然后是 restorecon -R -v /srv

第一个告诉 SELinux /srv 目录包含 HTTP 服务器的只读内容,第二个将检查并正确地重新标记所有文件。

最后,使用 setenforce 1 重新启用 SELinux。

说明来自 http://www.serverlab.ca/tutorials/linux/web-servers-linux/configuring-selinux-policies-for-apache-web-servers/, https://drupalwatchdog.com/volume-2/issue-2/using-apache-and-selinux-together and http://www.techrepublic.com/blog/linux-and-open-source/practical-selinux-for-the-beginner-contexts-and-labels/

Configure SELinux access so that Apache can access mounted directories 是一个相关问题。

我遇到过这个问题,出于文档目的我对此进行了评论。

示例:

nginx 用户:www-data

    location /sub {
            alias /home/dir1/dir2/dir3;
            autoindex on;
    }

将 www-data 的 r+x 设置为 dir3 的组所有者returns 权限被拒绝

将 www-data 的 r+x 设置为 dir2 的组所有者returns 想要的行为

正在使用递归选项设置权限