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
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.
It is not possible to listen on port 443 on the same IP for just one site, because it only knows which site the client wants to have from the SSL Client Hello. After it received the Hello it has the option to either complete the SSL handshake or to cut the connection. In the first case you need to provide a certificate, in the latter case the client will get some unhelpful error about broken SSL connection.
At the end it boils down to the following options:
Only the last option will work without any errors at the client.
I was thinking about a configuration for site1.com listening on port 443 without ssl that only redirects to http://site1.com. I think it should work without a need for a new IP address.