diff --git a/nix/host-modules/hive-forge/default.nix b/nix/host-modules/hive-forge/default.nix index 63d2b173..d0fca0f6 100644 --- a/nix/host-modules/hive-forge/default.nix +++ b/nix/host-modules/hive-forge/default.nix @@ -517,6 +517,10 @@ in # co-location nobody had agreed to. The name resolves here # today and resolves off-host later without this line moving. proxyPass = "https://${autheliaCfg.domain}/api/authz/auth-request"; + # nixpkgs appends its OWN `Host $host` after extraConfig, + # which would override verifiedProxyTo's — see the comment + # on verifiedProxyTo in hive-gateway/vhost-lib.nix. + recommendedProxySettings = false; extraConfig = '' internal; ${gatewayCfg.lib.verifiedProxyTo autheliaCfg.domain} diff --git a/nix/host-modules/hive-gateway/vhost-lib.nix b/nix/host-modules/hive-gateway/vhost-lib.nix index 74212d4e..c02f1745 100644 --- a/nix/host-modules/hive-gateway/vhost-lib.nix +++ b/nix/host-modules/hive-gateway/vhost-lib.nix @@ -112,12 +112,32 @@ in # testing though — the session cache is keyed by upstream address and # NOT by trust config, so two locations pointing at one upstream with # different trust do not verify independently. + # + # ⚠️ Also pins `Host` (and reinstates the rest of nginx's + # `recommendedProxySettings` header set) to `name` rather than leaving + # it to be filled in later. `name` here resolves back to THIS gateway + # — every consumer dials another vhost on the same nginx, not a + # separate host — and nginx picks the vhost to answer an HTTPS request + # from the `Host` header, not from the TLS SNI that `proxy_ssl_name` + # above sends. `recommendedProxySettings`'s own `Host $host` (the + # CALLER's host, not the target) is textually appended by nixpkgs + # AFTER a location's `extraConfig` — so it always wins over a + # `proxy_set_header Host` written in the location body, and the + # subrequest loops back into the ORIGINAL vhost instead of reaching + # the target, recursing on its own `auth_request` until nginx's + # subrequest-depth limit turns it into a plain 500. Every call site + # sets `recommendedProxySettings = false` on the location for exactly + # this reason — nixpkgs' version would still clobber this one. verifiedProxyTo = name: '' proxy_ssl_verify on; proxy_ssl_verify_depth 3; proxy_ssl_trusted_certificate ${caBundle}; proxy_ssl_name ${name}; proxy_ssl_server_name on; + proxy_set_header Host ${name}; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Server $hostname; ''; # Security headers added at the server scope on every vhost. diff --git a/nix/host-modules/swarm-ui.nix b/nix/host-modules/swarm-ui.nix index 7ac10f1c..e92b5cec 100644 --- a/nix/host-modules/swarm-ui.nix +++ b/nix/host-modules/swarm-ui.nix @@ -273,6 +273,10 @@ in # frontend calls this one directly. "= /api/whoami" = { proxyPass = "https://${autheliaCfg.domain}/api/user/info"; + # nixpkgs appends its OWN `Host $host` after extraConfig, + # which would override verifiedProxyTo's — see the comment + # on verifiedProxyTo in hive-gateway/vhost-lib.nix. + recommendedProxySettings = false; extraConfig = '' ${swarmAuthRequest} ${gatewayCfg.lib.verifiedProxyTo autheliaCfg.domain} @@ -296,6 +300,10 @@ in # would look like configuration and be dead weight. "= /__hive_authelia" = { proxyPass = "https://${autheliaCfg.domain}/api/authz/auth-request"; + # nixpkgs appends its OWN `Host $host` after extraConfig, + # which would override verifiedProxyTo's — see the comment + # on verifiedProxyTo in hive-gateway/vhost-lib.nix. + recommendedProxySettings = false; extraConfig = '' internal; ${gatewayCfg.lib.verifiedProxyTo autheliaCfg.domain} diff --git a/nix/host-modules/swarm-victorialogs.nix b/nix/host-modules/swarm-victorialogs.nix index 39b1b44f..68f87a1f 100644 --- a/nix/host-modules/swarm-victorialogs.nix +++ b/nix/host-modules/swarm-victorialogs.nix @@ -183,6 +183,10 @@ in # pinned authelia binary, not copied from an example). "= /__hive_authelia" = { proxyPass = "https://${autheliaCfg.domain}/api/authz/auth-request"; + # nixpkgs appends its OWN `Host $host` after extraConfig, + # which would override verifiedProxyTo's — see the comment + # on verifiedProxyTo in hive-gateway/vhost-lib.nix. + recommendedProxySettings = false; extraConfig = '' internal; ${gatewayCfg.lib.verifiedProxyTo autheliaCfg.domain}