From 861b4478a80f53be2bfeff1954625b531bfb5ab8 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 20 Jul 2026 19:29:26 +0000 Subject: [PATCH] =?UTF-8?q?Fix=20Authelia=20protection=20being=20dead=20co?= =?UTF-8?q?de=20=E2=80=94=20reverse=5Fproxy=20ran=20before=20the=20auth=20?= =?UTF-8?q?check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both Caddy site block generators (the shared configure_caddy_for_service helper, and asterisk-digital-ocean.sh's own inline template) wrote reverse_proxy before the forward_auth/import authelia block. Caddy doesn't reorder repeats of the same directive within a block — forward_auth and reverse_proxy are the same directive family internally, so they run in the order written. With reverse_proxy first, it handled and terminated every request immediately; the auth check written after it never ran at all. Full bypass on every domain using either generator with Authelia protection, regardless of how correct the Authelia access_control rules themselves were — confirmed live against a config that was otherwise completely correct (default_policy: deny, explicit wildcard rule covering the affected domain). Affects every service that's ever passed `import authelia` or a forward_auth block through configure_caddy_for_service (asterisk.sh, wolf-pair.sh, and any future caller), plus asterisk-digital-ocean.sh's own site block. Moved the auth block before reverse_proxy in both generators. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_015X1jRGHwrvovz2qkhKfDZi --- CLAUDE.md | 14 ++++++++++++++ lib/common.sh | 9 ++++++++- services/asterisk-digital-ocean.sh | 9 ++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index f99bb85..0692e30 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -159,6 +159,20 @@ reloads Caddy. No-ops silently if Caddy isn't installed. The fourth argument is an optional string inserted verbatim inside the Caddy site block (use it for `import authelia` or custom matchers). +The function places that block **before** `reverse_proxy` in the generated +site block — don't reorder this. `forward_auth` (what `import authelia` +expands to) is the same directive family as `reverse_proxy` internally, and +Caddy doesn't reorder repeats of the same directive within a block; it runs +them in the order they're written. `reverse_proxy` written first would +handle and terminate every request immediately, making an auth check +written after it dead code that never runs — full bypass regardless of what +the auth server's own access-control rules say. Confirmed live: this was +the actual cause of a "Caddy proxies fine but Authelia never prompts for +login" bug, on a site block that otherwise looked completely correct. If a +service builds its own site block instead of using this helper (e.g. +`services/asterisk-digital-ocean.sh` does, deliberately, see its own +comment for why), put its auth block first there too. + Sets two out-params (not `local` — read them after the call returns) so the caller can tell whether Caddy actually ended up fronting the service: diff --git a/lib/common.sh b/lib/common.sh index 80102ad..eca7cf0 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -573,6 +573,14 @@ configure_caddy_for_service() { # $SERVICE_NAME ${SERVICE_DOMAIN} { + # Auth (if any) must come before reverse_proxy — forward_auth is the + # same directive family as reverse_proxy internally, and Caddy doesn't + # reorder repeats of the same directive within a block; it runs them in + # the order they're written. With reverse_proxy first, it would handle + # and terminate every request immediately, so an auth check written + # after it would be dead code that never runs — full bypass regardless + # of what the auth server's own rules say. +${EXTRA_CONFIG} reverse_proxy ${_BLOCK_UPSTREAM} # Security headers @@ -588,7 +596,6 @@ ${SERVICE_DOMAIN} { output file /var/log/caddy/${SERVICE_DOMAIN}.log format json } -${EXTRA_CONFIG} } CADDY_BLOCK )" diff --git a/services/asterisk-digital-ocean.sh b/services/asterisk-digital-ocean.sh index 6282c44..480fb23 100755 --- a/services/asterisk-digital-ocean.sh +++ b/services/asterisk-digital-ocean.sh @@ -628,6 +628,14 @@ ENV # Asterisk Web Admin ${DOMAIN_NAME} { + # Auth (if any) must come before reverse_proxy — forward_auth is the + # same directive family as reverse_proxy internally, and Caddy doesn't + # reorder repeats of the same directive within a block; it runs them in + # the order they're written. With reverse_proxy first, it would handle + # and terminate every request immediately, so an auth check written + # after it would be dead code that never runs — full bypass regardless + # of what the auth server's own rules say. +${EXTRA_BLOCK} reverse_proxy ${_PROXY_TARGET} header { @@ -641,7 +649,6 @@ ${DOMAIN_NAME} { output file /var/log/caddy/${DOMAIN_NAME}.log format json } -${EXTRA_BLOCK} } CADDY_BLOCK )"