Nginx issues between vhosts and SSL

httphttpsnginxsslssl-certificate

I have two sites in the same IP with the follow configuration:

  • site1.com
    • Multiples subdomains (ie.: foo.site1.com, bar.site1.com)
    • Everything listening on port 80, NOTHING in 443

  • site2WithSSL.com
    • Listening on ports 80 and 443 (SSL)

I can access to https://site2WithSSL.com and to http://site1.com without problems. The issue comes when someone want to access to https://site1.com, nginx answers with the site2WithSSL.com I want to avoid this. I mean, whenever somebody access to https://site1.com no content has to be returned or just a redirect to https://

The configuration is:

server {
     listen      80;
     server_name    *.site1.com;

     // ...
}

server {
     server_name www.site2WithSSL.com;
     return 301 $scheme://site2WithSSL.com$request_uri;
}

server {
     listen 80;
     listen 443 ssl;
     server_name site2WithSSL.com;
     ssl_certificate site2WithSSL.crt;
     ssl_certificate_key site2WithSSL.key;

     // ...
 }

SOLVED: using a different ip for each site

Best Answer

Your problem is that SSL doesn't support multiple vhosts on the same IP.

When NGINX receives a new connection over HTTP/1.1, the request include a HOST header that specifies which virtual host to serve ( this was the big change in 1.1, and allows vitual hosts as we know them today).

But with HTTPS, the headers are encrypted, and the key exchange and TLS layer must be established before they can be decrypted. In other words, there is no way for nginx to choose the proper SSL server block until after it's sent an SSL certificate.

You could add a redirect matching site1's domain name under site2's configuration, but the user would still get a message saying the certificate was invalid, so that's not very palatable.

There are some multi-domain certificates you could use, though it'll cost you.

The easiest, and for your desired configuration, probably best option, is to use a different IP address for each site. The different NGINX server configurations can bind to different addresses so that there is never any question about which is which. Most providers can give you multiple IP addresses, some even multiple blocks, and of course in the cloud you can just provision more.

update: SNI works around this problem by moving the Host header outside the encrypted payload, and is supported by modern browsers.