gateway: service modules declare their vhost under gateway.vhosts
Ten service modules (forge, matrix chat, authelia, grafana, otel, nats, swarm-ui, victorialogs, victoriametrics, bao UI) wrote services.nginx.virtualHosts themselves, each applying the gateway's listen set, per-name TLS attrs and security headers by hand. They now declare services.hyperhive.gateway.vhosts.<name> with only their own locations and options; ./declared-vhosts.nix renders it into the nginx vhost with listen, TLS and headers added. An eval assertion refuses a declared vhost that sets listen, addSSL, onlySSL, enableACME, useACMEHost, sslCertificate or sslCertificateKey, and one declared while the gateway is off. nats' own leaf is the new `certificate` field. The rendered nginx vhosts are unchanged.
This commit is contained in:
parent
7b50ae57e4
commit
ddb583cc22
17 changed files with 652 additions and 513 deletions
|
|
@ -465,65 +465,56 @@ in
|
|||
# nothing else on this name: the monitoring endpoint (`/varz`, `/connz`)
|
||||
# is never proxied, and every other path is 403.
|
||||
#
|
||||
# ⚠️ Not `gateway.lib.tlsFor`, and the name is not in
|
||||
# `swarm.serviceDomains`. In self-signed mode this vhost serves the
|
||||
# queue's own leaf (issued for exactly this name, `server_flag` set), so
|
||||
# a host whose only swarm service is the queue never fronts a services
|
||||
# name and its gateway does not wait for the swarm-services leaf.
|
||||
# ⚠️ In self-signed mode this vhost serves the queue's own leaf
|
||||
# (`certificate`; issued for exactly this name, `server_flag` set), not
|
||||
# the gateway's pick for the name, and the name is not in
|
||||
# `swarm.serviceDomains`.
|
||||
#
|
||||
# `forceSSL` for the reason ./swarm-victorialogs.nix gives: authelia
|
||||
# answers a plain-http auth subrequest with 400.
|
||||
services.nginx.virtualHosts."${cfg.domain}" =
|
||||
(
|
||||
if gatewayServesQueueLeaf then
|
||||
{
|
||||
sslCertificate = "${gatewayTlsDir}/cert.pem";
|
||||
sslCertificateKey = "${gatewayTlsDir}/key.pem";
|
||||
}
|
||||
else
|
||||
builtins.removeAttrs (gatewayCfg.lib.tlsFor cfg.domain) [ "addSSL" ]
|
||||
)
|
||||
// {
|
||||
forceSSL = true;
|
||||
listen = gatewayCfg.lib.listen;
|
||||
extraConfig = gatewayCfg.lib.securityHeaders;
|
||||
locations = {
|
||||
"/".return = "403";
|
||||
services.hyperhive.gateway.vhosts."${cfg.domain}" = {
|
||||
certificate = lib.mkIf gatewayServesQueueLeaf {
|
||||
cert = "${gatewayTlsDir}/cert.pem";
|
||||
key = "${gatewayTlsDir}/key.pem";
|
||||
};
|
||||
forceSSL = true;
|
||||
locations = {
|
||||
"/".return = "403";
|
||||
|
||||
# The collector requests exactly this URL, declared as
|
||||
# `publishedScrapeTargets.nats` in ./swarm-otel-service.nix; the
|
||||
# two must agree, since that string is also the token's audience.
|
||||
# Authelia's rules for it admit the collector's client and deny
|
||||
# every other subject (`metricsRules` in ./swarm-authelia.nix).
|
||||
"= /metrics" = {
|
||||
proxyPass = "http://127.0.0.1:${toString cfg.metricsPort}/metrics";
|
||||
extraConfig = ''
|
||||
auth_request /__nats_metrics_authz;
|
||||
'';
|
||||
};
|
||||
# The collector requests exactly this URL, declared as
|
||||
# `publishedScrapeTargets.nats` in ./swarm-otel-service.nix; the
|
||||
# two must agree, since that string is also the token's audience.
|
||||
# Authelia's rules for it admit the collector's client and deny
|
||||
# every other subject (`metricsRules` in ./swarm-authelia.nix).
|
||||
"= /metrics" = {
|
||||
proxyPass = "http://127.0.0.1:${toString cfg.metricsPort}/metrics";
|
||||
extraConfig = ''
|
||||
auth_request /__nats_metrics_authz;
|
||||
'';
|
||||
};
|
||||
|
||||
# The subrequest, same shape as the forge's `= /__forge_metrics_authz`
|
||||
# (./hive-forge/default.nix): no `error_page 401 =302`, so a scraper
|
||||
# gets the 401 rather than a login page parsed as metrics.
|
||||
"= /__nats_metrics_authz" = {
|
||||
proxyPass = "https://${autheliaCfg.domain}/api/authz/auth-request";
|
||||
# nixpkgs appends its OWN `Host $host` after extraConfig, which
|
||||
# would override verifiedProxyTo's — see hive-gateway/vhost-lib.nix.
|
||||
recommendedProxySettings = false;
|
||||
extraConfig = ''
|
||||
internal;
|
||||
${gatewayCfg.lib.verifiedProxyTo autheliaCfg.domain}
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header X-Original-Method $request_method;
|
||||
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
'';
|
||||
};
|
||||
# The subrequest, same shape as the forge's `= /__forge_metrics_authz`
|
||||
# (./hive-forge/default.nix): no `error_page 401 =302`, so a scraper
|
||||
# gets the 401 rather than a login page parsed as metrics.
|
||||
"= /__nats_metrics_authz" = {
|
||||
proxyPass = "https://${autheliaCfg.domain}/api/authz/auth-request";
|
||||
# nixpkgs appends its OWN `Host $host` after extraConfig, which
|
||||
# would override verifiedProxyTo's — see hive-gateway/vhost-lib.nix.
|
||||
recommendedProxySettings = false;
|
||||
extraConfig = ''
|
||||
internal;
|
||||
${gatewayCfg.lib.verifiedProxyTo autheliaCfg.domain}
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header X-Original-Method $request_method;
|
||||
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Puts a pair at the paths the vhost above names, before nginx starts:
|
||||
# nginx refuses a config naming a missing cert file, and that takes the
|
||||
|
|
|
|||
Loading…
Reference in a new issue