Nginx 403 error: directory index of [folder] is forbidden
Asked Answered
B

21

305

I have 3 domain names and am trying to host all 3 sites on one server (a Digital Ocean droplet) using Nginx.

mysite1.name mysite2.name mysite3.name

Only 1 of them works. The other two result in 403 errors (in the same way).

In my nginx error log, I see: [error] 13108#0: *1 directory index of "/usr/share/nginx/mysite2.name/live/" is forbidden.

My sites-enabled config is:

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;
        }
}

All 3 sites have nearly identical config files.

Each site's files are in folders like /usr/share/nginx/mysite1.name/someFolder, and then /usr/share/nginx/mysite1.name/live is a symlink to that. (Same for mysite2 and mysite3.)

I've looked at Nginx 403 forbidden for all files but that didn't help.

Any ideas on what might be wrong?

Boulware answered 10/10, 2013 at 1:0 Comment(5)
i think you have index.html index.php files missing, did you make sure they exist in that folder?Postgraduate
Oh you are right; the 2 sites that aren't working are a Laravel project (which has index.php in a /public subfolder) and an old CodeIgniter project (which has index.php in a /public_web subfolder). But I'm not sure how to change my configuration to make the sites work.Boulware
Just like @MohammadAbuShady said, I didn't have an index file in the folder and got this error.Wolfson
I just got this error again, but this time the problem was that I'd accidentally set the root to be /Users/myUsername/code/app instead of /Users/myUsername/code/app/public.Boulware
This is when server admins shine. detailsLuminosity
B
77

Here is the config that works:

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;
    }

}

Then the only output in the browser was a Laravel error: “Whoops, looks like something went wrong.”

Do NOT run chmod -R 777 app/storage (note). Making something world-writable is bad security.

chmod -R 755 app/storage works and is more secure.

Boulware answered 10/10, 2013 at 17:46 Comment(5)
Yeah, you guys are right; that's a bad idea. I'll update my answer. People also might benefit from https://mcmap.net/q/101598/-starting-with-laravel-on-ubuntuBoulware
You may also have the option of changing the folders group to the nginx group ie www-data on debian. Then setting even stricter permissions on the folder like: chmod -R 640 app/storage then chown -R :www-data app/storage. This way the files are only visible to the app owner and the web server. And no-one at all can execute any of the stored (possibly uploaded) files directly. Nginx should only need read permission to access the files.Creosol
Note to self: I just got this Nginx 403 again and again the problem was that I had accidentally left off public/ on root /usr/share/nginx/mysitename/public/;. After adding public/ and running service nginx restart, it worked.Boulware
what about windows?Istic
To prevent error log on nginx, or support frameworks with custom error handling, you might want a index index.php /index.php; directive or something similar.Italicize
G
331

If you have directory indexing off, and is having this problem, it's probably because the try_files you are using has a directory option:

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

Remove it and it should work:

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

Why this happens

TL;DR: This is caused because nginx will try to index the directory, and be blocked by itself. Throwing the error mentioned by OP.

try_files $uri $uri/ means, from the root directory, try the file pointed by the uri, if that does not exists, try a directory instead (hence the /). When nginx access a directory, it tries to index it and return the list of files inside it to the browser/client, however by default directory indexing is disabled, and so it returns the error "Nginx 403 error: directory index of [folder] is forbidden".

Directory indexing is controlled by the autoindex option: https://nginx.org/en/docs/http/ngx_http_autoindex_module.html

