Profilarr replaces the recyclarr/TRaSH-Guides flow with a stateful web
service that owns *arr profiles end-to-end via its own UI. Runs as an
oci-container on 127.0.0.1:6868, fronted by nginx at
profilarr.nordhammer.it behind Authelia (one_factor).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- nginx: strip Referer on torrent.nordhammer.it so qBit's origin check
doesn't reject the post-Authelia redirect (Referer was auth.nordhammer.it,
Host was torrent.nordhammer.it → 401 loop).
- tmpfiles: collapse the nested qbittorrent `d` rules into a single
`d` + recursive `Z` so systemd re-enforces ownership/perms on every
boot. Caught Docker-migration UID drift that silently broke state
persistence and file logging.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
qBittorrent's auth logic is "no SID cookie → bypass for localhost; SID
cookie present → validate it." If the browser has a stale SID from an
earlier session, qBit fails validation and returns 401 even though the
connection is from 127.0.0.1 and bypass is enabled.
Strip both directions: drop the client's Cookie header on the way in so
qBit never sees an SID, and hide Set-Cookie on the way back so the
browser never accumulates one in the first place.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Only Jellyfin and the Authelia portal itself stay unprotected externally
(Jellyfin because it's streamed to remote clients; Authelia because it
is the login gate). Everything else (sonarr, radarr, bazarr, prowlarr,
torrent/qBittorrent, games, search) now goes through Authelia forward auth.
Internal integrations (Homepage widgets, Prowlarr → Sonarr/Radarr,
Bazarr → Sonarr/Radarr, transcode-hevc qBit queries) use 127.0.0.1:PORT
directly, so they are unaffected.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
New services/adguard.nix runs AdGuard Home on the mediaserver with DoH
upstreams (Cloudflare + Quad9) and three default blocklists. DNS listens
on :53; web UI on 127.0.0.1:3000, reverse-proxied at adguard.nordhammer.it.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Publishes the container's web dashboard port only on host loopback
(127.0.0.1:8090) so nginx can reverse-proxy it with Authelia
forward-auth, matching the Homepage/camera vhost pattern. Also flips
WebDashboardEnabled to true in the XML patcher so the server actually
starts the web server.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
record-update parses nvd diff after switch and writes latest.json;
Homepage polls a local-only nginx listener and renders date/changes/
closure/kernel via a customapi widget.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Runs Tdarr server with internal node on the mediaserver for managing
library-wide re-encoding to save disk space. Web UI at tdarr.nordhammer.it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cloudflare's authoritative nameservers take longer than the
default 2-minute timeout to propagate TXT records created via
API. Set CLOUDFLARE_PROPAGATION_TIMEOUT=600 to give enough
time for DNS-01 challenge validation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
--dns.resolvers is a global lego flag, not a run/renew subcommand
flag. Use extraLegoFlags instead of extraLegoRunFlags.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Route DNS propagation checks through 1.1.1.1 only, bypassing
the local resolver that caches stale responses and causes
wildcard cert DNS-01 challenges to time out.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Disabling the propagation check caused lego to submit to Let's
Encrypt before Cloudflare's authoritative nameservers had the
TXT record. A 30s wait gives Cloudflare time to propagate.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Local DNS resolver caches stale responses causing the wildcard
cert DNS-01 challenge to time out before propagation is confirmed.
Cloudflare's authoritative servers propagate fast enough for
Let's Encrypt to validate without the client-side check.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use /api/verify endpoint instead of /api/authz/forward-auth
- Add proxy_pass_request_body off to auth location
- Put redirect URL inline in error_page instead of using a variable
- Use X-Forwarded-Uri (matching old config) instead of X-Forwarded-URI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
auth_request_set reads variables from the auth subrequest context where
$scheme/$http_host/$request_uri are empty, causing a 500 instead of a
302 redirect. Using set captures from the main request context.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CNAME interference is resolved so the default lego propagation check
(querying Cloudflare authoritative NS) should work correctly now.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous dnsPropagationCheck=false caused lego to ask LE to validate
before the TXT record was globally visible. Adding --dns.propagation-wait
gives Cloudflare time to serve the record from all edge locations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cloudflare is the authoritative NS so API-created TXT records are
immediately visible — the propagation poll was timing out unnecessarily.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Native nginx with ACME wildcard cert (*.nordhammer.it) via Cloudflare DNS-01
- Native Authelia SSO with forward auth protecting homepage + camera
- Native go2rtc camera streaming (no more Docker)
- Auto-migration script for Authelia secrets and user database from Docker
- Homepage hrefs updated to use HTTPS domain names
- Fail2ban updated for native nginx log paths + new Authelia jail
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>