swarm-authelia: match the metrics rules with or without a query string
Authelia 4.39.20 matches `resources` against the cleaned path plus `?<query>` (authorization/types.go:94 NewObject, utils/url.go:11-34 URLPathFullClean), while nginx's `= /metrics` serves the request whatever its query. `^/metrics$` therefore missed `/metrics?x=1`: both the collector rule and the trailing `deny` were skipped and a plain session reached `default_policy = one_factor`. The pattern is now `^<path>([?].*)?$` for every published target. Forgejo strips trailing slashes before routing (routers/common/ middleware.go stripSlashesMiddleware) and serves metrics without a token when none is configured, so `forge.<swarm>/metrics/` reached its metrics through the ungated `/` location. The forge vhost now answers `= /metrics/` with 404; nginx merges slashes and decodes `%2F` before matching, so that also covers `/metrics//` and `/metrics%2F`. Part of #5205
This commit is contained in:
parent
393e84afd0
commit
8eb11a91da
3 changed files with 96 additions and 10 deletions
|
|
@ -327,6 +327,13 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
# ⚠️ Forgejo strips trailing slashes before routing, so `/metrics/`
|
||||
# reaches the same unauthenticated handler — and the exact match
|
||||
# above does not take it, leaving it to the `/` catch-all. nginx
|
||||
# merges slashes and decodes `%2F` before matching, so this one
|
||||
# location also takes `/metrics//` and `/metrics%2F`.
|
||||
"= /metrics/".return = "404";
|
||||
|
||||
# The subrequest. Same implementation and header set as
|
||||
# `swarm-ui.nix` uses, for the same reason: `X-Original-URL`
|
||||
# and `X-Original-Method` are what authelia's `auth-request`
|
||||
|
|
|
|||
|
|
@ -84,7 +84,11 @@ let
|
|||
parts = builtins.match "https://([^/]+)(/.*)" url;
|
||||
target = {
|
||||
domain = builtins.elemAt parts 0;
|
||||
resources = [ "^${lib.escapeRegex (builtins.elemAt parts 1)}$" ];
|
||||
# ⚠️ Authelia matches `resources` against the cleaned path PLUS the
|
||||
# query string, while nginx's `= <path>` location ignores the query.
|
||||
# A bare `^<path>$` therefore misses `<path>?x`, which the location
|
||||
# still serves, and that request falls through to `default_policy`.
|
||||
resources = [ "^${lib.escapeRegex (builtins.elemAt parts 1)}([?].*)?$" ];
|
||||
};
|
||||
in
|
||||
if parts == null then
|
||||
|
|
|
|||
Loading…
Reference in a new issue