Nginx & Multiple SSL Domains

September 5, 2017 2.4k views
Nginx DigitalOcean Ubuntu 16.04

Hi,

I'm using three domain names, one droplet and an nginx server to serve the three domains.

So far, I've managed to redirect from www.example.com to example.com for all domains and also force the websites to load on an SSL connection managed by certbot.

The problem that I'm facing is that, when I use the IP address of the droplet I get the non-HTTPS version of one of the websites (The first one in alphabetical order).

Is this normal behaviour? If not, how can I stop it from happening?

Any ideas?

I have three configuration files in sites-available with symbolic links pointing to sites-enabled.

Below is a configuration file for one of the websites.

The other two are practically the same.

server {
        listen 80;

        root /var/www/html/example.com;
        index index.html index.htm;

        server_name example.com;

        location / {
                try_files $uri $uri/ =404;
        }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
     ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/ssl/certs/dhparam.pem;

    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    } # managed by Certbot

}

server {
        listen 80;
        server_name example.com;
        return 301 $scheme://example.com$request_uri;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot


    # Redirect non-https traffic to https
    # if ($scheme != "https") {
    #     return 301 https://$host$request_uri;
    # } # managed by Certbot

}

Thank you for your time and any help is appreciated!

1 Answer

Yes, that is normal behavior. When Nginx receives a request that doesn't match any defined server_name it will rout it to the default server. If a default is not specified, Nginx will use the first server block defined.

To specify a default, add default_server to the end of a listen directive. For example:

listen       80  default_server;
server_name example.com;

So in your case, accessing the Droplet via IP address means that the server_name will never match and you'll be routed to the first one in alphabetical order. To disable all access via IP address, you can create a new server block that returns an error when accessed:

server {
    listen       80  default_server;
    server_name  _;
    return       444;
}

For more information on how Nginx handles all of this, take a look at their docs on the server_name directive.

Have another answer? Share your knowledge.