9
votes

I am trying to password protect a directory on my Nginx powered site that contains things like phpMyAdmin, MemcacheMyAdmin, and more admin utilities.

This directory is placed in the root of my site at:

domain.com/control/

The absolute path on my server is at:

/home/deployer/sites/domain.com/control/

I created a .htpasswd file in the directory by using this command:

htpasswd -c /home/deployer/sites/domain.com/control/.htpasswd admin

The file is present, owned by "root" user and is 0644 permissions.

In the .conf file for this domain within Nginx I use the following location block to require authentication.

  location /control {
    auth_basic            "Restricted Area: Control";
    auth_basic_user_file  /home/deployer/sites/domain.com/control/.htpasswd;
  }

When going to the password protected directory I'm prompted for a username and password. I enter my previously created credentials and I'm then presented with an error 403 forbidden page.

Access logs show me that I'm hitting the login prompt and then logging in as the "admin" user:

64.123.456.225 - - [12/May/2013:17:30:48 +0000] "GET /control HTTP/1.1" 401 597 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31"
64.123.456.225 - admin [12/May/2013:17:30:48 +0000] "GET /control HTTP/1.1" 301 185 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31"
64.123.456.225 - admin [12/May/2013:17:30:59 +0000] "GET /control/memcache/ HTTP/1.1" 403 199 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31"

The error logs show the following:

2013/05/12 17:31:01 [error] 30462#0: *1 directory index of "/home/deployer/sites/domain.com/control/memcache/" is forbidden, client: 64.123.456.225, server: domain.com, request: "GET /control/memcache/ HTTP/1.1", host: "domain.com"
2013/05/12 17:31:09 [error] 30462#0: *1 directory index of "/home/deployer/sites/domain.com/control/memcache/" is forbidden, client: 64.123.456.225, server: domain.com, request: "GET /control/memcache/ HTTP/1.1", host: "domain.com"

If I remove the Auth block for the Nginx .conf for that site I can then access the page like normal.

Thanks for any help!

6
There are a lot of good answers here and this is an old question, but just to add one more thing- it's worth disabling the authorization and checking that you aren't getting 403 errors anyway. I just spent ages on this only to find I was solving the wrong problem.glenatron

6 Answers

5
votes

This can be caused by permissions or a non-existent or invalid directory index directive.

Permissions: If www is owned by nginx but /var is owned by root, then www will inherit the permissions of var, thus denying access.

Index Directive: If the directory index is set to an unavailable file, then nginx will throw a 403. In this case, I'm guessing it's defaulting to index.htm instead of index.php.

Best of luckerage!

14
votes

Even though this question has its accepted answer, I still want to put another case that I have trouble with here so other people wouldn't need to struggle like me.

I got 403 with correct credentials too, the index file is not the case, the file existence is not the case neither and the config was this:

auth_basic "some message";
auth_basic_user_file /etc/nginx/.htpasswd;

The problem here is that /etc/nginx/.htpasswd is an absolute path which actually points inside the same directory with nginx.conf. It somehow confused nginx to lookup the file. (By saying somehow, I don't fully understand how nginx couldn't just handle this because it's quite obvious that the path is absolute and nginx should just read it, so if anyone has a better explanation, please share by comments).

If I change it to:

auth_basic_user_file .htpasswd;

It worked because nginx expected to find that file in the same directory with nginx.conf.

Even if I change it to:

auth_basic_user_file /home/user/.htpasswd; #and move the file to /home/user too

It worked also because I think that the path didn't confuse nginx.

4
votes

I got here because I had a similar problem. I had set up the top level directory to be "autoindex on;". I added password protection for a subdirectory with a separate declaration for ("/subdirectory") without repeating "autoindex on;" This left nginx looking for an index file, and since there was none, I saw "forbidden".

Once I added "autoindex on;" to the setup for "/subdirectory". the directory listing appeared when browsing the subdirectory.

1
votes

The error is not the authentication, but the directory your are trying to access and its content:

/home/deployer/sites/domain.com/control/memcache/

When the webserver processes the request it checks for known index files like index.html, index.php and so on. If it does not find one of these, it interprets the request as an attempt to list all files in the given directory. This seems to be forbidden in your nginx configuration ( which is good ). Message:

directory index of [...] is forbidden

Therefore I guess the directory

/home/deployer/sites/domain.com/control/memcache/

is empty or does not contain an index file that nginx recognizes.
If you request a specific file or create an index.html file, the 403-Error should be gone.

0
votes

I have described the steps with solution of " How to set Authentication" on nginx using .htpasswd HERE

Please check the above given link, I would be glad if it helps someone somehow because I struggled hard to make this thing work.

Thanks.

0
votes

If you are running NGINX in a dockerized environment, it helps putting the .htpasswd file in the same directory as the NGINX configuration file, default.conf

For example, assuming that I have my .htpasswd in /home/centos/nginx/conf (which is also a Docker volume):

/home/centos/nginx/conf
drwxr-xr-x. 2 centos centos   70 Sep 14 17:39 .
drwxr-xr-x. 3 centos centos   40 Sep 14 17:02 ..
-rw-r--r--. 1 centos centos 1409 Sep 14 17:39 default.conf
-rw-r--r--. 1 root   root     44 Sep 14 16:52 .htpasswd

Remember that you have to indicate the location in the NGINX container, not in your host machine.

In my case, the location of the configuration files in the container is:

   /etc/nginx/conf.d

which is a volume that matches my host directory

   /home/centos/nginx/conf

Therefore, the location you should specify in your default.conf file is the following, which is what NGINX sees:

   location / {
       auth_basic  "Administrato's area";
       auth_basic_user_file /etc/nginx/conf.d/.htpasswd;