Securing access to a folder - 404 error

I’m trying to secure a directory on a CentOS 6.3 64 server running NGINX
1.2.7. I think I’ve set this up correctly, but it keeps giving me a 404
Not
Found error when I try to access a file in that folder in the browser
using
domainName/secure/hello2.html.

I created an .htpasswd file using printf “MYUSER:$(openssl passwd -1
MYPASSWORD)\n” >> .htpasswd
and put that into the /var/www/protected/ folder.

I also modified the NGINX config file and included a location/auth block
for
the /secure/ folder:

protect the “secure” folder ( /var/www/html/secure )

location ^~ /secure/ {
    auth_basic "Restricted";
    auth_basic_user_file /var/www/protected/.htpasswd;
}

If I comment out this block from the config file and restart NGINX, I
can
see the file in the browser with no problem. I even moved the .htpasswd
file into the /secure/ folder and changed the config file to reflect
that
change (just to see what would happen), but I still get the 404 Not
Found
error.

Can anyone tell me what I’m missing?

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,237196,237196#msg-237196

On Sun, Mar 10, 2013 at 04:07:23PM -0400, mottwsc wrote:

Hi there,

I’m trying to secure a directory on a CentOS 6.3 64 server running NGINX
1.2.7. I think I’ve set this up correctly, but it keeps giving me a 404 Not
Found error when I try to access a file in that folder in the browser using
domainName/secure/hello2.html.

A 404 error from nginx for a local file should usually show something in
the error log. Is there anything there?

I even moved the .htpasswd
file into the /secure/ folder and changed the config file to reflect that
change (just to see what would happen), but I still get the 404 Not Found
error.

Can anyone tell me what I’m missing?

I get 401 if I don’t give the right credentials, and 403 if the passwd
file is missing or if the requested file is not readable. But the only
way I get 404 is if the file requested does not exist.

What “root” directive is effective in this location{}?

f

Francis D. removed_email_address@domain.invalid

I was able to get partway through the problem with some help. The basic
problem was that I had been missing a root directive in one of the
location
blocks. I was advised to (and did) move the root statement up to the
server
block and comment it out from any sub-blocks. I have found that this now
works as it should to protect the /secure folder when trying to view
html
files, but it does not when viewing php files in the /secure folder (it
just
bypasses authentication and displays the file. I must be missing
something
in the /php block (I guess), but I’m not sure what that would be.

Any suggestions?

Here’s the entire nginx config file…

CODE

server {
listen 80;
server_name mm201.myserver.com;

root  /var/www/html;

#charset koi8-r;
#access_log  /var/log/nginx/log/host.access.log  main;

location / {
#   root   /var/www/html;
# this statement allows static content to be served first
    try_files $uri $uri/ /index.php

    index  index.php  index.html index.htm;
}

# protect the "secure" folder  ( /var/www/html/secure )
location /secure/ {
#   root  /var/www/html;
    auth_basic "Restricted";
    auth_basic_user_file /var/www/protected/.htpasswd;
#   auth_basic_user_file /var/www/html/secure/.htpasswd;
}

# protect the "munin" folder  ( /var/www/html/munin ) and subfolders
location ^~ /munin/ {
    auth_basic "Restricted";
    auth_basic_user_file /var/www/protected/.htpasswd;
}

error_page  404              /404.html;
location = /404.html {
#   root   /var/www/html;
}

# redirect server error pages to the static page /50x.html
#
error_page   500 502 503 504  /50x.html;
location = /50x.html {
#   root   /var/www/html;
}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
#    proxy_pass   http://127.0.0.1;
#}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
#   root    /var/www/html;
    try_files $uri =404;
# the above was inserted to block malicious code uploads, but nginx 

and
# the php-fcgi workers must be on the same physical server

    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME 

$document_root$fastcgi_script_name;
include fastcgi_params;
}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
    deny  all;
}

}

This is what was done to solve the problem. I am providing the two
relevant
location blocks.

protect the “secure” folder ( /var/www/html/secure )

    location /secure/ {
       auth_basic "Restricted";
       auth_basic_user_file /var/www/protected/.htpasswd;
    }

This is required to protect individual files inside the directory

   location ~ ^/secure/.*\.php$ {
      auth_basic            "Restricted Area";
auth_basic_user_file  /var/www/protected/.htpasswd;
fastcgi_pass 127.0.0.1:9010;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
include   fastcgi_params;
   }

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,237196,238105#msg-238105

On Mon, Mar 18, 2013 at 08:10:47PM -0400, mottwsc wrote:

Hi there,

I have found that this now
works as it should to protect the /secure folder when trying to view html
files, but it does not when viewing php files in the /secure folder (it just
bypasses authentication and displays the file. I must be missing something
in the /php block (I guess), but I’m not sure what that would be.

Your “php” block doesn’t have any mention of auth_basic, and so basic
authentication does not apply there.

Any suggestions?

One request is handled in one location. You must have all of the
configuration that you want, available in the one location that handles
a specific request.

The “location” blocks you have are as follows.

location / {
location /secure/ {
location ^~ /munin/ {
location = /404.html {
location = /50x.html {
location ~ \.php$ {
location ~ /\.ht {

The documentation (http://nginx.org/r/location, for example) should tell
you exactly which location{} is used for each request you make.

What you want is a location for “secure php” – either “location ~
php” inside “location ^~ /secure/”; or else something like “location ~
^/secure/.*php” in which both auth_basic and fastcgi_pass apply.

f

Francis D. removed_email_address@domain.invalid