Grubman answered 27/6, 2016 at 4:49 Comment(14)
This is exactly the problem I was having. I could not understand why try_files was not trying index.php, I just kept getting 403 with "directory index of ... is forbidden"Pera
@JCM, would you mind adding an explanation of why having $uri/ creates a problem?Highjack
Solved mine as wellCzechoslovakia
@IanDunn because nginx will try to index the directory, and be blocked by itself. Throwing the error mentioned by OP.Grubman
Been looking for that all morning, couldn't figure it out. Thanks a lot!Acaleph
I had the same error. I had 2 sites, both in a subdomain. Removing the $uri/ did the trick. Thanks!Odonto
Been pulling my hair out for 2 days and there lies the answer, thank a lot man :)Environmentalist
I don't get your explanation. What does it mean to say, "It's trying to index directories, but blocked by itself?" What part is blocking? What part is indexing?Provo
@Provo try_files $uri $uri/ means, from the web root, try the file pointed by the uri, if that does not exists, try a directory instead (hence the /). When nginx access a directory, it tries to index it and return the list of files inside it to the browser/client, however by default directory indexing is disabled, and so it returns the error "Nginx 403 error: directory index of [folder] is forbidden". Directory indexing is controlled by the autoindex option: nginx.org/en/docs/http/ngx_http_autoindex_module.htmlGrubman
I had this exact issue. Once you pointed out what the problem was, it made so much more sense to me.Ortrud
I think try_files $uri $uri/ with index index.html should not try to show the directory listing (which is blocked), it should look for index.html. It doesn't though, it gives 403. What is the solution? try_files $uri $uri/index.html? Seems ugly?Karinekariotta
Great explanation, but keep in mind that removing $uri/ will have some "pages" in WordPress fail, such as /wp-admin/ and how it redirects to wp-login.phpPrecisian
solved mine tooGranada
Thanks this has Solved my problem. Simple and quick.Earlie
B
77

Here is the config that works:

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;
    }

}

Then the only output in the browser was a Laravel error: “Whoops, looks like something went wrong.”

Do NOT run chmod -R 777 app/storage (note). Making something world-writable is bad security.

chmod -R 755 app/storage works and is more secure.

Boulware answered 10/10, 2013 at 17:46 Comment(5)
Yeah, you guys are right; that's a bad idea. I'll update my answer. People also might benefit from https://mcmap.net/q/101598/-starting-with-laravel-on-ubuntuBoulware
You may also have the option of changing the folders group to the nginx group ie www-data on debian. Then setting even stricter permissions on the folder like: chmod -R 640 app/storage then chown -R :www-data app/storage. This way the files are only visible to the app owner and the web server. And no-one at all can execute any of the stored (possibly uploaded) files directly. Nginx should only need read permission to access the files.Creosol
Note to self: I just got this Nginx 403 again and again the problem was that I had accidentally left off public/ on root /usr/share/nginx/mysitename/public/;. After adding public/ and running service nginx restart, it worked.Boulware
what about windows?Istic
To prevent error log on nginx, or support frameworks with custom error handling, you might want a index index.php /index.php; directive or something similar.Italicize
M
75

If you're simply trying to list directory contents use autoindex on; like:

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;
        }
}
Mozzarella answered 15/11, 2013 at 18:11 Comment(4)
I definitely don't want autoindex on; it would be a bad idea to expose my directory contents to the public.Boulware
@Boulware It always comes down to "What do you want to do?"Eklund
It's pretty clear he wants to remove 403 errors and get webpages to show not display the entire directory contents (esp given the discussion above)Leatherleaf
FWIW I came to this question looking for the autoindex option as it's the first result on Google for the error.Baisden
E
43

I encountered similar error
--- "403 Forbidden" in the webpage
--- "13: Permission denied" in the error log at /var/log/nginx/error.log

Below 3 Steps worked for me:

1: Open Terminal, saw something like below

user1@comp1:/home/www/

So, my user name is "user1" (from above)

2: Changed user in /etc/nginx/nginx.conf

# user www-data;
user user1;

3: Reloaded the nginx

sudo nginx -s reload  

Additionally, I have applied file/folder permissions (before I did above 3 steps)
(755 to my directory, say /dir1/) & (644 for files under that directory):
(I am not sure, if this additional step is really required, just above 3 steps might be enough):

