Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7e4028a16 | ||
|
|
a03aafb004 |
1 changed files with 153 additions and 151 deletions
|
|
@ -565,6 +565,148 @@ in
|
|||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
${lib.optionalString cfg.hsts.enable ''add_header Strict-Transport-Security "${hstsDirectives}" always;''}
|
||||
'';
|
||||
|
||||
# Forge sub-domain vhost. `server_name = forge.domain`, proxies
|
||||
# all `/` → forgejo. Tuned for git: `client_max_body_size 1G`,
|
||||
# `proxy_read_timeout 1h` (multi-GB clones). SSH stays direct on
|
||||
# `forge.sshPort`. See `docs/gateway.md`. Empty attrset when the
|
||||
# forge isn't behind the gateway.
|
||||
forgeVhost = lib.optionalAttrs (forgeCfg.enable or false && forgeCfg.behindGateway or false) {
|
||||
"${forgeCfg.domain}" = vhostTls // {
|
||||
listen = vhostListen;
|
||||
extraConfig = securityHeaders;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString forgeCfg.httpPort}/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
client_max_body_size 1G;
|
||||
proxy_read_timeout 1h;
|
||||
proxy_send_timeout 1h;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Matrix sub-domain vhost. `server_name = matrixCfg.gatewayHost`.
|
||||
# `/_matrix/*` → tuwunel (CORS *, 50M body cap, 1h long-poll
|
||||
# timeout). `/` serves fluffychat or 404 if GUI off. nginx
|
||||
# longer-prefix-wins puts `/_matrix/` ahead of `/`. See
|
||||
# `docs/gateway.md`. Empty attrset when matrix has no gateway host.
|
||||
matrixVhost = lib.optionalAttrs (matrixCfg.enable && matrixCfg.gatewayHost != null) {
|
||||
"${matrixCfg.gatewayHost}" = vhostTls // {
|
||||
listen = vhostListen;
|
||||
extraConfig = securityHeaders;
|
||||
locations = {
|
||||
"/_matrix/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString matrixCfg.httpPort}";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
client_max_body_size 50M;
|
||||
proxy_read_timeout 1h;
|
||||
proxy_send_timeout 1h;
|
||||
${securityHeaders}
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
'';
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (matrixCfg.gui.enable) (
|
||||
{
|
||||
# fluffychat at sub-domain root, SPA-fallback via
|
||||
# the Accept-header `$matrix_spa_target` map.
|
||||
"/" = {
|
||||
alias = "${matrixCfg.gui.package}/";
|
||||
extraConfig = ''
|
||||
try_files $uri $uri/ $matrix_spa_target =404;
|
||||
'';
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (hyperhiveDomain != null) {
|
||||
# FluffyChat boot-config pre-fill so the client's
|
||||
# `.well-known/matrix/client` lookup hits the
|
||||
# right delegation endpoint.
|
||||
"= /config.json" = {
|
||||
extraConfig = ''
|
||||
default_type application/json;
|
||||
return 200 '{"defaultHomeserver":"${hyperhiveDomain}"}';
|
||||
'';
|
||||
};
|
||||
}
|
||||
)
|
||||
// lib.optionalAttrs (!matrixCfg.gui.enable) {
|
||||
"/" = {
|
||||
return = "404";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# `_` (default) server location groups, lifted out of the inline
|
||||
# `//`-chain so the two matrix groups (each with its own `let`)
|
||||
# read on their own. Composed into the `_` vhost's `locations`
|
||||
# below alongside the still-inline agent/dashboard/auth groups.
|
||||
|
||||
# `<hive>/matrix/*` → 301 → `matrix.<hive>/$1` (legacy deep-link
|
||||
# shim during the fluffychat sub-domain move). See `docs/gateway.md`.
|
||||
matrixRedirectLocations =
|
||||
lib.optionalAttrs (matrixCfg.enable && matrixCfg.gui.enable && matrixCfg.gatewayHost != null)
|
||||
(
|
||||
let
|
||||
target = "${publicScheme}://${matrixCfg.gatewayHost}${publicPortSuffix}";
|
||||
in
|
||||
{
|
||||
"/matrix/" = {
|
||||
extraConfig = ''
|
||||
rewrite ^/matrix/(.*)$ ${target}/$1 permanent;
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
# `.well-known/matrix/{client,server}` discovery JSON. Points
|
||||
# clients at `matrixCfg.gatewayHost` when set; falls back to direct
|
||||
# `<hive>:<httpPort>`. CORS `*` per matrix spec. The `m.server`
|
||||
# port-8448 carve-out is documented inline. See `docs/gateway.md`.
|
||||
wellKnownLocations = lib.optionalAttrs (matrixCfg.enable && hyperhiveDomain != null) (
|
||||
let
|
||||
clientBaseUrl =
|
||||
if matrixCfg.gatewayHost != null then
|
||||
"${publicScheme}://${matrixCfg.gatewayHost}${publicPortSuffix}"
|
||||
else
|
||||
"${publicScheme}://${hyperhiveDomain}:${toString matrixCfg.httpPort}";
|
||||
# `m.server` is NOT a URL: per the matrix server-server spec
|
||||
# (Resolving Server Names) a delegated host with NO port resolves
|
||||
# to the federation default 8448 (after the SRV check) — the
|
||||
# https-implies-443 rule does NOT apply here. So the port must be
|
||||
# explicit even when it's the HTTPS default; `publicPortSuffix`
|
||||
# (which drops :443) is right for the client base_url above but
|
||||
# wrong for federation delegation. Without this, peers federate to
|
||||
# <gatewayHost>:8448 (closed) while the endpoint actually lives on
|
||||
# the gateway's 443 vhost. See docs/gateway.md discovery flow.
|
||||
serverHostPort =
|
||||
if matrixCfg.gatewayHost != null then
|
||||
"${matrixCfg.gatewayHost}:${toString publicPort}"
|
||||
else
|
||||
"${hyperhiveDomain}:${toString matrixCfg.httpPort}";
|
||||
in
|
||||
{
|
||||
"= /.well-known/matrix/client" = {
|
||||
extraConfig = ''
|
||||
default_type application/json;
|
||||
${securityHeaders}
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
return 200 '{"m.homeserver":{"base_url":"${clientBaseUrl}"}}';
|
||||
'';
|
||||
};
|
||||
"= /.well-known/matrix/server" = {
|
||||
extraConfig = ''
|
||||
default_type application/json;
|
||||
return 200 '{"m.server":"${serverHostPort}"}';
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
in
|
||||
{
|
||||
system.stateVersion = "26.05";
|
||||
|
|
@ -657,14 +799,13 @@ in
|
|||
};
|
||||
|
||||
# nginx reload is triggered from the HOST side by hive-c0re
|
||||
# via `systemctl -M hive-gateway reload nginx` — lets systemd
|
||||
# resolve the nginx binary path, avoiding exit-203 EXEC failures.
|
||||
# after each agents.conf write. A path unit watching the
|
||||
# bind-mounted file inside the container was tried first
|
||||
# (A path unit inside the container was tried but IN_MOVED_TO from an atomic rename on the host
|
||||
# does not propagate across the nspawn mount-namespace boundary,
|
||||
# does not cross the mount-namespace boundary. Host-side trigger is the
|
||||
# correct approach.
|
||||
# via `systemctl -M hive-gateway reload nginx` after each
|
||||
# agents.conf write — letting systemd resolve the nginx binary
|
||||
# path avoids exit-203 EXEC failures. A path unit watching the
|
||||
# bind-mounted file inside the container was tried first but
|
||||
# doesn't work: an IN_MOVED_TO from an atomic rename on the host
|
||||
# does not propagate across the nspawn mount-namespace boundary.
|
||||
# The host-side trigger is the correct approach.
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
|
@ -687,72 +828,8 @@ in
|
|||
"_" = vhostTls // {
|
||||
listen = vhostListen;
|
||||
locations =
|
||||
# `<hive>/matrix/*` → 301 → `matrix.<hive>/$1`
|
||||
# (fluffychat moved to sub-domain root; this
|
||||
# keeps bookmarks + deep-links working during the
|
||||
# transition). See `docs/gateway.md` for the vhost
|
||||
# map.
|
||||
lib.optionalAttrs (matrixCfg.enable && matrixCfg.gui.enable && matrixCfg.gatewayHost != null) (
|
||||
let
|
||||
target = "${publicScheme}://${matrixCfg.gatewayHost}${publicPortSuffix}";
|
||||
in
|
||||
{
|
||||
"/matrix/" = {
|
||||
extraConfig = ''
|
||||
rewrite ^/matrix/(.*)$ ${target}/$1 permanent;
|
||||
'';
|
||||
};
|
||||
}
|
||||
)
|
||||
//
|
||||
# `.well-known/matrix/{client,server}` discovery JSON.
|
||||
# Points clients at `matrixCfg.gatewayHost` (sub-domain
|
||||
# vhost) when set; falls back to direct `<hive>:<httpPort>`
|
||||
# when no gateway target. CORS `*` per matrix spec.
|
||||
# See `docs/gateway.md` "Discovery flow" for the full
|
||||
# client-bootstrap sequence.
|
||||
lib.optionalAttrs (matrixCfg.enable && hyperhiveDomain != null) (
|
||||
let
|
||||
clientBaseUrl =
|
||||
if matrixCfg.gatewayHost != null then
|
||||
"${publicScheme}://${matrixCfg.gatewayHost}${publicPortSuffix}"
|
||||
else
|
||||
"${publicScheme}://${hyperhiveDomain}:${toString matrixCfg.httpPort}";
|
||||
# `m.server` is NOT a URL: per the matrix
|
||||
# server-server spec (Resolving Server Names) a
|
||||
# delegated host with NO port resolves to the
|
||||
# federation default 8448 (after the SRV check) —
|
||||
# the https-implies-443 rule does NOT apply here.
|
||||
# So the port must be explicit even when it's the
|
||||
# HTTPS default; `publicPortSuffix` (which drops
|
||||
# :443) is right for the client base_url above but
|
||||
# wrong for federation delegation. Without this,
|
||||
# peers federate to <gatewayHost>:8448 (closed) while
|
||||
# the endpoint actually lives on the gateway's 443
|
||||
# vhost. See docs/gateway.md discovery flow.
|
||||
serverHostPort =
|
||||
if matrixCfg.gatewayHost != null then
|
||||
"${matrixCfg.gatewayHost}:${toString publicPort}"
|
||||
else
|
||||
"${hyperhiveDomain}:${toString matrixCfg.httpPort}";
|
||||
in
|
||||
{
|
||||
"= /.well-known/matrix/client" = {
|
||||
extraConfig = ''
|
||||
default_type application/json;
|
||||
${securityHeaders}
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
return 200 '{"m.homeserver":{"base_url":"${clientBaseUrl}"}}';
|
||||
'';
|
||||
};
|
||||
"= /.well-known/matrix/server" = {
|
||||
extraConfig = ''
|
||||
default_type application/json;
|
||||
return 200 '{"m.server":"${serverHostPort}"}';
|
||||
'';
|
||||
};
|
||||
}
|
||||
)
|
||||
matrixRedirectLocations
|
||||
// wellKnownLocations
|
||||
//
|
||||
# `/agent/` catch-all: hits when an operator
|
||||
# requests `/agent/<unknown>/...`. Without this the
|
||||
|
|
@ -879,83 +956,8 @@ in
|
|||
'';
|
||||
};
|
||||
}
|
||||
//
|
||||
# Forge sub-domain vhost. `server_name =
|
||||
# forge.domain`, proxies all `/` → forgejo. Tuned for
|
||||
# git: `client_max_body_size 1G`, `proxy_read_timeout 1h`
|
||||
# (multi-GB clones). SSH stays direct on `forge.sshPort`.
|
||||
# See `docs/gateway.md`.
|
||||
lib.optionalAttrs (forgeCfg.enable or false && forgeCfg.behindGateway or false) {
|
||||
"${forgeCfg.domain}" = vhostTls // {
|
||||
listen = vhostListen;
|
||||
extraConfig = securityHeaders;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString forgeCfg.httpPort}/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
client_max_body_size 1G;
|
||||
proxy_read_timeout 1h;
|
||||
proxy_send_timeout 1h;
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
//
|
||||
# Matrix sub-domain vhost. `server_name =
|
||||
# matrixCfg.gatewayHost`. `/_matrix/*` → tuwunel (CORS *,
|
||||
# 50M body cap, 1h long-poll timeout). `/` serves
|
||||
# fluffychat or 404 if GUI off. nginx
|
||||
# longer-prefix-wins puts `/_matrix/` ahead of `/`.
|
||||
# See `docs/gateway.md`.
|
||||
lib.optionalAttrs (matrixCfg.enable && matrixCfg.gatewayHost != null) {
|
||||
"${matrixCfg.gatewayHost}" = vhostTls // {
|
||||
listen = vhostListen;
|
||||
extraConfig = securityHeaders;
|
||||
locations = {
|
||||
"/_matrix/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString matrixCfg.httpPort}";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
client_max_body_size 50M;
|
||||
proxy_read_timeout 1h;
|
||||
proxy_send_timeout 1h;
|
||||
${securityHeaders}
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
'';
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (matrixCfg.gui.enable) (
|
||||
{
|
||||
# fluffychat at sub-domain root, SPA-fallback via
|
||||
# the Accept-header `$matrix_spa_target` map.
|
||||
"/" = {
|
||||
alias = "${matrixCfg.gui.package}/";
|
||||
extraConfig = ''
|
||||
try_files $uri $uri/ $matrix_spa_target =404;
|
||||
'';
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (hyperhiveDomain != null) {
|
||||
# FluffyChat boot-config pre-fill so the client's
|
||||
# `.well-known/matrix/client` lookup hits the
|
||||
# right delegation endpoint.
|
||||
"= /config.json" = {
|
||||
extraConfig = ''
|
||||
default_type application/json;
|
||||
return 200 '{"defaultHomeserver":"${hyperhiveDomain}"}';
|
||||
'';
|
||||
};
|
||||
}
|
||||
)
|
||||
// lib.optionalAttrs (!matrixCfg.gui.enable) {
|
||||
"/" = {
|
||||
return = "404";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
// forgeVhost
|
||||
// matrixVhost;
|
||||
};
|
||||
|
||||
# Hive-internal DNS resolver, co-located in the
|
||||
|
|
|
|||
Loading…
Reference in a new issue