12

I am setting up a very simple file server system. I install nginx and set its root directory to /home to make it serve files from users' home directories.

However, when I attempt to download files via http://12.34.56.78/user1/testfile.bin with my browser, it says "403 Forbidden". When I connect to http://12.34.56.78/ with my browser, however, it displays default index page that I've put in /home/.

How do I make nginx serve files from user directories? e.g.

/home/user1

/home/user2

Additionaly, If I wanted to exclude root directory

/home

and system files

.bash_history .bash_profile .bashrc (say, all files whose names start with a dot)

from the files being served?

Nickolai Leschov
  • 1,101
  • 5
  • 13
  • 26

3 Answers3

17

Nginx does not have the right to read the users files. And it's a very bad idea to put all your users files available on the Web.

A better idea is to only serve a dedicated directory in users home directory.

To serve the www folder in each user folder when accessing /<USER>, use the following location:

location ~ ^/(.+?)(/.*)?$ {
  alias /home/$1/www$2;
  index  index.html index.htm;
  autoindex on;
}

You should also allow Nginx to access this directory.

$ chmod 0755 /home/$USER/www
Spack
  • 1,987
  • 1
  • 17
  • 18
  • Does the first snippet in `/etc/nginx/conf.d/default.conf` make `public_html` subdirectory in each user's directory available to be served by nginx? That would be a nice way to do what I wanted. Now, can I make it so that this directory and rights to it for `nginx` are automatically created when the user is created? – Nickolai Leschov Apr 27 '14 at 12:58
  • The `public_html` folder is not created by Nginx. However, you can make use of the `/etc/skel` directory for new users. – Spack Apr 27 '14 at 13:05
  • I have added directory `www` to `/etc/skel`, thanks for the hint. I hope chmod applied to `/etc/skel/www` will be copied over to each user? Still can't get the server to work. How is it supposed to work? What is $1 and $2? I would like `www` subdirectory in each user's directory available to be served by nginx. If this is the case, then what directory on the computer should correspond to root directory of the site in the URL, e.g. `http://12.34.56.78/`? – Nickolai Leschov Apr 27 '14 at 17:03
  • 1
    The location uses a [regular expression](https://en.wikipedia.org/wiki/Regular_expression). `$1` refers to the user's name caught by `(.+?)` (meaning one or more character) while `$2` refers to the file's path caught by `(/.*)` (meaning a `/` followed by 0 or more characters). – Spack Apr 27 '14 at 17:24
  • So, if we have a user named `hasu` and each user has a directory named `www` and there is a file named [`100mb.bin`](http://mirror.de.leaseweb.net/speedtest/100mb.bin), then a file `/home/hasu/www/100mb.bin` should be accessible by URL `http://12.34.56.78/hasu/www/100mb.bin`? – Nickolai Leschov Apr 27 '14 at 17:39
  • Yes that is it. – Spack Apr 27 '14 at 17:41
  • doesn't work for me, and I don't know where to start debugging it. Is there an easier way to set up serving users' directories? – Nickolai Leschov Apr 27 '14 at 17:48
  • No not with Nginx. What's not working? Are you sure permissions are OK? – Spack Apr 27 '14 at 18:10
  • After I changed directory permissions per darnold0714's advice, `403` changed to `404`. I figured there's actually extra `www` in the URL; `/home/hasu/www/100mb.bin` should translate to URL `http://12.34.56.78/hasu/100mb.bin`. Looks like I got it working. Now what should I change in the regex to allow for dashes in usernames? – Nickolai Leschov Apr 27 '14 at 22:41
7

Many times 403 errors are due to permissions problems. Files in web directories should be world readable (chmod 644 or 664) and directories should be world readable and executable (chmod 755 or 775).

2

All the answers above give valid explanations. What has not been mentioned so far, is that error 403 might persist, even after setting the correct permissions, due to caching, depending on your cache settings.

To make sure this is not the case, reset cache:

rm -r /path/to/nginx/cache/*
systemctl restart nginx
deeenes
  • 163
  • 8