chmod 755 ./dir1/
chmod 644 ./dir1/*.*

Hope this helps quick someone. Best of luck.

Exuberance answered 19/8, 2015 at 7:22 Comment(6)
Thanks bro, i had the same issue, and it was because of permissions. I set folder and file permissions, and now it is working fine.Hymnody
Glad to hear I am helpful. (Help others, in your known domain, in your free time, if possible, without expecting anything back)Exuberance
<3 This is worked for me. Thank you. <3Bygone
Spent alot of time on this, thanks for this answer!Raychel
Thank you so much, after several hours of griding, i finally resolved the issue just because of you, even chatgpt couldn't help me out, thankUnpile
@Unpile very happy to know above post helped & issue is resolvedExuberance
M
14

In fact there are several things you need to check. 1. check your nginx's running status

ps -ef|grep nginx

ps aux|grep nginx|grep -v grep

Here we need to check who is running nginx. please remember the user and group

  1. check folder's access status

    ls -alt

  2. compare with the folder's status with nginx's

(1) if folder's access status is not right

sudo chmod 755 /your_folder_path

(2) if folder's user and group are not the same with nginx's running's

sudo chown your_user_name:your_group_name /your_folder_path

and change nginx's running username and group

nginx -h

to find where is nginx configuration file

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

Because nginx default running's user is nobody and group is nobody. if we haven't notice this user and group, 403 will be introduced.

Monotype answered 24/2, 2015 at 4:23 Comment(0)
D
10

I had the same problem, the logfile showed me this error:

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"

I am hosting a PHP app with codeignitor framework. When i wanted to view uploaded files i received a 403 Error.

The problem was, that the nginx.conf was not properly defined. Instead of

index index.html index.htm index.php

i only included

index index.php

I have an index.php in my root and i thought that was enough, i was wrong ;) The hint gave me NginxLibrary

Dressel answered 30/3, 2016 at 13:21 Comment(1)
Thank man.. I was with the same boat.. I spent hours figuring out why my wordpress do't work at all! index directive is needed in the nginx main config for my wordpress installation to work include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; index index.html index.htm index.php;Melise
P
10

Here's how I managed to fix it on my Kali machine:

  • Locate to the directory:

    cd /etc/nginx/sites-enabled/

  • Edit the 'default' configuration file:

    sudo nano default

  • Add the following lines in the location block:

    location /yourdirectory {
      autoindex on;
      autoindex_exact_size off;
    }
    
  • Note that I have activated auto-indexing in a specific directory /yourdirectory only. Otherwise, it will be enabled for all of your folders on your computer and you don't want it.

  • Now restart your server and it should be working now:

    sudo service nginx restart

Presentational answered 29/12, 2020 at 12:27 Comment(0)
H
9

You might get this because of Nginx policy (eg. "deny"), or you might get this because of Nginx misconfiguration, or you might get this because of filesystem restrictions.

You can determine if its the later (and possibly see evidence of a misconfiguration by using strace (except, the OP won't have access to that):

# 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

Here I'm inspecting the filesystem activity done by nginx while a ran a test (I had the same error as you).

Here's a selected part of my config at the time

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

In my case, as strace quite clearly shows, the joining of in the "alias" to the "index" was not what I had expected, and it seems I need to get into the habit of always appending directory names with a /, so in my case, the following worked:

    location /kibana/3/ {
        alias /var/www/html/kibana/;
        index index.html;
    }
Harned answered 26/9, 2015 at 19:6 Comment(3)
Thanks for this. I knew I did not have a permissions problem and your comment helped me find the solution. I added a "/" to the end of my alias and it works fine.Van
you are my hero @Cameron Kerr, based on my experience the problem is nginx raise 403 for not found files on alias directory e.g /home/web/public. Why nginx try to access these not found files is because i forgot to remove this line index index.html index.htm index.nginx-debian.html; since thats files is not inside my public dir.Blinni
I've never heard of strace before. It was helpful in fixing this problem (I had the same mistake of leaving / off the end of my alias) and showed errors that weren't displayed in /var/log/nginx/error.log... could you explain more about how it works?Ma
L
7

It look's like some permissions problem.

Try to set all permisions like you did in mysite1 to the others site.

By default file permissions should be 644 and dirs 755. Also check if the user that runs nginx have permission to read that files and dirs.

Losing answered 10/10, 2013 at 1:21 Comment(0)
A
6

For me the problem was that any routes other than the base route were working, adding this line fixed my problem:

index           index.php;

Full thing:

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;
    }
}
Adore answered 12/2, 2018 at 5:50 Comment(0)
P
5

change the try_files to point to the index.php path, in the "Laravel" that you mentioned it should be something like this

location / {
    try_files $uri $uri/ /public/index.php$request_uri;
}

And in the "codeigniter" project try it like this

location / {
    try_files $uri $uri/ /public_web/index.php$request_uri;
}
Postgraduate answered 10/10, 2013 at 8:13 Comment(0)
R
4

Because you're using php-fpm, you should make sure that php-fpm user is the same as nginx user.

Check /etc/php-fpm.d/www.conf and set php user and group to nginx if it's not.

The php-fpm user needs write permission.

Robbegrillet answered 8/4, 2017 at 19:58 Comment(0)
L
3

You need execute permission on your static files directory. Also they need to be chown'ed by your nginx user and group.

Libido answered 11/10, 2013 at 7:44 Comment(1)
I think he only need needs read permission to the nginx process?Creosol
C
3
location ~* \.php$ {
    ...
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;    
}

Change default

fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;

to

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

solved my problem.

Chatelaine answered 12/3, 2015 at 12:49 Comment(0)
H
3

In my case I was using hhvm listening on port 9000 and the fastcgi_pass line in nginx config was incorrect.

Also, if you are using mysql and the connections from hhvm to the database don't work check if you have apparmor installed.

Hardiman answered 22/6, 2019 at 11:18 Comment(0)
I
2
6833#0: *1 directory index of "/path/to/your/app" is forbidden, client: 127.0.0.1, server: lol.com, request: "GET / HTTP/1.1", host: "localhost"    

I was running Ubuntu 15.10 and encountered the 403 Forbidden error due to a simple reason. In the nginx.conf(configuration file for nginx), the user was 'www-data'. Once I changed the username to [my username], it worked fine assuming the necessary permissions were given to my username. Steps followed by me:

chmod 755 /path/to/your/app    

My configuration file looks like this:

**user [my username]**;#I made the change here.
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}

http {

##
# Basic Settings
##

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;

# server_names_hash_bucket_size 64;
# server_name_in_redirect off;

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

##
# SSL Settings
##

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;

##
# Logging Settings
##

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

##
# Gzip Settings
##

gzip on;
gzip_disable "msie6";

# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

##
# Virtual Host Configs
##

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;


server {
    listen 80;

    server_name My_Server;

    access_log  /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        proxy_pass         http://127.0.0.1:8000;
        proxy_redirect     off;

        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
}
}
Irrelevant answered 17/2, 2016 at 12:45 Comment(0)
I
2

I resolved my problem, if i configure like follow:

location = /login {
    index  login2.html;
}

It'll show the 403 error.

[error] 4212#2916: *2 directory index of "D:\path/to/login/" is forbidden

I've tried autoindex on, but not working. If i change my configure like this, it works.

location = /login/ {
    index  login2.html;
}

I think the exact matching, if it's a path should be a directory.

Inactivate answered 18/3, 2019 at 3:58 Comment(0)
C
2
  1. Check that index.html or index.php is not missing in the directory

  2. See the error log file which is located in /var/log/nginx and then open

    vim error.log

Cannular answered 10/8, 2020 at 17:59 Comment(0)
M
2

In my case it was related to SELinux in CentOS 7:

You can check if it is enabled running the following command:

cat /etc/selinux/config

Sample outputs:

SELINUX=enforcing
SELINUXTYPE=targeted

Disabling SELinux permanently Edit the /etc/selinux/config file, run:

sudo vi /etc/selinux/config

Set SELINUX to disabled:

SELINUX=disabled

Save and close the file in vi/vim. Reboot the Linux system:

sudo reboot
Maintenance answered 22/9, 2020 at 14:34 Comment(1)
SELinux is a security feature and should not be disabled. You have tools like ausearch, journalctl, sealert, among others to troubleshoot it.Granada
G
2

In my case I didn't run this command

sudo apt-get install php7.4-fpm
Gurge answered 15/11, 2020 at 8:9 Comment(0)
C
1

when you want to keep the directory option,you can put the index.php ahead of $uri like this.

try_files /index.php $uri $uri/
Cahan answered 17/6, 2019 at 14:2 Comment(1)
with this, nginx downloading files in browserBestial

© 2022 - 2024 — McMap. All rights reserved.