fix(3213): the swarm UI vhost forces https

authelia refuses to authorize a non-https target: the auth subrequest for
`X-Original-URL: http://…` answers 400, and nginx's auth_request only
understands 2xx/401/403, so a plain-http visit died as "auth request
unexpected status: 400" — a bare 400 in the browser with no hint that a
login exists.

The shared vhostListen binds :80 as well as :443 and every vhost used
addSSL, so the door was open on a port the lock cannot work on. That is
harmless for forge and matrix, where http is merely insecure rather than
broken, so the asymmetry stays local to the one vhost whose correctness
depends on the scheme.

removeAttrs because nixos asserts on a vhost declaring both addSSL and
forceSSL.

Measured against the pinned binary rather than reasoned about:
  X-Original-URL: http://constellation…/   -> 400 Bad Request
  X-Original-URL: https://constellation…/  -> 401 + Location: auth…?rd=…
This commit is contained in:
atlas 2026-08-12 20:11:33 +02:00
commit d03549c40f

View file

@ -186,8 +186,19 @@ let
# that wrongly denies takes the whole UI away. That is the reason the
# redirect target and the header set below are copied from a measured
# source rather than from an example.
# ⚠️ `forceSSL`, not `addSSL` like every other vhost — not a hardening
# preference, the only way this page works at all. authelia answers the
# auth subrequest for an `http://` target with **400**, and nginx's
# `auth_request` only understands 2xx/401/403, so a plain-http visit
# dies as "auth request unexpected status: 400" with no hint a login
# exists. `vhostListen` binds :80, so without this the door is open on
# a port the lock cannot work on. Serving forge or matrix over http is
# merely insecure rather than broken, so they keep `addSSL` and the
# asymmetry stays local to the vhost whose correctness depends on the
# scheme. `removeAttrs` because nixos asserts on a vhost declaring both.
swarmUiVhost = lib.optionalAttrs uiCfg.enable {
"${uiCfg.domain}" = (vhostTlsFor uiCfg.domain) // {
"${uiCfg.domain}" = (builtins.removeAttrs (vhostTlsFor uiCfg.domain) [ "addSSL" ]) // {
forceSSL = true;
listen = vhostListen;
extraConfig = securityHeaders;
locations = {