feat: try rework

This commit is contained in:
Katharina Heidenreich 2026-04-04 11:42:19 +02:00
parent 1ddbd3b8b6
commit ecf10628c3
51 changed files with 1941 additions and 445 deletions

View file

@ -1,92 +1,36 @@
{ config, pkgs, lib, ... }:
let
network = import ../data/network.nix;
web = import ../data/web.nix;
virtualHostFn = name: service: let
domain = if service ? domainOverride
then service.domainOverride
else "${name}.${network.local_domain}";
locationList = if service.reverse_proxy ? endpoints
then service.reverse_proxy.endpoints
else ["/"];
locationsData = builtins.listToAttrs (map (endpointName: {
name = endpointName;
value = {
proxyPass = "http://127.0.0.1:${builtins.toString service.reverse_proxy.port}";
proxyWebsockets = true;
};
}) locationList);
serverAlias = lib.optionalAttrs (service.reverse_proxy ? aliases) {
serverAliases = map (alias: "${alias}.${domain}") service.reverse_proxy.aliases;
};
myExtraConfig = if service.reverse_proxy ? extraConfig
then service.reverse_proxy.extraConfig
else {};
listenConfig = if service.reverse_proxy ? listen
then service.reverse_proxy.listen
else if service.reverse_proxy ? ssl && service.reverse_proxy.ssl
then [ {port = 80;} {port = 443; ssl=true;} ]
else [ {port = 80;} ];
sslConfig = if service.reverse_proxy ? ssl && service.reverse_proxy.ssl
then {
enableACME = true;
forceSSL = true;
}
else {};
externConnections = if service.reverse_proxy ? allowExternConnections && service.reverse_proxy.allowExternConnections
then {
extraConfig = ''
allow all;
'';
}
else {};
in
{
serverName = "${domain}";
listen = map (obj: ({
addr = if obj ? addr then obj.addr else "0.0.0.0";
port = obj.port;
} // (if obj ? ssl then {ssl = obj.ssl;} else {}))) listenConfig;
locations = locationsData;
extraConfig = ''
allow ${network.network.subnet};
deny all;
'';
} // serverAlias // sslConfig // externConnections // myExtraConfig;
rproxyServices = builtins.mapAttrs (virtualHostFn) network.reverse_proxy;
serviceNamesMessage = builtins.toString (builtins.attrNames network.reverse_proxy);
webHosts = lib.mapAttrs' (name: description: {
name = "${name}.web";
value = {
serverName = "${name}";
listen = [ {addr = "0.0.0.0"; port = 80;} {addr = "0.0.0.0"; port = 443; ssl = true;}];
locations = lib.mapAttrs' (endpointName: endpointValue: {
name = endpointName;
value = {
extraConfig = ''
default_type ${endpointValue.contentType};
return ${toString endpointValue.status} "${endpointValue.content}";
'';
};
}) description;
};
}) web;
fallback = {
serverName = "_";
listen = [ {addr = "0.0.0.0"; port = 80;}];
locations."/" = {
return = "404";
extraConfig = ''
add_header Content-Type text/plain;
'';
};
nginxModel = import ../intermediate/nginx.nix;
extraConfig = ''
return 404 "This domain is not configured. Available services: ${serviceNamesMessage}";
'';
};
virtualHosts' = builtins.attrValues (rproxyServices // webHosts // {fallback = fallback;});
virtualHostsData = nginxModel.virtualHostsData;
validatedEndpoints = nginxModel.validatedEndpoints;
tlsEndpoints = lib.filter (endpoint: endpoint.force_ssl) validatedEndpoints;
localTlsEndpoints = lib.filter (endpoint: endpoint.force_ssl && endpoint.exposure == "local") validatedEndpoints;
localTlsDomains = lib.unique (map (endpoint: endpoint.domain) localTlsEndpoints);
acmeEmailConfigured =
config.security.acme ? defaults
&& builtins.isAttrs config.security.acme.defaults
&& config.security.acme.defaults ? email
&& builtins.isString config.security.acme.defaults.email
&& config.security.acme.defaults.email != "";
virtualHosts' = virtualHostsData;
in {
assertions = [
{
assertion = validatedEndpoints != [];
message = "No endpoints configured. config/endpoints.nix must contain at least one endpoint.";
}
{
assertion = localTlsEndpoints == [];
message = "ACME-managed TLS is only supported for external domains. Local domains with force_ssl=true are not allowed: ${builtins.concatStringsSep ", " localTlsDomains}";
}
{
assertion = tlsEndpoints == [] || acmeEmailConfigured;
message = "TLS endpoints exist, but security.acme.defaults.email is missing or empty.";
}
];
services.nginx = {
enable = true;
@ -98,7 +42,7 @@ in {
virtualHosts = virtualHosts';
};
networking.firewall.allowedTCPPorts = network.usedPorts;
networking.firewall.allowedTCPPorts = nginxModel.nginxUsedPorts;
security.acme = {
acceptTerms = true;