Nginx: Matching server host name in location directive
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?
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)
You don't need to use the location directive if you use map. This is the most simple solution and equivalent i can think of. You can name the htpasswd files according to your $http_host e.g. x.domain.com.htpasswd
.
map $http_host $auth_type {
default "off"; #This will turn off auth-basic
x.domain.com "Restricted"; #This or any other string will turn it back on
}
server {
auth_basic $auth_type;
auth_basic_user_file /etc/nginx/conf.d/$http_host.htpasswd;
}
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;
}