diff --git a/Caddyfile b/Caddyfile index aa2f4bd..a0d8e59 100644 --- a/Caddyfile +++ b/Caddyfile @@ -36,22 +36,27 @@ remote_ip 192.168.1.0/24 172.16.0.0/12 100.64.0.0/10 127.0.0.1 } -# Shared-link gate — external users visit ?k={$SHARE_KEY} once to get a 30-day cookie. +# Shared-link gate — external users visit ?k= once to get a 30-day cookie. # Internal IPs and tailnet clients pass through unconditionally. # Usage: import share_gate (replaces import internal_only on shared services) +# Uses {$SHARE_KEY} (parse-time substitution) — baked in at caddy reload/start when the +# env var is set. Rotate: update SHARE_KEY in stack.env, push → Portainer redeploys → key changes. (share_gate) { - route { - @has_key query k={$SHARE_KEY} - handle @has_key { - header Set-Cookie "share_access={$SHARE_KEY}; Path=/; Max-Age=2592000; HttpOnly; Secure; SameSite=Strict" - redir {http.request.uri.path} 302 + @external not remote_ip 192.168.1.0/24 172.16.0.0/12 100.64.0.0/10 127.0.0.1 + handle @external { + route { + @has_key query k={$SHARE_KEY} + handle @has_key { + header Set-Cookie "share_access={$SHARE_KEY}; Path=/; Max-Age=2592000; HttpOnly; Secure; SameSite=Strict" + redir {http.request.uri.path} 302 + } + @has_cookie expression `{http.request.cookie.share_access} == "{$SHARE_KEY}"` + handle @has_cookie { + } + handle { + respond "Access denied" 403 + } } - - @deny_external { - not remote_ip 192.168.1.0/24 172.16.0.0/12 100.64.0.0/10 127.0.0.1 - not expression `{http.request.cookie.share_access} == "{$SHARE_KEY}"` - } - respond @deny_external "Access denied" 403 } }