Nginx one ip and multiple ssl certificates

nginxssl

Example case. I have a web-server with one IPV4 address. I am hosting ~50 web sites and just two of them have ssl certificates. I have configured vhosts for 2 ssl websites and everything is OK, except one big problem – if i visit other 48 sites using https:// prefix (they don't have ssl certificates), i am seeing my latest website with a SSL certificate.

It is possible to prevent https prefix on non SSL websites? Or there's just one solution – to use dedicated ip addresses. If i have dedicated ip address i am using the following config:

server {
        listen 111.222.333.444:443 ssl;
}

This way, if i force https on non SSL website – nothing happens.

Best Answer

Nginx uses a "default server" that it picks to serve pages when there isn't another closest match. If you haven't specified the default server to use, I believe it uses the first that it finds (which in your case is one of your HTTPS sites). So you should be able to create a default server vhost with your IPv4 address for TLS (you are using only TLS and not SSL anymore right?) and have it listen on the IP that will catch the random HTTPS requests. You might also need to add the server_name item in there too for your 48 non-secure sites, but it may work without that.

#Your catch-all HTTPS server:
server {
  listen 104.218.234.204:443 default_server;
  server_name ruel.in ruel.pro;
  root /var/www/ruel.pro;
  index index.html;
  ssl on;
  ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
  ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
  ssl_dhparam /etc/ssl/private/dhparams_4096.pem;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}

#Regular HTTP server
server {
  listen ruel.in:80;
  server_name ruel.in;
  root /var/www/ruel.in;
  index index.php index.html index.htm;
  ...
}

#Regular HTTP server
server {
  listen ruel.pro:80;
  server_name ruel.pro;
  root /var/www/ruel.pro;
  index index.php index.html index.htm;
  ...
}

#Your HTTPS server
server {
  listen dallas.ruhnet.net:443 ssl;
  server_name dallas.ruhnet.net;
  ...
}

Another alternative is to go ahead and set them all up with HTTPS! With the Let's Encrypt project (https://www.letsencrypt.org) you can get trusted certificates for all those other sites for free. And it's quite easy.