4

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

blacksoul
  • 244
  • 6
  • 21

3 Answers3

3

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.

erik258
  • 766
  • 5
  • 9
  • 1
    I was thinking that was something related to that. Only 1 SSL vhost on the same IP, so I will ask for a new one for that vhost. Thanks you! – blacksoul Mar 19 '14 at 21:53
  • 3
    Good answer, except that you _can_ have multiple SSL vhosts on the same IP address. It's called [Server Name Indication](http://serverfault.com/a/417580/126632) and every modern browser supports it. The problem here comes from trying to run virtual hosts on the same IP for which SSL is _not_ wanted. – Michael Hampton Mar 29 '14 at 14:33
  • 1
    @MichaelHampton Very good point about not mixing HTTP-only vhosts and HTTPS vhosts on the same IP. However, the possibilities of IP sharing for HTTPS vhosts goes beyond and predates SNI, this because without SNI it's not actually the number of vhosts that matters but rather the number of certificates in use. If you have multiple vhosts that all use a single certificate (wildcard cert or SAN cert matching all the names) then that works fine on a single IP even without SNI. – Håkan Lindqvist Apr 01 '14 at 20:12
  • 2
    Actually, the answer is partially correct. It should read as "Your problem is that SSL doesn't support multiple vhosts on the same IP --> AND port <--. – John Greene Jan 10 '17 at 22:40
2

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:

  • Cut the connection and cause some strange error message at the client (I don't know if you could enable this behavior with nginx).
  • Serve the same certificate as for site2WithSSL.com and redirect the client to http-only. Unfortunately the redirect will be done after the SSL handshake and this SSL handshake will cause an error at the clients because hostname does not match the certificate.
  • Use a self-signed cert for site1 and redirect to http-only: same problem because the client will not accept the certificate.
  • Use a real certificate for site1, even if you only use it to redirect to http-only.

Only the last option will work without any errors at the client.

Steffen Ullrich
  • 12,227
  • 24
  • 37
  • +1 And here additional doc : http://nginx.org/en/docs/http/configuring_https_servers.html#name_based_https_servers – krisFR Mar 19 '14 at 20:33
0

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.

Dolanor
  • 173
  • 2
  • 8