3

So I've got a server with a single IP and a lot of websites, all hosted under nginx. Here's a very simplified reduction of my actual setup:

server {
    listen 80;
    listen 443 ssl;
    server_name ssl.example.com;
    #...
}

server {
    listen 80;
    server_name nossl.example.com;
    #...
}

If I connect to ssl.example.com:443 everything works, as expected.
If I connect to nossl.example.com:443, it tries to serve the content of ssl.example.com:443.

I've made my peace with the why that happens (it's just how ssl+nginx best-matches a virtual server), I just need to stop it sending content from the wrong site.

Short of buying certificates for all my sites (or issuing my own), or pushing the SSL site off onto its own IP, what are my options here? Can nginx double-check the domain for every SSL request and make sure it matches that server_name?

1
4

Add the following virtual server:

server {
  listen 443 ssl;
  server_name _;

  ssl on;
  ssl_certificate /path/to/certificate.crt;
  ssl_certificate_key /path/to/certificate.key;

  return 444;
}

If no host is matching, Nginx will use this one as last resort and send back an error.

It needs a SSL certificate to work but you can generate a self-signed one of these very quickly and that will do. This is better than sharing an otherwise valid, existing certificate for another domain (which throws up errors anyway) because there's less leakage.

6
  • I like the idea in theory but it's not working here on nginx 1.4.7 – Oli May 3 '14 at 10:25
  • I think I might need to provide it with an actual certificate. I've added ssl on; but that's moaning about needing ssl_certificate. I'll churn out a self-sign for the whole server and see if that works. – Oli May 3 '14 at 10:28
  • Yup, once the certificate configuration is in there it all works. I've suggested an edit for your post. Please accept it. – Oli May 3 '14 at 10:39
  • Well the strangest thing happened. All was working well but the server has just started spitting out the wrong certificate again. No idea what's going wrong. – Oli May 3 '14 at 18:20
  • 2
    Well apparently the order matters. I had my version of the above out in another file that was being included later and that wasn't working. I just moved it to just above the proper SSL server code and now it works. – Oli May 4 '14 at 0:18
1

I tend to think that #2 is the most proper answer, but I have found that the following works as well when placed above the server block of the non-ssl virtual servers.

server {
  listen 443;
  server_name .example.com;
  return 444;
}

Don't use the "ssl" flag.

1
  • ssl is required otherwise the vhost will serve HTTPS for all the domains (even if they have their own vhosts) – Finesse Sep 6 '18 at 0:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.