1

I'm stuck with configuring nginx regarding SSL and SNI support.

In order to simplify my case let's say I have two domains, foo.com and bar.com. I have only one IP and both domains are mapped to this one. I want foo.com to be available via https, but not bar.com. The latter should just be unavailable on port 443. I know this is not possible with plain SSL but I was told that I can safely rely on SNI these days. So I assume that my browser (Chrome) sends the domain of the website it wants to access alongside the SSL init request.

If I access bar.com, nginx uses the configured certificate issued for bar.com, perfect. If I access https://foo.com, for which no listen *:443 directive actually exists, nginx also replies with the certificate for bar.com, thus Chrome throws a certificate exception. I tried to configure the SSL listen directive for foo.com and added the following code in the vhost with no success:

if ($server_port = 443) {
  return 444;
}

It now sends the wrong certificate and only afterwards denies the connection.

Is it possible to let nginx close the connection before any SSL reply is sent back to the browser if nginx cannot find an appropriate certificate for the requested domain?

2
  • After a TLS session has been requested, it is not possible to deny it gracefully.
    – Daniel B
    Commented Apr 7, 2014 at 22:00
  • Well, I do not want to deny it gracefully. Just drop the connection.
    – creethy
    Commented Apr 7, 2014 at 22:01

1 Answer 1

1

Nginx uses the first appropriate (by port and ssl presence) virtual host when it can't find a virtual host for the given domain. You need to add a server {} entry before all the other server {} entries so that Nginx will use it for https://foo.com and other HTTPS requests with an unknown domain:

server {
    listen 443 ssl;

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

    return 404;
    # or return 444; to just drop such connections
    # or return 302 http://$host$request_uri; to redirect them to HTTP
}

It needs a SSL certificate to work but you can generate a self-signed one (the certificate is not required to be valid).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .