views:

447

answers:

1

To my knowledge Nginx can only password protect directories from within the configuration file(s). That works nicely, but is not a real option for end-users who A) can not edit the configs and B) would break the configs if they could

Right now I am thinking about a webbased representation of the directory structure where they can point and click - rewriting the configs and re-kill-HUP-ing Nginx... But somehow the whole idea feels like I am about to rewrite cPanel v0.0.1 ;-)

Anybody here had the same problem and came up with an elegant and maintainable solution? I have full control over the server.

Thanks!

+2  A: 

You don't really want users to change the configs, do you? For password-protection, a htpasswd-file is sufficient, if the realm always stays the same. And nginx itself can check for a file existense. So, this is what could do the job:

  location ~ ^/([^/]*)/(.*) {
        if (-f $document_root/$1/.htpasswd) {
                error_page 599 = @auth;
                return 599;
        }
  }
  location @auth {
        auth_basic "Password-protected";
        auth_basic_user_file $document_root/$1/.htpasswd;
  }

Works for me with nginx-0.7.65. 0.6.x and earlier releases are probably no-go

rzab
The / location won't match. Put "if -f" condition in it's block if a .htpasswd in root should trigger the auth request. Matching / is bad idea, because it's almost always the most requested and matching is the last thing nginx does, besides matching cannot be fast compared to the regular locations.
rzab
Thanks Rzab! Am I correctly understanding this will only work on .htpasswd files one level below root? So /first/second/.htpasswd will not be caught? Also - do you have any experience in the speed penalty of this implementation? I always understood the reason Nginx did not implement the whole .ht feature was to gain speed?
Matt
Ouch! Was distracted probably. Location should be "~* ^/(.*)/(.*)" for, err, second and beyond level matching.Speed in terms of looking up the thing to do for nginx on a particular request should't be that bad.When the location is matched, checks for .htpassword files can be expensive.Basically, if you don't need to password-protect /, you're good.Declare "location = /", which is wise thing to do anyway.Declare any other locations (say, /rss) which you don't expect to be password protected.This is what I would do. But no, I didn't have a chance to use the trick in production.
rzab