diff --git a/nix/host-modules/hive-gateway/vhosts.nix b/nix/host-modules/hive-gateway/vhosts.nix index cf4ecb4f..f872abb7 100644 --- a/nix/host-modules/hive-gateway/vhosts.nix +++ b/nix/host-modules/hive-gateway/vhosts.nix @@ -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 = {