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 have nginx running multiple domains under a single server directive as

server {
        listen       80;
        server_name  www.domain.com;
        server_name  x.domain.com;
        server_name  y.domain.com;

----
----
----
}

Now, I need to use location directive to match a subdomain and apply basic auth to it. The equivalent of

location x.domain.com {
        auth_basic "Admin Login";
        auth_basic_user_file /etc/nginx/.htpasswd;
}

How do I do this?

share|improve this question

3 Answers 3

You can use a regular expression to capture the subdomain and then use it later in your location.

server {
    server_name   ~^(?<sub>\.)?(?<domain>.+)$;

    location / {
        root   /sites/$sub;
    }
}

Alternatively, it might be preferable to move all common configurations to an other file, and then create server blocks per-subdomain and include the external file.

server {
        server_name  www.domain.com;
        include /etc/nginx/sites-enabled/default.inc;

    location / {
        ... 
    } 
}

(repeat for other servers)

share|improve this answer
    
Am I missing something or is the server name line missing a ? and <> ? I believe it should be server_name ~^(?<sub>\.)?(?<domain>.+)$; –  Mohammad AbuShady Sep 30 '13 at 8:36
    
You are quite probably correct - I can't think of any reason for it being the way it was at the moment, so I have changed it to your suggestion. –  cyberx86 Sep 30 '13 at 11:25

If you have multiple (sub)domains and they do not behave exactly alike then you use multiple server blcoks. Sorry but that's seriously the best way, even though you'll have a larger configuration.

You can do a ghetto hack by using something like if ($http_host ~ foo) but then you'll most likely run afoul of the unpredictable and weird behaviour of if as documented here: http://wiki.nginx.org/IfIsEvil

Don't try to outsmart Nginx, just use the options it gives you and you'll have far less headaches.

share|improve this answer

One option is to return an error and send that error to a location that handles the HTTP authentication:

if ($host = x.domain.com) {
    return 550;
}

error_page 550 = @xauth;

location @xauth {
    auth_basic "Admin Login";
    auth_basic_user_file /etc/nginx/.htpasswd;
}
share|improve this answer

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.