Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I recently deployed my first nginx setup and everything works really nice, except the location parsing is driving me nuts. I have a simple php fastcgi setup like this:

location ~ \.php {
    if (!-e $request_filename) {
            return 404;
    }

    include /etc/nginx/fastcgi.conf;
    keepalive_timeout 0;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass 127.0.0.1:9000;
}

Now i want to secure some locations with basic auth like this:

 location /madmin {
         auth_basic "Restricted";
         auth_basic_user_file /var/www/localhost/admincp/.htpasswd;
 }

Witht his setup, nginx asks for a password when going to /madmin, but won't ask at /madmin/foo.php. If i change the auth location to something like "location ~ ^/madmin" then nginx serves php file for download ...

isn't it possible to configure multiple locations in nginx? if not, what's the workaround here?

Thanks for your help.

share|improve this question
add comment

3 Answers 3

Please see http://nginx.org/en/docs/http/request_processing.html for a description of how nginx handles a request, including locations. The wiki documentation also has some good examples. Unfortunately, a currently undocumented feature is what you want here, most likely.

As mentioned previously, only one location wins in NginX; however, you may not know that nginx supports locations within locations. So your location strategy might actually be like this example server (fastcgi.conf in 0.8.31+):

upstream my-backend {
  localhost:9000;
}
server {
  listen 80;
  server_name my-awesome-php.site;
  root /path/to/root;
  # The protected location
  location /protected {
    auth_basic "Give me codes.";
    auth_basic_user_file /path/to/.htpasswd;
    location ~ \.php$ {
      include fastcgi.conf;
      fastcgi_pass my-backend;
    }
  }      

  # Normal files (blank location is OK, just means serve from root)
  location / {
  }
  # PHP for normal stuff
  location ~ \.php$ {
    include fastcgi.conf;
    fastcgi_pass my-backend;
  } 

}
share|improve this answer
    
Is there a solution that does not require to repeat the *.php configuration? It can be quite lengthy in some setups. –  Michael Härtl Jun 4 '13 at 15:43
add comment

The reason for this is because nginx will choose the most specific location block available. A location matched by a regular expression will triumph over a pure string match.

So when you have a request for /madmin it matches your auth location, but anything ending in .php will go to that first.

The reason location ~^ /madmin serves php-code without parsing is because ~^ halts the search if the following regular expression matches.

You can see the location documentation here: http://wiki.nginx.org/NginxHttpCoreModule#location

share|improve this answer
    
yeah, i figured it from the documentation why php files are not interpreted anymore in the second case. but i have yet to find a proper solution to this problem. i'm going to try to include the php/fastcgi stuff in every location now, but this seems really hacky –  Hollow Mar 4 '10 at 14:33
add comment

this seems to solve the problem, but it looks really aweful with a lot of location directives and i think even static files are now served by php-fastcgi, but it could be solved by rewrites' if directive i guess.

location ~ ^/madmin {
        auth_basic "Restricted Access";
        auth_basic_user_file /var/www/localhost/admincp/.htpasswd;
        include /etc/nginx/fastcgi.conf;
        fastcgi_pass 127.0.0.1:9000;
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.