Your one-stop-cake-shop for everything Freshly Baked has to offer

feat(pm): block missing nginx host connections

We previously returned One Of The Websites when nginx was accessed from
a host that we didn't know about. That included direct IP address access
as well as things which have been CNAMEd to us (either through a starred
record or due to past services) but which aren't actually hosted by us.

This leads to a number of undesireable effects:
- User confusion ("why does the aux docs website have Stalwart?")
- Incorrect SSL certificates ("your blog seems to have an invalid
certificate")
- SSL being offered via direct IPs, which isn't possible to sign on the
public internet

We can block this by making a default server to take control whenever
nothing matches, and setting that default server to block all
connections and reject all SSL handshakes

We need to have a certificate for this, but it needn't actually be valid
for anything so let's self sign stuff...

Changed files
+37
packetmix
systems
common
+37
packetmix/systems/common/nginx.nix
··· 1 + # SPDX-FileCopyrightText: 2025 FreshlyBakedCake 2 + # 3 + # SPDX-License-Identifier: MIT 4 + 5 + { lib, ... }: 6 + { 7 + # By default, nginx will serve a "best-effort" site even if there is no matching vhost 8 + # We can disable this by making a matching vhost and returning 444... 9 + # Notice how we don't enable nginx here: that makes this safe to deploy even on places that don't currently run nginx. We're effectively changing the default behavior 10 + services.nginx.virtualHosts."missinghost.invalid" = { 11 + default = true; 12 + 13 + addSSL = true; 14 + enableACME = true; 15 + acmeRoot = null; 16 + 17 + locations."/".return = "444"; 18 + 19 + extraConfig = '' 20 + ssl_reject_handshake on; 21 + ''; 22 + }; 23 + 24 + systemd.services."acme-missinghost.invalid".enable = false; 25 + systemd.timers."acme-missinghost.invalid".enable = false; 26 + 27 + systemd.targets."acme-finished-missinghost.invalid" = { 28 + requires = lib.mkForce [ "acme-selfsigned-missinghost.invalid.service" ]; 29 + after = lib.mkForce [ "acme-selfsigned-missinghost.invalid.service" ]; 30 + }; 31 + 32 + security.acme.acceptTerms = true; 33 + security.acme.certs."missinghost.invalid" = { 34 + webroot = "/dev/null"; 35 + email = "invalid@missinghost.invalid"; 36 + }; # Nix requires some values, even if we're actually disabling the acme-missinghost.invalid service... that's problematic if there are no defaults for the system 37 + }