Score:0

nginx/swag and FULLY ignoring unknown subdomains

co flag

I have a domain, let's call it foo.dev.

If someone navigates to anything other than the subdomains I have site-confs for, I want it to look like there's nothing at all set up on the domain. If someone goes to http://foo.dev or http://www.foo.dev or http://gibberish.foo.dev, or tries to go directly to my IP address, I want them to get a not found error. Same with https.

Every search hit I've found says "just use 444." But 444 still leaks that there's a server there; if I go to http://gibberish.foo.dev, it says connection reset. If I shut my server down and try revisiting, it says that it couldn't find that page.

I've tried this in site-confs/default.conf:

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

server {
    listen       443  ssl;
    server_name _;
    return 444;
}

The other issue I'm having is that if I navigate to a https subdomain like https://randomgiberish.foo.dev, it serves my subdomain's site for some reason, even though the subdomain is invalid! It doesn't even do the connection reset.

My site-conf/mysterioussubdomain.foo.dev.conf file:

# only serve https
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 443 ssl http2;
    server_name mysterioussubdomain.foo.dev;

    # Hide from search engine crawlers
    add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive";

    # make sure ssl is enabled
    include /config/nginx/ssl.conf;

    client_max_body_size 0;
    ssl_session_cache shared:SSL:10m;
    proxy_buffering off;

    location / {
        include /config/nginx/proxy.conf;

        # Set proxy headers
        # proxy_set_header Host $host;
        # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # proxy_set_header X-Forwarded-Proto $scheme;

        # These are important to support WebSockets
        # proxy_set_header Upgrade $http_upgrade;
        # proxy_set_header Connection "Upgrade";

        resolver 127.0.0.11 valid=30s;

        set $upstream_proto http;
        set $upstream_app myapp;
        set $upstream_port 30000;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    } 

    location /health-check {
        add_header Content-Type text/plain;
        return 200 "OK\n";
    }
}

Edit: I have found this post which says to add server_name_in_redirect off;. This partially solves the second problem. Rather than a random subdomain causing content to be served, it now gives an error about being unable to confirm authenticity. This is effectively the same as the first problem, though.

Richard Smith avatar
jp flag
You are missing the `default_server` option on the default `listen 443 ssl;` statement. Which is maybe why Nginx is choosing a different server block to handle random `https` requests.
Richard Smith avatar
jp flag
What you are asking for is impossible. First the browser connects to your server's IP address, then it passes the domain name it is attempting to access. The browser already knows that there is a server there, before it passes the name of the domain, so the best you can achieve is close the connection using 444.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.