From 4d58e5ca38aeccf9d6111a0fca0d913ebb40dfae Mon Sep 17 00:00:00 2001 From: Connor Johnstone Date: Tue, 8 Sep 2026 16:43:38 -0400 Subject: [PATCH] Publish news.rcjohnstone.com with a carve-out for the feedback path Applied to the live Caddyfile (snapshot: ~/Caddyfile.pre-news-public) and reloaded; ddns_update published the A record and Let's Encrypt issued a cert. The block moved out of the "Internal only -- no public DNS record" section into the Public section rather than just gaining a marker in place. Those section headers are load-bearing documentation, and a public block sitting under an internal header would make the file lie about its own security posture. /api/feedback/* bypasses Authelia because ntfy runs action buttons from the phone and a native app cannot complete an interactive login -- the exemption ntfy, Immich and Jellyfin already have on this box. That path is HMAC-signed per (cluster, kind), so a leaked URL casts one vote on one story. Verified after reload: / and /healthz return 403 from Authelia while /api/feedback/... returns 404, and a 404 from the still-running old backend is what proves Caddy routed it through unauthenticated. Worth recording, since it is irreversible: publishing the name also publishes it to Certificate Transparency, which is append-only and world-readable. The hostname is public forever regardless of any later change. --- deploy/README.md | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 45d05a6..e2ae741 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -52,11 +52,19 @@ Copy `profile/*.toml` to `~/config/news2/`. A bind-mounted config edit needs container when only a mounted file changed. An **environment** change does need the full `up -d`. -## 2. Caddy +## 2. Caddy — APPLIED 2026-09-08 -The existing `news.rcjohnstone.com` block serves a static SPA from -`/srv/news/dist` and proxies only `/api*`. This app renders its own pages, so -the block simplifies -- but it must also become reachable from the phone. +Done. The block was moved out of the "Internal only" section into the Public +section (the section headers are load-bearing documentation, and leaving a +public block under an internal header would make the file lie), given a +`# ddns: public` marker, and reloaded. `ddns_update` published the A record and +Let's Encrypt issued a cert for the name. + +Snapshot of the previous file: `~/Caddyfile.pre-news-public`. + +Verified after reload: `/` and `/healthz` return 403 (Authelia gating), while +`/api/feedback/...` returns 404 -- a 404 from the OLD backend, which proves +Caddy routed it through without authentication. ``` # ddns: public @@ -91,8 +99,18 @@ that, feedback buttons fail on cellular and the digest link is unopenable away from home -- and silent failure there is precisely how the previous version ended up with 32 labels in a week. -`/srv/news/dist` becomes unused and the `news-update` systemd timer that -populated it can be disabled. +`/srv/news/dist` is now unused and the root-owned `news-update` systemd timer +that populated it should be disabled: + +```sh +sudo systemctl disable --now news-update.timer +``` + +**Current state:** the vhost is public and correctly gated, but `news-backend` +is still the old Rust service, which no longer has its SPA served by Caddy. So +`https://news.rcjohnstone.com/` is a 404 behind the login until the compose +service is switched to this image. Notifications from the old service are +unaffected. ## 3. Scheduling