0

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!

MattW
  • 538
  • 1
  • 4
  • 12

1 Answers1

3

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
  • 1,657
  • 11
  • 7
  • 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 Mar 10 '10 at 11:16
  • 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? – MattW Mar 16 '10 at 10:01
  • 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 Mar 16 '10 at 14:38