The problem
I have an nginx server serving 3 subdomains - say a.example.com
, b.example.com
, and c.example.com
.
The configuration files are a.example.com.conf
, b.example.com.conf
, and c.example.com.conf
respectively. They are stored in /etc/nginx/sites-available
and soft-linked from /etc/nginx/sites-enabled
.
In the configuration files, each server
clause has its appropriate server_name
directive. If it matters, all three subdomains use the same SSL certificate issues by Let's Encrypt (which works fine).
When b.example.com.conf
is removed from sites-enabled
, I expect an error message when trying to browse to it. Surprisingly, nginx redirects the traffic to a.example.com
. In fact, every incoming connection without a matching server name in /etc/nginx/sites-enabled
- including just the machine IP - is routed to a.example.com
.
How to configure nginx to make the server
directive exclusive, so that requests to b.example.com
will never be served by a.example.com
?
Configuration
a.example.com.conf
server {
listen 443 ssl;
server_name a.example.com;
ssl_certificate /etc/letsencrypt/live/a.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/a.example.com/privkey.pem;
location / {
proxy_pass http://localhost:8080;
}
}
b.example.com.conf
server {
listen 443 ssl;
server_name b.example.com;
# I'm using a multi-domain certificate called `a.example.com`, which is
# serving a.example.com, b.example.com and c.example.com - not an error
ssl_certificate /etc/letsencrypt/live/a.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/a.example.com/privkey.pem;
location / {
proxy_pass http://localhost:8090;
}
}
Temporary solution
I have created a default server that catches all default requests and returns error 404. However, I would like to have a more holistic solution preventing requests from any given server served by another server.
server {
listen 443 default_server;
server_name _;
return 404;
ssl_certificate /etc/letsencrypt/live/a.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/a.example.com/privkey.pem;
}