Nginx 403错误:禁止访问目录索引 [folder]。

294

我有三个域名,想要将这三个网站都托管在一个服务器上(Digital Ocean droplet)使用 Nginx。

mysite1.name mysite2.name mysite3.name

但只有其中一个网站能够正常工作。其它两个会出现相同的 403 错误。

在我的 Nginx 错误日志中,我看到了这样一条错误信息:[error] 13108#0: *1 directory index of "/usr/share/nginx/mysite2.name/live/" is forbidden

我的 sites-enabled 配置文件如下:

server {
        server_name www.mysite2.name;
        return 301 $scheme://mysite2.name$request_uri;
}
server {
        server_name     mysite2.name;

        root /usr/share/nginx/mysite2.name/live/;
        index index.html index.htm index.php;

        location / {
                try_files $uri $uri/ /index.html index.php;
        }

        location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
        }
}

所有3个网站的配置文件几乎相同。

每个网站的文件都在像/usr/share/nginx/mysite1.name/someFolder这样的文件夹中,然后/usr/share/nginx/mysite1.name/live是该文件夹的符号链接。mysite2和mysite3同理。

我查看了Nginx 403 forbidden for all files,但没有帮助。

有什么想法可能出了什么问题吗?


51
我认为你缺少了 index.htmlindex.php 文件,你确定它们在那个文件夹中存在吗? - Mohammad AbuShady
哦,你说得对;两个无法工作的站点分别是一个Laravel项目(其中index.php位于/public子文件夹中)和一个旧的CodeIgniter项目(其中index.php位于/public_web子文件夹中)。但我不确定如何更改我的配置以使这些站点正常工作。 - Ryan
就像@MohammadAbuShady所说,我在文件夹中没有索引文件,因此出现了这个错误。 - ajon
我又遇到了这个错误,但这次问题是我不小心将 root 设置为 /Users/myUsername/code/app 而非 /Users/myUsername/code/app/public - Ryan
这就是服务器管理员大显身手的时候。 - OldFart
21个回答

308

如果您已关闭目录索引,并且遇到了此问题,则很可能是由于您正在使用带有目录选项的try_files导致的:

location / {
  try_files $uri $uri/ /index.html index.php;
}                 ^ that is the issue

移除它,然后它应该可以工作:

location / {
  try_files $uri /index.html index.php;
} 

为什么会发生这种情况

TL;DR:这是因为nginx会尝试索引目录,但被自身阻止。从而导致OP提到的错误。

try_files $uri $uri/ 的意思是,从根目录开始,先尝试请求uri指向的文件,如果不存在,则请求一个目录(因此需要 /)。当nginx访问一个目录时,它会尝试对其进行索引,并将该目录中的文件列表返回给浏览器/客户端。但是默认情况下,目录索引已禁用,因此会返回“Nginx 403错误:禁止 [folder] 目录索引”错误消息。

目录索引由autoindex选项控制:https://nginx.org/en/docs/http/ngx_http_autoindex_module.html


1
这正是我遇到的问题。我不明白为什么 try_files 没有尝试 index.php,我一直收到 "directory index of ... is forbidden" 的 403 错误提示。 - Travis D
4
@JCM,您介意解释一下为什么使用$uri/会出现问题吗? - Ian Dunn
也解决了我的问题 - alariva
1
我遇到了同样的错误。我有两个站点,都在子域中。移除$uri/就解决了问题。谢谢! - jivanrij
5
try_files $uri $uri/表示从网站的根目录开始,尝试访问URI所指向的文件,如果文件不存在,则尝试访问一个目录(因此有/符号)。当Nginx访问一个目录时,它会尝试对其进行索引,并将目录中的文件列表返回给浏览器/客户端。然而,默认情况下目录索引是禁用的,因此会返回错误“Nginx 403 error: directory index of [folder] is forbidden”。目录索引由autoindex选项控制:http://nginx.org/en/docs/http/ngx_http_autoindex_module.html。 - jonathancardoso
显示剩余6条评论

77

以下是可行的配置:

