feat(nginx): enable option for vhost/location

This commit is contained in:
arcnmx 2024-03-21 11:25:31 -07:00
parent a6fced79d5
commit 8f227a1bc5
7 changed files with 116 additions and 31 deletions

View file

@ -0,0 +1,47 @@
{
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkOverride;
mkExtraForce = mkOverride 25;
locationModule = { config, virtualHost, ... }: {
options = with lib.types; {
enable = mkEnableOption "enable location" // {
default = true;
};
};
config = mkIf (!virtualHost.enable || !config.enable) {
extraConfig = mkExtraForce "deny all;";
};
};
hostModule = { config, ... }: {
options = with lib.types; {
enable = mkEnableOption "enable server" // {
default = true;
};
locations = mkOption {
type = attrsOf (submoduleWith {
modules = [ locationModule ];
shorthandOnlyDefinesConfig = true;
});
};
};
config = mkIf (!config.enable) {
default = mkExtraForce false;
extraConfig = mkExtraForce ''
deny all;
'';
};
};
in {
options = with lib.types; {
services.nginx.virtualHosts = mkOption {
type = attrsOf (submoduleWith {
modules = [ hostModule ];
shorthandOnlyDefinesConfig = true;
});
};
};
}

View file

@ -4,17 +4,26 @@
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkDefault mkOptionDefault mkForce mkOverride;
inherit (lib.attrsets) mapAttrsToList filterAttrs removeAttrs;
inherit (lib.lists) concatMap;
inherit (lib.modules) mkIf mkMerge mkOptionDefault mkForce mkOverride mkRenamedOptionModule;
inherit (lib.attrsets) attrValues mapAttrs mapAttrsToList;
inherit (lib.lists) filter concatMap;
mkAlmostOptionDefault = mkOverride 1250;
inherit (config.services) nginx;
extraListenAttrs = [ "enable" ];
listenModule = { config, virtualHost, ... }: {
options = with lib.types; {
enable = mkEnableOption "this port" // {
default = true;
};
addr = mkOption {
type = nullOr str;
default = null;
description = "shorthand to override config.addresses";
};
addresses = mkOption {
type = listOf str;
description = "applies to all listen addresses unless set";
defaultText = "virtualHost.listenAddresses'";
};
ssl = mkOption {
type = bool;
default = false;
@ -22,23 +31,42 @@
port = mkOption {
type = nullOr port;
};
extraParameters = mkOption {
type = listOf str;
default = [ ];
};
proxyProtocol = mkOption {
type = bool;
default = false;
};
};
config = {
enable = mkIf (config.ssl && !virtualHost.ssl.enable) (mkForce false);
_module.freeformType = with lib.types; attrsOf (oneOf [
str (listOf str) (nullOr port) bool
]);
port = mkOptionDefault (
if config.ssl then nginx.defaultSSLListenPort else nginx.defaultHTTPListenPort
);
addresses = mkMerge [
(mkOptionDefault virtualHost.listenAddresses')
(mkIf (config.addr != null) (mkAlmostOptionDefault [ config.addr ]))
];
};
};
hostModule = { config, ... }: let
cfg = config.listenPorts;
enabledPorts = filterAttrs (_: port: port.enable) cfg;
cfg = attrValues config.listen';
enabledCfg = filter (port: port.enable) cfg;
mkListen = listen: addr: let
listenAttrs = {
inherit addr;
inherit (listen) port ssl extraParameters proxyProtocol;
};
in mapAttrs (_: mkAlmostOptionDefault) listenAttrs;
mkListens = listen: map (mkListen listen) listen.addresses;
in {
imports = [
(mkRenamedOptionModule [ "listenPorts" ] [ "listen'" ])
];
options = with lib.types; {
listenPorts = mkOption {
listen' = mkOption {
type = attrsOf (submoduleWith {
modules = [ listenModule ];
specialArgs = {
@ -47,15 +75,19 @@
});
default = { };
};
listenAddresses' = mkOption {
type = listOf str;
description = "listenAddresses or defaultListenAddresses if empty";
};
};
config = {
listen = let
addresses = if config.listenAddresses != [ ] then config.listenAddresses else nginx.defaultListenAddresses;
in mkIf (cfg != { }) (mkAlmostOptionDefault (
concatMap (addr: mapAttrsToList (_: listen: {
addr = mkDefault addr;
} // removeAttrs listen extraListenAttrs) enabledPorts) addresses
enable = mkIf (cfg != [ ] && enabledCfg == [ ]) (mkForce false);
listenAddresses' = mkOptionDefault (
if config.listenAddresses != [ ] then config.listenAddresses else nginx.defaultListenAddresses
);
listen = mkIf (cfg != { }) (mkAlmostOptionDefault (
concatMap (mkListens) enabledCfg
));
};
};

View file

@ -9,12 +9,16 @@
listenPorts = {
http = { };
https.ssl = true;
hass = mkIf (!home-assistant.enable) { port = mkDefault home-assistant.config.http.server_port; };
hass = {
enable = !home-assistant.enable;
port = mkDefault home-assistant.config.http.server_port;
extraParameters = [ "default_server" ];
};
};
in {
config.services.nginx.virtualHosts = {
home-assistant = {
inherit name listenPorts;
inherit name;
locations."/" = {
proxy = {
websocket.enable = true;
@ -33,7 +37,7 @@ in {
websocket.enable = true;
headers.enableRecommended = true;
};
proxyPass = mkIf (!home-assistant.enable) (mkDefault
proxyPass = (mkDefault
nginx.virtualHosts.home-assistant.locations."/".proxyPass
);
};

View file

@ -52,17 +52,20 @@ in {
in {
plex = {
inherit name locations extraConfig kTLS;
listenPorts = {
http = { };
https.ssl = true;
external = {
enable = mkDefault (access.externalPort != null);
port = mkDefault access.externalPort;
extraParameters = [ "default_server" ];
};
};
};
plex'local = {
inherit name locations extraConfig kTLS;
local.enable = true;
};
plex-external = mkIf (access.externalPort != null) {
serverName = mkDefault "plex.${config.networking.domain}";
default = mkDefault true;
listenPorts.external.port = access.externalPort;
inherit extraConfig locations;
};
};
};
config.networking.firewall.allowedTCPPorts = mkIf (access.externalPort != null) [

View file

@ -43,9 +43,9 @@ in {
listenPorts.management = {
port = access.managementPort;
ssl = true;
extraParameters = [ "default_server" ];
};
ssl.force = true;
default = mkDefault true;
inherit name locations extraConfig kTLS;
};
unifi = {

View file

@ -71,7 +71,8 @@ in {
(localLocations "sso.local.${networking.domain}")
];
};
vouch'tail = mkIf tailscale.enable {
vouch'tail = {
enable = mkDefault tailscale.enable;
name = {
inherit (name) shortServer;
qualifier = mkDefault "tail";

View file

@ -106,7 +106,7 @@ in {
extraDomainNames = mkMerge [
virtualHosts.vouch.serverAliases
virtualHosts.vouch'local.allServerNames
(mkIf tailscale.enable virtualHosts.vouch'tail.allServerNames)
(mkIf virtualHosts.vouch'tail.enable virtualHosts.vouch'tail.allServerNames)
];
};
unifi = {
@ -219,9 +219,7 @@ in {
keycloak'local.ssl.cert.name = "keycloak";
vouch.ssl.cert.name = "vouch";
vouch'local.ssl.cert.name = "vouch";
vouch'tail = mkIf tailscale.enable {
ssl.cert.name = "vouch";
};
vouch'tail.ssl.cert.name = "vouch";
unifi = {
# we're not the real unifi record-holder, so don't respond globally..
local.denyGlobal = true;