Hero Image

No default website!

No default website

A "default" website is the website a webserver will fall back to when there is no other website configured with a specific name.

I believe, that you should not have a default website. Why? Well:

  1. SSL/TLS-certificates only work with specific names. Unknown names will cause certificate errors anyway.
  2. Don't make it attackers too easy to figure out what website(s) run(s) on your system.
    Attackers usually connect to IP-addresses without knowing the name of a website for it.

For insecure HTTP-requests, you'll probably want a full redirect to HTTPS. Just redirect by default and avoid having other configurations for port 80:

server {
    listen 0.0.0.0:80 default_server;
    listen    [::]:80 default_server;

    server_name _;

    # Redirect to the exact same URL, but https:// instead.
    location / {
        return 302 https://$host$request_uri;
    }
}

Next, for HTTPS, generate a SSL/TLS-certificate to use as fallback, that clarifies through the Common Name that you require SNI-support:

openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \
    -subj '/CN=sni-support-required-for-valid-ssl' \
    -keyout /etc/ssl/nginx-fallback.key \
    -out /etc/ssl/nginx-fallback.crt

Lastly, configure a default website that will disconnect clients if they connect without supplying a configured SNI-host:

server {
    listen 0.0.0.0:443 default_server ssl http2;
    listen    [::]:443 default_server ssl http2;

    server_name _;

    ssl_certificate     /etc/ssl/nginx-fallback.crt;
    ssl_certificate_key /etc/ssl/nginx-fallback.key;

    location / {
        return 444;
    }
}

Note that "444" is a magic HTTP status code, that only works in nginx. It will drop the connection without sending anything else back to the client. No response headers, no content. Attackers will be none the wiser as to what runs on your system!

Alternatively, if you don't want to be that mean and allow for easier troubleshooting with curl, you could opt instead for:

server {
    listen 0.0.0.0:443 default_server ssl http2;
    listen    [::]:443 default_server ssl http2;

    server_name _;

    ssl_certificate     /etc/ssl/nginx-fallback.crt;
    ssl_certificate_key /etc/ssl/nginx-fallback.key;

    location / {
        default_type text/plain;
        return 200 "No website configured at this address.";
    }
}