server {
    server_name www.mysite2.name;
    return 301 $scheme://mysite2.name$request_uri;
}
server {
    #This config is based on https://github.com/daylerees/laravel-website-configs/blob/6db24701073dbe34d2d58fea3a3c6b3c0cd5685b/nginx.conf
    server_name mysite2.name;

     # The location of our project's public directory.
    root /usr/share/nginx/mysite2/live/public/;

     # Point index to the Laravel front controller.
    index           index.php;

    location / {
        # URLs to attempt, including pretty ones.
        try_files   $uri $uri/ /index.php?$query_string;
    }

    # Remove trailing slash to please routing system.
    if (!-d $request_filename) {
            rewrite     ^/(.+)/$ /$1 permanent;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #   # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    #   # With php5-fpm:
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param                   SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

}

然后浏览器中唯一的输出是 Laravel 错误:“哎呀,看起来出了些问题。”

不要运行chmod -R 777 app/storage (注意)。让某个文件可以被任何人写入是不安全的。

chmod -R 755 app/storage 是更安全的方法。


1
是的,你们说得对;那是个不好的主意。我会更新我的答案。人们也可能从https://dev59.com/0Gct5IYBdhLWcg3wk-Vq#11996645中受益。 - Ryan
1
您可能还可以将文件夹的组更改为debian上的nginx组,例如www-data。然后将文件夹设置为更严格的权限,例如:chmod -R 640 app/storage 然后 chown -R :www-data app/storage。这样,文件仅可对应用程序所有者和Web服务器可见,没有任何人可以直接执行存储(可能已上传)文件中的任何内容。 Nginx只需要读取访问文件的权限即可。 - complistic
4
备忘录:我又一次遇到了 Nginx 403 错误,原因是我无意中在 root /usr/share/nginx/mysitename/public/; 中漏掉了 public/。加上 public/ 并运行 service nginx restart 后,问题得以解决。 - Ryan
Windows怎么样? - Himanshu Bansal
为了防止nginx的错误日志,或者支持具有自定义错误处理的框架,您可能需要一个index index.php /index.php;指令或类似的内容。 - peorthijel

74
如果您只是想列出目录内容,请使用autoindex on;,例如:
location /somedir {
       autoindex on;
}

server {
        listen   80;
        server_name  example.com www.example.com;
        access_log  /var/...........................;
        root   /path/to/root;
        location / {
                index  index.php index.html index.htm;
        }
        location /somedir {
               autoindex on;
        }
}

13
我绝对不希望开启“自动索引”,将我的目录内容暴露给公众是一个坏主意。 - Ryan
7
@Ryan,这总归归结为“你想做什么?” - Bhargav Nanekalva
21
显然,他希望消除403错误并使网页显示而非显示整个目录内容(尤其是考虑到以上讨论)。 - jpmorris
3
就我个人而言,我来到这个问题是为了寻找autoindex选项,因为它是在Google上搜索该错误的第一个结果。 - user4945014

39

我遇到了类似的错误:
---在网页中看到“403 Forbidden”
---在/var/log/nginx/error.log的错误日志中看到“13:Permission denied”

下面是三个步骤可以解决问题:

1:打开终端,看到以下内容:

user1@comp1:/home/www/

所以,我的用户名是"user1"(来自上文)

2: 在/etc/nginx/nginx.conf中更改了用户

# user www-data;
user user1;

重新加载了nginx

sudo nginx -s reload  
此外,在执行上述三个步骤之前,我已经应用了文件/文件夹权限
(对于我的目录,如/dir1/,设置为755)和该目录下的文件(设置为644):
(我不确定是否真的需要这一额外步骤,以上3个步骤可能已经足够)
chmod 755 ./dir1/
chmod 644 ./dir1/*.*

希望这能快速帮助到有需要的人,祝你好运。


2
谢谢兄弟,我也遇到了同样的问题,原因是权限不足。我设置了文件夹和文件的权限,现在一切正常运行。 - Altaf Hussain
2
很高兴听到我有帮助。在你的空闲时间,如果可能的话,在你熟悉的领域帮助他人,不期望任何回报。 - Manohar Reddy Poreddy
1
这对我有用。谢谢。<3 - Ahmet Yusuf Başaran
1
我花了很多时间在这上面,感谢你的答案! - Gareth Quirke
1
非常感谢你,在经过几个小时的努力后,我终于因为你的帮助解决了这个问题。即使是 ChatGPT 也无法帮到我,真的非常感谢你。 - Naeem
@Naeem 很高兴知道上面的帖子有所帮助,问题已经解决了。 - Manohar Reddy Poreddy

13

实际上,有几件事情您需要检查。 1. 检查您的nginx运行状态

ps -ef|grep nginx

ps aux|grep nginx|grep -v grep

在这里,我们需要检查谁在运行nginx。请记住用户和组。

  1. 检查文件夹的访问状态

    ls -alt

  2. 将文件夹的状态与nginx的状态进行比较

(1) 如果文件夹的访问状态不正确

sudo chmod 755 /your_folder_path

(2) 如果文件夹的用户和组与nginx运行的用户和组不同

sudo chown your_user_name:your_group_name /your_folder_path

更改nginx运行的用户名和用户组

nginx -h

查找nginx配置文件的位置

sudo vi /your_nginx_configuration_file

//in the file change its user and group
user your_user_name your_group_name;

//restart your nginx
sudo nginx -s reload

由于nginx默认的用户和组是nobody,如果我们没有注意到这一点,就会引入403错误。


10

我遇到了同样的问题,日志文件显示了以下错误:

2016/03/30 14:35:51 [error] 11915#0: *3 directory index of "path_scripts/viewerjs/" is forbidden, client: IP.IP.IP.IP,     server: domain.com, request: "GET /scripts/viewerjs/ HTTP/1.1", host: "domain", referrer: "domain.com/new_project/do_update"

我正在使用codeignitor框架托管PHP应用程序。当我想查看上传的文件时,收到了403错误

问题在于nginx.conf没有正确定义。而是

index index.html index.htm index.php

我只包含了

index index.php

我在根目录下有一个index.php,本以为这就足够了,但我错了 ;) 提示给了我NginxLibrary


谢谢,我也遇到了同样的问题。我花了几个小时才弄清楚为什么我的WordPress完全无法工作!对于我的WordPress安装,nginx主配置需要index指令才能正常工作。include /etc/nginx/conf.d/*.conf;include /etc/nginx/sites-enabled/*;index index.html index.htm index.php; - mboy

10

以下是我在我的Kali机器上如何修复它的方法:

  • 进入目录:

    cd /etc/nginx/sites-enabled/

  • 编辑“default”配置文件:

    sudo nano default

  • location块中添加以下几行:

    location /yourdirectory {
      autoindex on;
      autoindex_exact_size off;
    }
    
  • 请注意,我已经仅在特定目录/yourdirectory中启用了自动索引。否则,它将为您计算机上的所有文件夹启用,并且您不希望这样。

  • 现在重新启动服务器,应该就可以工作了:

    sudo service nginx restart


9
你可能会因为Nginx策略(例如“deny”)而遇到这个问题,也可能是因为Nginx配置错误,或者是因为文件系统限制。你可以确定它是否是后者(并可能通过使用strace看到配置错误的证据,但是,操作者可能无法访问该工具)。
# pidof nginx
11853 11852

# strace -p 11853 -p 11852 -e trace=file -f
Process 11853 attached - interrupt to quit
Process 11852 attached - interrupt to quit
[pid 11853] stat("/var/www/html/kibanaindex.html", 0x7ffe04e93000) = -1 ENOENT (No such file or directory)
[pid 11853] stat("/var/www/html/kibana", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
^CProcess 11853 detached
Process 11852 detached

我正在检查运行测试时nginx执行的文件系统活动(我遇到了与您相同的错误)。

以下是当时我的配置的部分内容

    location /kibana/3/ {
        alias /var/www/html/kibana;
        index index.html;
    }

根据strace的明确显示,在我的情况下,“alias” 加入 “index” 的结果与我预期的不同,似乎我需要养成始终在目录名称后添加 / 的习惯。因此,在我的情况下,以下方式可行:
    location /kibana/3/ {
        alias /var/www/html/kibana/;
        index index.html;
    }

谢谢您。我知道这不是权限问题,您的评论帮助我找到了解决方案。我在我的别名末尾添加了一个“/”,现在它可以正常工作了。 - kzahel
1
根据我的经验,问题是nginx在别名目录(例如/home/web/public)中找不到文件时会引发403错误。为什么nginx要访问这些未找到的文件呢?因为我忘记删除这行代码:index index.html index.htm index.nginx-debian.html;,而这些文件并不在我的公共目录中。@Cameron Kerr,你是我的英雄。 - Agung Prasetyo
我以前从未听说过 strace。它在解决这个问题上非常有帮助(我犯了同样的错误,即在我的别名末尾漏掉了 /),并显示了在 /var/log/nginx/error.log 中没有显示的错误... 你能详细解释一下它是如何工作的吗? - ArtOfWarfare

7

看起来是一些权限问题。

尝试将所有权限设置与mysite1相同的权限设置到其他站点上。

默认情况下,文件权限应为644,目录权限应为755。 还要检查运行nginx的用户是否具有读取这些文件和目录的权限。


6

对我来说,问题在于除了基础路由之外的任何路由都无法工作,添加这行代码解决了我的问题:

index           index.php;

完整内容:

server {

    server_name example.dev;
    root /var/www/example/public;
    index           index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接