fix(caddy): restore the IP gate on nine sites where it was dead code
Deploy Caddyfile to valhalla / deploy (push) Failing after 43s

Caddy sorts the `route` directive ahead of `respond`, so on any site that
wrapped its handlers in a catch-all `route {}`, the `import internal_only`
above it never executed — the route matched everything and handled the
request before the 403 was reached. Confirmed in the adapted JSON: the
route was sub[0] with match="<always>" and the 403 was sub[1], unreachable.

sonarr, radarr, bazarr, prowlarr, tautulli, qbittorrent, nzbget, whisparr
and stash were all affected. They were still behind Authentik, so this was
not an open door, but the LAN/tailnet restriction was doing nothing.

Add an (internal_gate) snippet with the same IP check, intended to be
imported as the first directive INSIDE a route, where directives run in
written order. Verified in the adapted config: the 403 is now [0] inside
the route, ahead of the outpost proxy and the handle blocks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
ginnoir
2026-08-05 11:38:58 -05:00
co-authored by Claude Opus 5
parent cc960eb3eb
commit 61cea7ee04
+21 -9
View File
@@ -17,6 +17,18 @@
respond @blocked "Access denied" 403
}
# Same IP gate as (internal_only), but for use INSIDE a route{} block.
# Caddy sorts the `route` directive ahead of `respond`, so an `import
# internal_only` sitting above a catch-all `route {}` is dead code — the route
# matches everything and handles the request before the 403 is ever reached.
# Inside a route, directives run in written order, so importing this as the
# first line of the route makes the gate fire. Use this, not internal_only,
# on any site that wraps its handlers in route{} (i.e. the Authentik sites).
(internal_gate) {
@blocked_ip not remote_ip 192.168.1.0/24 172.16.0.0/12 100.64.0.0/10 127.0.0.1
respond @blocked_ip "Access denied" 403
}
# TB-006 — Authentik forward auth (embedded outpost on authentik-server:9000).
# Wrap protected sites in `route { ... }` so bypass handles run before forward_auth.
(authentik_outpost) {
@@ -126,8 +138,8 @@ requests.ginnoir.com {
# =============================================================
sonarr.ginnoir.com {
import internal_only
route {
import internal_gate
import authentik_outpost
handle /api/* {
reverse_proxy sonarr:8989
@@ -140,8 +152,8 @@ sonarr.ginnoir.com {
}
radarr.ginnoir.com {
import internal_only
route {
import internal_gate
import authentik_outpost
handle /api/* {
reverse_proxy radarr:7878
@@ -154,8 +166,8 @@ radarr.ginnoir.com {
}
bazarr.ginnoir.com {
import internal_only
route {
import internal_gate
import authentik_outpost
handle /api/* {
reverse_proxy bazarr:6767
@@ -168,8 +180,8 @@ bazarr.ginnoir.com {
}
prowlarr.ginnoir.com {
import internal_only
route {
import internal_gate
import authentik_outpost
handle /api/* {
reverse_proxy prowlarr:9696
@@ -182,8 +194,8 @@ prowlarr.ginnoir.com {
}
tautulli.ginnoir.com {
import internal_only
route {
import internal_gate
import authentik_outpost
handle {
import authentik_forward_auth
@@ -196,8 +208,8 @@ tautulli.ginnoir.com {
# DOWNLOAD CLIENTS — internal only
# =============================================================
qbittorrent.ginnoir.com {
import internal_only
route {
import internal_gate
import authentik_outpost
handle {
import authentik_forward_auth
@@ -207,8 +219,8 @@ qbittorrent.ginnoir.com {
}
nzbget.ginnoir.com {
import internal_only
route {
import internal_gate
import authentik_outpost
handle {
import authentik_forward_auth
@@ -218,8 +230,8 @@ nzbget.ginnoir.com {
}
whisparr.ginnoir.com {
import internal_only
route {
import internal_gate
import authentik_outpost
handle /api/* {
reverse_proxy whisparr:6969
@@ -232,8 +244,8 @@ whisparr.ginnoir.com {
}
stash.ginnoir.com {
import internal_only
route {
import internal_gate
import authentik_outpost
handle {
import authentik_forward_auth