I've recently set up a VPS with a couple of websites running on it (all using different domains) using nginx to proxy requests to the correct application.
I've a valid SSL certificate for one of these domains, so I set up a http->https direct for this:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate ..... (etc)
}
For the other domains, I only listen at port 80 and obviously do not set the SSL certificates. Although all domains are accessible, and the HTTPS redirection works as expected for the main domain, I noticed that when I load one of the other domains (without SSL certificate) over HTTPS, nginx is serving the wrong website, instead of… not accepting the connection at all, I would expect?
I tried adding a default config before loading the sites-available:
server {
listen 80;
listen 443 ssl;
return 444;
}
Which gives me the expected behaviour except for the fact that my main domain is not available over HTTPS anymore (although the HTTP->HTTPS redirection is still functional).
This is probably something stupid and/or me not correctly understanding the way nginx handles configuration, but I've no idea where the problem lies exactly. Help?
Best Answer
That's the expected behaviour.
You are using vhosts on a single IP address where you both listen on HTTP and HTTPs. So the server block handling SSL is acting as the default one for everything going to this IP port 443.
You won't be able to refuse the SSL handshake but after it has been completed you can forbid further HTTP requests not targetting a particular domain by adding a separate catch-all server block returning nginx special 444 code.
The generic solution is to have one unique IP for the domain that should support both HTTP and HTTPS and handle all other HTTP vhost on an other IP.