Search code examples
sslnginxssl-certificatevhosts

nginx - set multiple server_name with ssl-support


I'd love to use nginx to serve a website with multiple domain names and SSL:

  • webmail.example.com
  • webmail.beispiel.de

Both use the same vhost so I only set the server_name twice. Problem is, that I need nginx to serve the correct ssl certificate for each domain name.

Is this possible with one vhost or do I need to set up two vhosts?


Solution

  • Edit November 2014: the initial answer is not correct and is incomplete ; it needed a refresh! here it is.

    Basically, there are two cases

    • You own a wildcard certificate (or multi-domains certificate)

    In this case, you may use several vhosts listening to the same IP address/https port, and both vhosts use the same certificate (listening on all interfaces), e.g.

        server {
          listen 443;
          server_name webmail.example.com;
          root /var/www/html/docs/sslexampledata;
        
          ssl on;
          ssl_certificate /var/www/ssl/samecertif.crt;
          ssl_certificate_key /var/www/ssl/samecertif.key;
          ...
        }
        
        
        server {
          listen 443;
          server_name webmail.beispiel.de;
          root /var/www/html/docs/sslbeispieldata;
        
          ssl on;
          ssl_certificate /var/www/ssl/samecertif.crt;
          ssl_certificate_key /var/www/ssl/samecertif.key;
          ...
        }
    

    or in you specific case, having both domains served by the same data

        server {
          listen 443;
          server_name webmail.example.com webmail.beispiel.de; # <== 2 domains
          root /var/www/html/docs/sslbeispieldata;
        
          ssl on;
          ssl_certificate /var/www/ssl/samecertif.crt;
          ssl_certificate_key /var/www/ssl/samecertif.key;
          ...
        }
    



    • You have two(+) different certificates

    The case above (one IP for all certificates) will still work with modern browsers via Server Name Indication. SNI has the client (browser) send the host it wants to reach in the request header, allowing the server (nginx) to deal with vhosts before having to deal with the certificate. The configuration is the same as above, except that each vhost has a specific certificate, crt and key.

    (nginx support SNI from 0.9.8f, check your nginx server is SNI compliant)
    (also, SF talks about SNI and browser support)

    Otherwise, if you want to reach older browsers as well, you need several vhosts listening each to a different IP addresses/https ports, e.g.

        server {
          listen 1.2.3.4:443; # <== IP 1.2.3.4
          server_name webmail.example.com;
          root /var/www/html/docs/sslexampledata;
        
          ssl on;
          ssl_certificate /var/www/ssl/certifIP1example.crt;
          ssl_certificate_key /var/www/ssl/certifIP1example.key;
          ...
        }
        
        
        server {
          listen 101.102.103:443; <== different IP
          server_name webmail.beispiel.de;
          root /var/www/html/docs/sslbeispieldata;
        
          ssl on;
          ssl_certificate /var/www/ssl/certifIP2beispiel.crt;
          ssl_certificate_key /var/www/ssl/certifIP2beispiel.key;
          ...
        }
    

    The reason is well explained here.