1

I currently have two nginx server blocks to process the requests to any subdomain under example.com. Add subdomains under example.com must be server only with HTTPS. And so the server blocks are as such:

server {
    server_name ~^(.*)\.example\.com$;
    root /var/www/x;
    listen 443 ssl;
    ...
}

server {
    listen 80;
    server_name ~^(.*)\.example\.com$;
    return 301 https://$host$request_uri;
}

Objective

Now, I also want to add a default server block for ANY other server names, but all of its traffic should only be served on HTTP, not HTTPS.

So the first trial was:

server {
    listen 80 default_server;
    server_name _;
    root /var/www/app;
    ...
}

Which works great, but if the processed request was as such: https://abc.def.com then the user will get the "Your connection is not private" scary error, where in fact I'd love if they'd get redirected to HTTP.

If I add:

server {
    listen 443 default_server;
    server_name _;
    return 301 http://$host$request_uri;
}

Then this works, but the second server block stops working and I get that the server is unable to handle the request.

How can I do this?

zed
  • 242
  • 2
  • 3
  • 12

1 Answers1

3

You either listen on port 443 or you don't. If you listen on it, you'll get answer on every hostname pointed to that IP, as the information on hostname is only transferred within the established connection. If you manually type https:// on a non-HTTPS site and the same IP listens on both port 80 for HTTP and 443 for HTTPS, you'll get the warning on all hostnames without a proper TLS certificate.

You have two options:

  1. Make every site available on HTTPS. This shouldn't be a problem in this era of Let's Encrypt, Certbot and Server Name Indication (SNI). This is the only rational solution this day.

  2. Have a separate IP address (e.g. 198.51.100.2) for sites without HTTPS, point them to it. Listen to HTTPS on e.g. 198.51.100.1, and the 198.51.100.2:443 simply doesn't answer:

    server {
        listen *:80 default_server;
        ...
    }
    
    server {
        listen 198.51.100.1:443 default_server ssl;
        ...
    }
    
Esa Jokinen
  • 46,944
  • 3
  • 83
  • 129
  • That would be using SANs to get for all domains, right? I like the IP solution, but it's going to be a bit hard to manage as I scale. – zed Jul 16 '18 at 07:57
  • SAN, if you prefer one certificate. With Let's Encrypt you can have up to 100 SAN domains. Another approach is SNI, allowing multiple certificates on a single IP. – Esa Jokinen Jul 16 '18 at 08:07