From 03c20dc24d652b82dc762613d7a837e51bcaa6bf Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Sat, 1 Aug 2026 18:18:44 +0000 Subject: [PATCH] Warn when a new origin block silently steals the default vhost Second thing the first live run got wrong, and this one broke a working site rather than just misreporting. nginx picks the first-parsed server block for a listen address as the default when nothing is marked `default_server`, and sites-enabled is parsed in filename order. `chovy.hacker` sorts ahead of `userdirs.conf`, so adding it made it the default vhost for 443 on a box that had never declared one. Every request with no SNI or an unmatched Host then got a self-signed certificate for a Moshpit name instead of the box's real one -- which presents as the *other*, untouched sites breaking. Detected by asking the loaded config whether anything claims default_server for 443, and saying plainly what to do if not. Not fixed automatically: the remedy is to edit somebody else's server block, and this script should not reach into unrelated config to do that unasked. Verified on the box it happened to: marking the pre-existing block restored the correct certificate for no-SNI and unmatched hosts, with chovy.hacker still answering with its own. Co-Authored-By: Claude Opus 5 (1M context) --- scripts/setup-origin.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scripts/setup-origin.sh b/scripts/setup-origin.sh index b3bc99d..bf62a45 100755 --- a/scripts/setup-origin.sh +++ b/scripts/setup-origin.sh @@ -138,6 +138,22 @@ fi # certificate — which is exactly the bug this script exists to fix. So ask the # running server what it actually presents for this name. if [ "$DRY_RUN" = "0" ]; then + # Adding a block to a box that already serves other sites can silently steal + # the default vhost. nginx picks the first-parsed server for a listen address + # when nothing is marked `default_server`, and files in sites-enabled are + # parsed in filename order -- so `chovy.hacker` sorts ahead of `userdirs.conf` + # and becomes the default. Every request with no SNI or an unmatched Host then + # gets this name's self-signed certificate instead of whatever the box used to + # answer with, which looks like the *other* sites broke. + # + # Found by doing exactly this to a live server. + if [ "$(nginx -T 2>/dev/null | grep -c 'listen.*443.*default_server')" = "0" ]; then + warn "no server block on this box marks itself \`default_server\` for 443." + warn "adding $NAME may have taken over as the default vhost, so requests" + warn "with no SNI or an unmatched Host now get its self-signed certificate." + warn "fix by marking the intended default, e.g. \`listen 443 ssl default_server;\`" + fi + step "checking what the server now presents for $NAME" # Retried, because `nginx -s reload` returns as soon as the signal is sent,