Nginx redirects all https requests for multiple domains to one domain

nginx

I am hosting multiple domains on a server with nginx server blocks. For some reason when other domains are requested with https it always loads one particular website.

  • domain1.com /var/www/domain1.com
  • domain2.com /var/www/domain2.com

When I type http://domain1.com this loads correctly but when I type https://domain1.com it serves what's under /var/domain2.com

Below is my nginx config for domain2 server block which has ssl. I am guessing the listen 443 ssl default_server; on the 3rd server block is the culprit but not sure how to proceed. I tried removing the default_server from there but that breaks the site.

How do I configure the nginx config so that other domains are not serving the wrong website when requested with https. I appreciate any help.

# Default server configuration
#

server {
    listen 80;
    listen [::]:80;
    server_name domain2.com www.domain2.com;
    return 301 https://www.domain2.com$request_uri;
}

server {
    listen 443;
    listen [::]:443;
    server_name domain2.com;
    return 301 https://www.domain2.com$request_uri;
}

server {
    # SSL configuration
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    server_name www.domain2.com;
    include snippets/ssl-domain2.com.conf;
    include snippets/ssl-params.conf;
    # Self signed certs generated by the ssl-cert package
    # Don't use them in a production server!
    #
    # include snippets/snakeoil.conf;

    root /var/www/domain2.com;

    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm index.nginx-debian.html;

    location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.

            try_files $uri $uri/ /index.php?$args;
    }
...

Best Answer

Well, what you are observing is a normal and expected behaviour. You have several domains pointing to one IP address, and only one HTTPS host is configured on the webserver that the target machine runs. Whether you have the default_server server clause or not, you'll always will have a default vhost for a given port. Considering that fact that a default vhost will always terminate all the request that don't have the appropiate server_name, and given that you have only one server for port 443 and it will be the default, it will terminate all the HTTP request to this web-server. In fact, this behavior isn't nginx-specific, you would get same behavior on apache and I guess every other web server implementation.

Define exactly what do you mean other domains are not serving the wrong website and configure you web server accordingly. I suggest you configure the HTTPS for all the other domain or just accept this behavior, because you cannot filter HTTP sessions on a packet filter without breaking your working HTTPS site. The last option would be creating dummy HTTPS sites for all the domains you don't want to sertve and serve 403 status there, but that would be just wrong.