mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 04:19:19 -08:00
feat(exports): service access
This commit is contained in:
parent
91918b8061
commit
871b1c5b2d
69 changed files with 1317 additions and 509 deletions
5
lib.nix
5
lib.nix
|
|
@ -8,7 +8,7 @@
|
|||
inherit (nixlib.strings) splitString toLower;
|
||||
inherit (nixlib.lists) imap0 elemAt;
|
||||
inherit (nixlib.attrsets) mapAttrs listToAttrs nameValuePair;
|
||||
inherit (nixlib.strings) substring fixedWidthString replaceStrings concatMapStringsSep;
|
||||
inherit (nixlib.strings) hasPrefix hasInfix substring fixedWidthString replaceStrings concatMapStringsSep;
|
||||
inherit (nixlib.trivial) flip toHexString bitOr;
|
||||
|
||||
toHexStringLower = v: toLower (toHexString v);
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
mkWinPath = replaceStrings ["/"] ["\\"];
|
||||
mkBaseDn = domain: concatMapStringsSep "," (part: "dc=${part}") (splitString "." domain);
|
||||
mkAddress6 = addr: if hasInfix ":" addr && ! hasPrefix "[" addr then "[${addr}]" else addr;
|
||||
|
||||
mapListToAttrs = f: l: listToAttrs (map f l);
|
||||
|
||||
|
|
@ -77,7 +78,7 @@ in {
|
|||
lib = {
|
||||
domain = "gensokyo.zone";
|
||||
inherit treeToModulesOutput userIs
|
||||
eui64 mkWinPath mkBaseDn
|
||||
eui64 mkWinPath mkBaseDn mkAddress6
|
||||
toHexStringLower hexCharToInt
|
||||
mapListToAttrs
|
||||
mkAlmostOptionDefault mkAlmostDefault mkAlmostForce mapOverride mapOptionDefaults mapAlmostOptionDefaults mapDefaults
|
||||
|
|
|
|||
20
modules/nixos/keycloak.nix
Normal file
20
modules/nixos/keycloak.nix
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{config, lib, ...}: let
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (lib.modules) mkOptionDefault;
|
||||
cfg = config.services.keycloak;
|
||||
in {
|
||||
options.services.keycloak = with lib.types; {
|
||||
protocol = mkOption {
|
||||
type = enum [ "http" "https" ];
|
||||
readOnly = true;
|
||||
};
|
||||
port = mkOption {
|
||||
type = port;
|
||||
readOnly = true;
|
||||
};
|
||||
};
|
||||
config.services.keycloak = {
|
||||
protocol = mkOptionDefault (if cfg.sslCertificate != null then "https" else "http");
|
||||
port = mkOptionDefault cfg.settings."${cfg.protocol}-port";
|
||||
};
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{config, lib, ...}: let
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
||||
inherit (lib.modules) mkIf mkOptionDefault;
|
||||
inherit (lib.lists) filter optional;
|
||||
inherit (lib.strings) hasInfix concatStrings;
|
||||
inherit (config.services) resolved;
|
||||
|
|
|
|||
|
|
@ -4,12 +4,11 @@
|
|||
inputs,
|
||||
...
|
||||
}: let
|
||||
inherit (inputs.self.lib.lib) mkAlmostOptionDefault;
|
||||
inherit (inputs.self.lib.lib) mkAlmostOptionDefault mkAddress6;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkBefore mkOptionDefault mkForce;
|
||||
inherit (lib.attrsets) attrValues mapAttrs;
|
||||
inherit (lib.lists) optional filter concatMap;
|
||||
inherit (lib.strings) hasPrefix hasInfix;
|
||||
inherit (config.services) nginx;
|
||||
listenModule = { config, virtualHost, listenKind, ... }: {
|
||||
options = with lib.types; {
|
||||
|
|
@ -76,9 +75,8 @@
|
|||
listenConfigs = let
|
||||
# TODO: handle quic listener..?
|
||||
mkListenHost = { addr, port }: let
|
||||
addr' = if hasInfix ":" addr && !hasPrefix "[" addr then "[${addr}]" else addr;
|
||||
host =
|
||||
if addr != null then "${addr'}:${toString port}"
|
||||
if addr != null then "${mkAddress6 addr}:${toString port}"
|
||||
else toString port;
|
||||
in assert port != null; host;
|
||||
mkDirective = addr: let
|
||||
|
|
|
|||
|
|
@ -73,14 +73,14 @@
|
|||
cert = let
|
||||
mkCopyCert = copyCert: {
|
||||
name = mkDefault copyCert.name;
|
||||
keyPath = mkAlmostOptionDefault copyCert.keyPath;
|
||||
path = mkAlmostOptionDefault copyCert.path;
|
||||
keyPath = mkDefault copyCert.keyPath;
|
||||
path = mkDefault copyCert.path;
|
||||
};
|
||||
copyCertVhost = mkCopyCert nginx.virtualHosts.${cfg.cert.copyFromVhost}.ssl.cert;
|
||||
copyCertStreamServer = mkCopyCert nginx.stream.servers.${cfg.cert.copyFromStreamServer}.ssl.cert;
|
||||
in mkMerge [
|
||||
(mkIf (cfg.cert.copyFromVhost != null) copyCertVhost)
|
||||
(mkIf (cfg.cert.copyFromStreamServer != null) copyCertStreamServer)
|
||||
(mkIf (cfg.cert.copyFromVhost != null) copyCertVhost)
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
gensokyo-zone,
|
||||
...
|
||||
}: let
|
||||
inherit (gensokyo-zone.lib) mkAddress6;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkBefore mkOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrsToList;
|
||||
inherit (lib.lists) optional;
|
||||
inherit (lib.strings) hasPrefix hasInfix;
|
||||
cfg = config.services.nginx.stream;
|
||||
upstreamServerModule = {config, name, ...}: {
|
||||
options = with lib.types; {
|
||||
|
|
@ -45,9 +46,7 @@
|
|||
config = let
|
||||
settings = mapAttrsToList (key: value: "${key}=${toString value}") config.settings;
|
||||
in {
|
||||
server = let
|
||||
addr = if hasInfix ":" config.addr && ! hasPrefix "[" config.addr then "[${config.addr}]" else config.addr;
|
||||
in mkOptionDefault "${addr}:${toString config.port}";
|
||||
server = mkOptionDefault "${mkAddress6 config.addr}:${toString config.port}";
|
||||
serverConfig = mkMerge (
|
||||
[ (mkBefore config.server) ]
|
||||
++ settings
|
||||
|
|
@ -76,6 +75,9 @@
|
|||
servers = mkOption {
|
||||
type = attrsOf upstreamServer;
|
||||
};
|
||||
ssl = {
|
||||
enable = mkEnableOption "ssl upstream";
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
type = lines;
|
||||
default = "";
|
||||
|
|
@ -119,11 +121,35 @@
|
|||
type = lines;
|
||||
internal = true;
|
||||
};
|
||||
proxy = {
|
||||
upstream = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
url = mkOption {
|
||||
type = nullOr str;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
streamConfig = mkMerge [
|
||||
proxy = {
|
||||
url = mkOptionDefault (
|
||||
if config.proxy.upstream != null then cfg.upstreams.${config.proxy.upstream}.name
|
||||
else null
|
||||
);
|
||||
};
|
||||
streamConfig = let
|
||||
proxyUpstream = cfg.upstreams.${config.proxy.upstream};
|
||||
in mkMerge [
|
||||
config.extraConfig
|
||||
(mkIf (config.proxy.upstream != null && proxyUpstream.ssl.enable) ''
|
||||
proxy_ssl on;
|
||||
proxy_ssl_verify off;
|
||||
'')
|
||||
(mkIf (config.proxy.url != null) ''
|
||||
proxy_pass ${config.proxy.url};
|
||||
'')
|
||||
];
|
||||
serverBlock = mkOptionDefault ''
|
||||
server {
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@
|
|||
}: let
|
||||
inherit (inputs.self) nixosConfigurations;
|
||||
inherit (inputs.self.lib) systems;
|
||||
inherit (inputs.self.lib.lib) domain;
|
||||
inherit (inputs.self.lib.lib) domain mkAddress6;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
inherit (lib.attrsets) mapAttrs attrValues;
|
||||
inherit (lib.lists) findSingle;
|
||||
inherit (lib.trivial) mapNullable;
|
||||
cfg = config.access;
|
||||
systemConfig = config;
|
||||
systemAccess = access;
|
||||
|
|
@ -42,20 +44,29 @@
|
|||
config = {
|
||||
networking.access = {
|
||||
moduleArgAttrs = let
|
||||
mkGetAddressFor = addressForAttr: hostName: network: let
|
||||
mkGetAddressFor = nameAllowed: addressForAttr: hostName: network: let
|
||||
forSystem = access.systemFor hostName;
|
||||
err = throw "no lan interface found between ${config.networking.hostName} and ${hostName}";
|
||||
err = throw "no interface found between ${config.networking.hostName} -> ${hostName}@${network}";
|
||||
fallback = if nameAllowed
|
||||
then lib.warn "getAddressFor hostname fallback for ${config.networking.hostName} -> ${hostName}@${network}" (access.getHostnameFor hostName network)
|
||||
else err;
|
||||
local = forSystem.access.${addressForAttr}.local or forSystem.access.address4ForNetwork.local or fallback;
|
||||
int = forSystem.access.${addressForAttr}.int or forSystem.access.address4ForNetwork.int or fallback;
|
||||
tail = forSystem.access.${addressForAttr}.tail or fallback;
|
||||
in {
|
||||
lan =
|
||||
if has'Int then forSystem.access.${addressForAttr}.int or forSystem.access.${addressForAttr}.local or err
|
||||
else if has'Local then forSystem.access.${addressForAttr}.local or err
|
||||
else err;
|
||||
${if has'Local then "local" else null} = forSystem.access.${addressForAttr}.local or err;
|
||||
${if has'Int then "int" else null} = forSystem.access.${addressForAttr}.int or err;
|
||||
${if has'Tail then "tail" else null} = forSystem.access.${addressForAttr}.tail or err;
|
||||
}.${network} or err;
|
||||
if hostName == system.name then forSystem.access.${addressForAttr}.localhost
|
||||
else if has'Int then int
|
||||
else if has'Local then local
|
||||
else fallback;
|
||||
${if has'Local then "local" else null} = local;
|
||||
${if has'Int then "int" else null} = int;
|
||||
${if has'Tail then "tail" else null} = tail;
|
||||
}.${network} or fallback;
|
||||
in {
|
||||
inherit (systemAccess) hostnameForNetwork address4ForNetwork address6ForNetwork;
|
||||
inherit (systemAccess)
|
||||
hostnameForNetwork address4ForNetwork address6ForNetwork
|
||||
systemForService systemForServiceId;
|
||||
addressForNetwork = systemAccess.${addressForAttr};
|
||||
systemFor = hostName:
|
||||
if hostName == config.networking.hostName
|
||||
|
|
@ -73,21 +84,39 @@
|
|||
if hostName == config.networking.hostName
|
||||
then config
|
||||
else systemAccess.nixosForOrNull hostName;
|
||||
getAddressFor = mkGetAddressFor addressForAttr;
|
||||
getAddress4For = mkGetAddressFor "address4ForNetwork";
|
||||
getAddress6For = mkGetAddressFor "address6ForNetwork";
|
||||
getAddressFor = mkGetAddressFor true addressForAttr;
|
||||
getAddress4For = mkGetAddressFor false "address4ForNetwork";
|
||||
getAddress6For = mkGetAddressFor false "address6ForNetwork";
|
||||
getHostnameFor = hostName: network: let
|
||||
forSystem = access.systemFor hostName;
|
||||
err = throw "no ${network} interface found between ${config.networking.hostName} and ${hostName}";
|
||||
in {
|
||||
lan =
|
||||
if has'Int then forSystem.access.hostnameForNetwork.int or forSystem.access.hostnameForNetwork.local or err
|
||||
if hostName == system.name then forSystem.access.hostnameForNetwork.localhost
|
||||
else if has'Int then forSystem.access.hostnameForNetwork.int or forSystem.access.hostnameForNetwork.local or err
|
||||
else if has'Local then forSystem.access.hostnameForNetwork.local or err
|
||||
else err;
|
||||
${if has'Local then "local" else null} = forSystem.access.hostnameForNetwork.local or err;
|
||||
${if has'Int then "int" else null} = forSystem.access.hostnameForNetwork.int or err;
|
||||
${if has'Tail then "tail" else null} = forSystem.access.hostnameForNetwork.tail or err;
|
||||
}.${network} or err;
|
||||
proxyUrlFor = {
|
||||
system ? if serviceId != null then access.systemForServiceId serviceId else access.systemForService serviceName,
|
||||
serviceName ? mapNullable (serviceId: (findSingle (s: s.id == serviceId) null null (attrValues system.exports.services)).name) serviceId,
|
||||
serviceId ? null,
|
||||
service ? system.exports.services.${serviceName},
|
||||
portName ? "default",
|
||||
network ? "lan",
|
||||
scheme ? null,
|
||||
}: let
|
||||
port = service.ports.${portName};
|
||||
scheme' = if scheme == null then port.protocol else scheme;
|
||||
port' = if !port.enable
|
||||
then throw "${system.name}.exports.services.${service.name}.ports.${portName} isn't enabled"
|
||||
else ":${toString port.port}";
|
||||
host = access.getAddressFor system.name network;
|
||||
url = "${scheme'}://${mkAddress6 host}${port'}";
|
||||
in assert service.enable; url;
|
||||
};
|
||||
};
|
||||
networking.tempAddresses = mkIf cfg.global.enable (
|
||||
|
|
@ -110,7 +139,6 @@ in {
|
|||
type = str;
|
||||
default = domain;
|
||||
};
|
||||
tailscale.enable = mkEnableOption "tailscale access";
|
||||
global.enable = mkEnableOption "globally routeable";
|
||||
hostnameForNetwork = mkOption {
|
||||
type = attrsOf str;
|
||||
|
|
@ -143,6 +171,7 @@ in {
|
|||
hostnameForNetwork = mkMerge [
|
||||
(mapAttrs (_: mapNetworkFqdn) config.network.networks)
|
||||
{
|
||||
localhost = mkOptionDefault "localhost";
|
||||
lan = mkMerge [
|
||||
(mapNetwork' mkDefault "fqdn" int)
|
||||
(mapNetworkFqdn local)
|
||||
|
|
@ -153,6 +182,7 @@ in {
|
|||
address4ForNetwork = mkMerge [
|
||||
(mapAttrs (_: mapNetwork4) config.network.networks)
|
||||
{
|
||||
localhost = mkOptionDefault "127.0.0.1";
|
||||
lan = mkMerge [
|
||||
(mapNetwork' mkDefault "address4" int)
|
||||
(mapNetwork4 local)
|
||||
|
|
@ -162,6 +192,7 @@ in {
|
|||
address6ForNetwork = mkMerge [
|
||||
(mapAttrs (_: mapNetwork6) config.network.networks)
|
||||
{
|
||||
localhost = mkOptionDefault "::1";
|
||||
lan = mkMerge [
|
||||
(mapNetwork' mkDefault "address6" int)
|
||||
(mapNetwork6 local)
|
||||
|
|
@ -176,6 +207,16 @@ in {
|
|||
systemForOrNull = hostName: systems.${hostName}.config or null;
|
||||
nixosFor = hostName: nixosConfigurations.${hostName}.config or (access.systemFor hostName).built.config;
|
||||
nixosForOrNull = hostName: nixosConfigurations.${hostName}.config or (access.systemForOrNull hostName).built.config or null;
|
||||
systemForService = service: let
|
||||
hasService = system: system.config.exports.services.${service}.enable;
|
||||
notFound = throw "no system found serving ${service}";
|
||||
multiple = throw "multiple systems found serving ${service}";
|
||||
in (findSingle hasService notFound multiple (attrValues systems)).config;
|
||||
systemForServiceId = serviceId: let
|
||||
hasService = system: findSingle (service: service.id == serviceId && service.enable) null multiple (attrValues system.config.exports.services) != null;
|
||||
notFound = throw "no system found serving ${serviceId}";
|
||||
multiple = throw "multiple systems found serving ${serviceId}";
|
||||
in (findSingle hasService notFound multiple (attrValues systems)).config;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
22
modules/system/exports/dnsmasq.nix
Normal file
22
modules/system/exports/dnsmasq.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.dnsmasq = { config, ... }: {
|
||||
id = mkAlmostOptionDefault "dns";
|
||||
nixos = {
|
||||
serviceAttr = "dnsmasq";
|
||||
};
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
default = {
|
||||
port = 53;
|
||||
transport = "udp";
|
||||
};
|
||||
tcp = {
|
||||
port = config.ports.default.port;
|
||||
transport = "tcp";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
48
modules/system/exports/exports.nix
Normal file
48
modules/system/exports/exports.nix
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
config,
|
||||
name,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
cfg = config.exports;
|
||||
systemConfig = config;
|
||||
exportModule = {
|
||||
config,
|
||||
name,
|
||||
...
|
||||
}: {
|
||||
options = with lib.types; {
|
||||
enable = mkEnableOption "exported service";
|
||||
name = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
};
|
||||
serviceName = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
};
|
||||
id = mkOption {
|
||||
type = str;
|
||||
default = cfg.services.${config.serviceName}.id/* or config.name*/;
|
||||
};
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.exports = with lib.types; {
|
||||
exports = mkOption {
|
||||
type = attrsOf (submoduleWith {
|
||||
modules = [exportModule];
|
||||
specialArgs = {
|
||||
machine = name;
|
||||
inherit systemConfig;
|
||||
};
|
||||
});
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
_module.args.exports = cfg;
|
||||
};
|
||||
}
|
||||
18
modules/system/exports/freeipa.nix
Normal file
18
modules/system/exports/freeipa.nix
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.freeipa = {
|
||||
id = mkAlmostOptionDefault "freeipa";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
default = {
|
||||
port = 443;
|
||||
protocol = "https";
|
||||
};
|
||||
redirect = {
|
||||
port = 80;
|
||||
protocol = "http";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
34
modules/system/exports/freepbx.nix
Normal file
34
modules/system/exports/freepbx.nix
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.freepbx = {
|
||||
id = mkAlmostOptionDefault "pbx";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
http = {
|
||||
port = 80;
|
||||
protocol = "http";
|
||||
};
|
||||
https = {
|
||||
port = 443;
|
||||
protocol = "https";
|
||||
};
|
||||
ucp = {
|
||||
port = 8001;
|
||||
protocol = "http";
|
||||
};
|
||||
ucp-ssl = {
|
||||
port = 8003;
|
||||
protocol = "https";
|
||||
};
|
||||
asterisk = {
|
||||
port = 8088;
|
||||
protocol = "http";
|
||||
};
|
||||
asterisk-ssl = {
|
||||
port = 8089;
|
||||
protocol = "https";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
45
modules/system/exports/home-assistant.nix
Normal file
45
modules/system/exports/home-assistant.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
inherit (lib.lists) all imap0;
|
||||
inherit (lib.trivial) id;
|
||||
in {
|
||||
config.exports.services.home-assistant = { config, ... }: let
|
||||
mkAssertion = f: nixosConfig: let
|
||||
cfg = nixosConfig.services.home-assistant;
|
||||
in f nixosConfig cfg;
|
||||
assertPort = nixosConfig: cfg: {
|
||||
assertion = config.ports.default.port == cfg.config.http.server_port;
|
||||
message = "port mismatch";
|
||||
};
|
||||
assertHomekitPort = let
|
||||
portName = i: "homekit${toString i}";
|
||||
mkAssertPort = i: homekit: config.ports.${portName i}.port or null == homekit.port;
|
||||
in nixosConfig: cfg: {
|
||||
assertion = all id (imap0 mkAssertPort cfg.config.homekit);
|
||||
message = "homekit port mismatch";
|
||||
};
|
||||
in {
|
||||
id = mkAlmostOptionDefault "home";
|
||||
nixos = {
|
||||
serviceAttr = "home-assistant";
|
||||
assertions = mkIf config.enable [
|
||||
(mkAssertion assertPort)
|
||||
(mkAssertion assertHomekitPort)
|
||||
];
|
||||
};
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
default = {
|
||||
port = 8123;
|
||||
protocol = "http";
|
||||
};
|
||||
homekit0 = {
|
||||
port = 21063;
|
||||
transport = "tcp";
|
||||
};
|
||||
# TODO: cast udp port range 32768 to 60999
|
||||
};
|
||||
};
|
||||
}
|
||||
21
modules/system/exports/invidious.nix
Normal file
21
modules/system/exports/invidious.nix
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkIf;
|
||||
in {
|
||||
config.exports.services.invidious = { config, ... }: {
|
||||
id = mkAlmostOptionDefault "yt";
|
||||
nixos = {
|
||||
serviceAttr = "invidious";
|
||||
assertions = mkIf config.enable [
|
||||
(nixosConfig: {
|
||||
assertion = config.ports.default.port == nixosConfig.services.invidious.port;
|
||||
message = "port mismatch";
|
||||
})
|
||||
];
|
||||
};
|
||||
ports.default = mapAlmostOptionDefaults {
|
||||
port = 3000;
|
||||
protocol = "http";
|
||||
};
|
||||
};
|
||||
}
|
||||
35
modules/system/exports/kerberos.nix
Normal file
35
modules/system/exports/kerberos.nix
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.kerberos = { config, ... }: {
|
||||
id = "krb5";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
default = {
|
||||
port = 88;
|
||||
transport = "tcp";
|
||||
};
|
||||
udp = {
|
||||
port = config.ports.default.port;
|
||||
transport = "udp";
|
||||
};
|
||||
kadmin = {
|
||||
port = 749;
|
||||
transport = "tcp";
|
||||
};
|
||||
kpasswd = {
|
||||
port = 464;
|
||||
transport = "tcp";
|
||||
};
|
||||
kpasswd-udp = {
|
||||
port = config.ports.kpasswd.port;
|
||||
transport = "udp";
|
||||
};
|
||||
ticket4 = {
|
||||
enable = false;
|
||||
port = 4444;
|
||||
transport = "udp";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
37
modules/system/exports/keycloak.nix
Normal file
37
modules/system/exports/keycloak.nix
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.keycloak = { config, ... }: {
|
||||
id = mkAlmostOptionDefault "sso";
|
||||
nixos = {
|
||||
serviceAttr = "keycloak";
|
||||
assertions = let
|
||||
mkAssertion = f: nixosConfig: let
|
||||
cfg = nixosConfig.services.keycloak;
|
||||
in f nixosConfig cfg;
|
||||
in mkIf config.enable [
|
||||
(mkAssertion (nixosConfig: cfg: {
|
||||
assertion = config.ports.${cfg.protocol}.port == cfg.port;
|
||||
message = "port mismatch";
|
||||
}))
|
||||
(mkAssertion (nixosConfig: cfg: {
|
||||
assertion = config.ports.${cfg.protocol}.enable;
|
||||
message = "port enable mismatch";
|
||||
}))
|
||||
];
|
||||
};
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
http = {
|
||||
enable = !config.ports.https.enable;
|
||||
port = 8080;
|
||||
protocol = "http";
|
||||
};
|
||||
https = {
|
||||
port = 8443;
|
||||
protocol = "https";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
19
modules/system/exports/ldap.nix
Normal file
19
modules/system/exports/ldap.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.ldap = { config, ... }: {
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
default = {
|
||||
port = 389;
|
||||
transport = "tcp";
|
||||
};
|
||||
ssl = {
|
||||
port = 636;
|
||||
ssl = true;
|
||||
listen = "wan";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
38
modules/system/exports/mosquitto.nix
Normal file
38
modules/system/exports/mosquitto.nix
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
inherit (lib.lists) all imap0;
|
||||
inherit (lib.trivial) id;
|
||||
in {
|
||||
config.exports.services.mosquitto = { config, ... }: {
|
||||
id = mkAlmostOptionDefault "mqtt";
|
||||
nixos = {
|
||||
serviceAttr = "mosquitto";
|
||||
assertions = mkIf config.enable [
|
||||
(nixosConfig: let
|
||||
cfg = nixosConfig.services.mosquitto;
|
||||
portName = i:
|
||||
if i == 0 then "default"
|
||||
else "listener${toString i}";
|
||||
mkAssertPort = i: listener: config.ports.${portName i}.port or null == listener.port;
|
||||
in {
|
||||
assertion = all id (imap0 mkAssertPort cfg.listeners);
|
||||
message = "port mismatch";
|
||||
})
|
||||
];
|
||||
};
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
default = {
|
||||
port = 1883;
|
||||
transport = "tcp";
|
||||
};
|
||||
ssl = {
|
||||
enable = false;
|
||||
port = 8883;
|
||||
ssl = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
18
modules/system/exports/motion.nix
Normal file
18
modules/system/exports/motion.nix
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.motion = { config, ... }: {
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
default = {
|
||||
port = 8080;
|
||||
protocol = "http";
|
||||
};
|
||||
stream = {
|
||||
port = 8081;
|
||||
protocol = "http";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
77
modules/system/exports/nfs.nix
Normal file
77
modules/system/exports/nfs.nix
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.nfs = { config, ... }: let
|
||||
mkAssertion = f: nixosConfig: let
|
||||
cfg = nixosConfig.services.nfs;
|
||||
in f nixosConfig cfg;
|
||||
mkAssertionPort = portName: mkAssertion (nixosConfig: cfg: let
|
||||
portAttr = "${portName}Port";
|
||||
in {
|
||||
assertion = mkAssertPort config.ports.${portName} cfg.server.${portAttr};
|
||||
message = "${portAttr} mismatch";
|
||||
});
|
||||
mkAssertPort = port: cfgPort: let
|
||||
cmpPort = if port.enable then port.port else null;
|
||||
in cfgPort == cmpPort;
|
||||
in {
|
||||
nixos = {
|
||||
serviceAttrPath = [ "services" "nfs" "server" ];
|
||||
assertions = mkIf config.enable [
|
||||
(mkAssertionPort "statd")
|
||||
(mkAssertionPort "lockd")
|
||||
(mkAssertionPort "mountd")
|
||||
(mkAssertion (nixosConfig: cfg: {
|
||||
assertion = nixosConfig.services.rpcbind.enable == config.ports.rpcbind.enable;
|
||||
message = "rpcbind enable mismatch";
|
||||
}))
|
||||
];
|
||||
};
|
||||
# TODO: expose over wan
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
default = {
|
||||
port = 2049;
|
||||
transport = "tcp";
|
||||
};
|
||||
udp = {
|
||||
port = config.ports.default.port;
|
||||
transport = "udp";
|
||||
};
|
||||
rpcbind = {
|
||||
port = 111;
|
||||
transport = "tcp";
|
||||
};
|
||||
rpcbind-udp = {
|
||||
port = config.ports.rpcbind.port;
|
||||
transport = "udp";
|
||||
};
|
||||
statd = {
|
||||
port = 4000;
|
||||
transport = "tcp";
|
||||
};
|
||||
statd-udp = {
|
||||
port = config.ports.statd.port;
|
||||
transport = "udp";
|
||||
};
|
||||
lockd = {
|
||||
port = 4001;
|
||||
transport = "tcp";
|
||||
};
|
||||
lockd-udp = {
|
||||
port = config.ports.lockd.port;
|
||||
transport = "udp";
|
||||
};
|
||||
mountd = {
|
||||
port = 4002;
|
||||
transport = "tcp";
|
||||
};
|
||||
mountd-udp = {
|
||||
port = config.ports.mountd.port;
|
||||
transport = "udp";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
43
modules/system/exports/plex.nix
Normal file
43
modules/system/exports/plex.nix
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.plex = {
|
||||
nixos.serviceAttr = "plex";
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
default = {
|
||||
port = 32400;
|
||||
protocol = "http";
|
||||
};
|
||||
roku = {
|
||||
port = 8324;
|
||||
transport = "tcp";
|
||||
};
|
||||
dlna-tcp = {
|
||||
port = 32469;
|
||||
transport = "tcp";
|
||||
};
|
||||
dlna-udp = {
|
||||
port = 1900;
|
||||
transport = "udp";
|
||||
};
|
||||
gdm0 = {
|
||||
port = 32410;
|
||||
transport = "udp";
|
||||
};
|
||||
gdm1 = {
|
||||
port = 32412;
|
||||
transport = "udp";
|
||||
};
|
||||
gdm2 = {
|
||||
port = 32413;
|
||||
transport = "udp";
|
||||
};
|
||||
gdm3 = {
|
||||
port = 32414;
|
||||
transport = "udp";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
27
modules/system/exports/postgresql.nix
Normal file
27
modules/system/exports/postgresql.nix
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults;
|
||||
inherit (lib.modules) mkIf;
|
||||
in {
|
||||
config.exports.services.postgresql = { config, ... }: let
|
||||
mkAssertion = f: nixosConfig: let
|
||||
cfg = nixosConfig.services.postgresql;
|
||||
in f nixosConfig cfg;
|
||||
in {
|
||||
nixos = {
|
||||
assertions = mkIf config.enable [
|
||||
(mkAssertion (nixosConfig: cfg: {
|
||||
assertion = config.ports.default.port == cfg.settings.port;
|
||||
message = "port mismatch";
|
||||
}))
|
||||
(mkAssertion (nixosConfig: cfg: {
|
||||
assertion = config.ports.default.enable == cfg.enableTCPIP;
|
||||
message = "enableTCPIP mismatch";
|
||||
}))
|
||||
];
|
||||
};
|
||||
ports.default = mapAlmostOptionDefaults {
|
||||
port = 5432;
|
||||
transport = "tcp";
|
||||
};
|
||||
};
|
||||
}
|
||||
12
modules/system/exports/prox.nix
Normal file
12
modules/system/exports/prox.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
in {
|
||||
config.exports.services.proxmox = { config, ... }: {
|
||||
id = mkAlmostOptionDefault "prox";
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports.default = mapAlmostOptionDefaults {
|
||||
port = 8006;
|
||||
protocol = "https";
|
||||
};
|
||||
};
|
||||
}
|
||||
29
modules/system/exports/samba.nix
Normal file
29
modules/system/exports/samba.nix
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.samba = {
|
||||
id = mkAlmostOptionDefault "smb";
|
||||
nixos.serviceAttr = "samba";
|
||||
# TODO: expose over wan
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
port0 = {
|
||||
port = 137;
|
||||
transport = "udp";
|
||||
};
|
||||
port1 = {
|
||||
port = 138;
|
||||
transport = "udp";
|
||||
};
|
||||
port2 = {
|
||||
port = 139;
|
||||
transport = "tcp";
|
||||
};
|
||||
default = {
|
||||
port = 445;
|
||||
transport = "tcp";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
155
modules/system/exports/services.nix
Normal file
155
modules/system/exports/services.nix
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
{
|
||||
config,
|
||||
name,
|
||||
lib,
|
||||
gensokyo-zone,
|
||||
...
|
||||
}: let
|
||||
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrsToList getAttrFromPath;
|
||||
inherit (lib.trivial) mapNullable;
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
systemConfig = config;
|
||||
portModule = {config, service, ...}: {
|
||||
options = with lib.types; {
|
||||
enable =
|
||||
mkEnableOption "port"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
listen = mkOption {
|
||||
type = enum ["wan" "lan" "int" "localhost"];
|
||||
};
|
||||
protocol = mkOption {
|
||||
type = nullOr (enum ["http" "https"]);
|
||||
default = null;
|
||||
};
|
||||
transport = mkOption {
|
||||
type = enum ["tcp" "udp" "unix"];
|
||||
};
|
||||
path = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
description = "unix socket path";
|
||||
};
|
||||
ssl = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
};
|
||||
port = mkOption {
|
||||
type = nullOr int;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
transport = mkMerge [
|
||||
(mkIf (config.protocol == "http" || config.protocol == "https") (mkOptionDefault "tcp"))
|
||||
(mkIf config.ssl (mkOptionDefault "tcp"))
|
||||
];
|
||||
ssl = mkIf (config.protocol == "https") (
|
||||
mkAlmostOptionDefault true
|
||||
);
|
||||
listen = mkOptionDefault service.defaults.port.listen;
|
||||
};
|
||||
};
|
||||
serviceModule = {
|
||||
config,
|
||||
name,
|
||||
...
|
||||
}: {
|
||||
options = with lib.types; {
|
||||
enable = mkEnableOption "hosted service";
|
||||
name = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
};
|
||||
id = mkOption {
|
||||
type = str;
|
||||
default = config.name;
|
||||
};
|
||||
ports = mkOption {
|
||||
type = attrsOf (submoduleWith {
|
||||
modules = [portModule];
|
||||
specialArgs = {
|
||||
service = config;
|
||||
};
|
||||
});
|
||||
};
|
||||
nixos = {
|
||||
serviceAttr = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
serviceAttrPath = mkOption {
|
||||
type = nullOr (listOf str);
|
||||
};
|
||||
assertions = mkOption {
|
||||
type = listOf (functionTo attrs);
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
defaults = {
|
||||
port = {
|
||||
listen = mkOption {
|
||||
type = str;
|
||||
default = "int";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
nixos = {
|
||||
serviceAttrPath = mkOptionDefault (
|
||||
mapNullable (serviceAttr: ["services" config.nixos.serviceAttr]) config.nixos.serviceAttr
|
||||
);
|
||||
assertions = let
|
||||
serviceConfig = getAttrFromPath config.nixos.serviceAttrPath;
|
||||
mkAssertion = f: nixosConfig: let
|
||||
cfg = serviceConfig nixosConfig;
|
||||
in f nixosConfig cfg;
|
||||
enableAssertion = nixosConfig: cfg: {
|
||||
assertion = (! cfg ? enable) || (config.enable == cfg.enable);
|
||||
message = "enable == nixosConfig.${concatStringsSep "." config.nixos.serviceAttrPath}.enable";
|
||||
};
|
||||
in [
|
||||
(mkIf (config.nixos.serviceAttrPath != null) (
|
||||
mkAssertion enableAssertion
|
||||
))
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
nixosModule = {config, system, ...}: let
|
||||
mapAssertion = service: a: let
|
||||
res = a config;
|
||||
in res // {
|
||||
message = "system.exports.${service.name}: " + res.message or "assertion failed";
|
||||
};
|
||||
assertions = mapAttrsToList (_: service: map (mapAssertion service) service.nixos.assertions) system.exports.services;
|
||||
in {
|
||||
config = {
|
||||
assertions = mkMerge assertions;
|
||||
# TODO: export ports via firewall according to enable/listen/etc
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.exports = with lib.types; {
|
||||
services = mkOption {
|
||||
type = attrsOf (submoduleWith {
|
||||
modules = [serviceModule];
|
||||
specialArgs = {
|
||||
machine = name;
|
||||
inherit systemConfig;
|
||||
};
|
||||
});
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
modules = mkIf (config.type == "NixOS") [
|
||||
nixosModule
|
||||
];
|
||||
};
|
||||
}
|
||||
7
modules/system/exports/tailscale.nix
Normal file
7
modules/system/exports/tailscale.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{...}: {
|
||||
config.exports.services.tailscale = {
|
||||
id = "tail";
|
||||
nixos.serviceAttr = "tailscale";
|
||||
ports = {};
|
||||
};
|
||||
}
|
||||
47
modules/system/exports/unifi.nix
Normal file
47
modules/system/exports/unifi.nix
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.unifi = { config, ... }: {
|
||||
nixos.serviceAttr = "unifi";
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
management = {
|
||||
# remote login
|
||||
port = 8443;
|
||||
protocol = "https";
|
||||
listen = "int";
|
||||
};
|
||||
uap = {
|
||||
# UAP to inform controller
|
||||
port = 8080;
|
||||
transport = "tcp";
|
||||
};
|
||||
portal = {
|
||||
# HTTP portal redirect, if guest portal is enabled
|
||||
port = 8880;
|
||||
protocol = "http";
|
||||
};
|
||||
portal-secure = {
|
||||
# HTTPS portal redirect
|
||||
port = 8843;
|
||||
protocol = "https";
|
||||
};
|
||||
speedtest = {
|
||||
# UniFi mobile speed test
|
||||
port = 6789;
|
||||
transport = "tcp";
|
||||
};
|
||||
stun = {
|
||||
port = 3478;
|
||||
transport = "udp";
|
||||
listen = "wan";
|
||||
};
|
||||
discovery = {
|
||||
# device discovery
|
||||
port = 10001;
|
||||
transport = "udp";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
22
modules/system/exports/vouch.nix
Normal file
22
modules/system/exports/vouch.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkIf;
|
||||
in {
|
||||
config.exports.services.vouch-proxy = { config, ... }: {
|
||||
id = mkAlmostOptionDefault "login";
|
||||
defaults.port.listen = mkAlmostOptionDefault "localhost";
|
||||
nixos = {
|
||||
serviceAttr = "vouch-proxy";
|
||||
assertions = mkIf config.enable [
|
||||
(nixosConfig: {
|
||||
assertion = config.ports.default.port == nixosConfig.services.vouch-proxy.settings.vouch.port;
|
||||
message = "port mismatch";
|
||||
})
|
||||
];
|
||||
};
|
||||
ports.default = mapAlmostOptionDefaults {
|
||||
port = 30746;
|
||||
protocol = "http";
|
||||
};
|
||||
};
|
||||
}
|
||||
21
modules/system/exports/zigbee2mqtt.nix
Normal file
21
modules/system/exports/zigbee2mqtt.nix
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkIf;
|
||||
in {
|
||||
config.exports.services.zigbee2mqtt = { config, ... }: {
|
||||
id = mkAlmostOptionDefault "z2m";
|
||||
nixos = {
|
||||
serviceAttr = "zigbee2mqtt";
|
||||
assertions = mkIf config.enable [
|
||||
(nixosConfig: {
|
||||
assertion = config.ports.default.port == nixosConfig.services.zigbee2mqtt.settings.frontend.port;
|
||||
message = "port mismatch";
|
||||
})
|
||||
];
|
||||
};
|
||||
ports.default = mapAlmostOptionDefaults {
|
||||
port = 8072;
|
||||
protocol = "http";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -15,6 +15,11 @@ in {
|
|||
inherit (lib.types) str listOf attrs unspecified enum;
|
||||
inherit (lib.options) mkOption;
|
||||
in {
|
||||
name = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
readOnly = true;
|
||||
};
|
||||
arch = mkOption {
|
||||
description = "Processor architecture of the host";
|
||||
type = str;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
}:
|
||||
let
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
|
||||
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault mkOptionDefault;
|
||||
inherit (lib.strings) optionalString concatStringsSep;
|
||||
inherit (config.services) tailscale;
|
||||
inherit (config.services) nginx;
|
||||
|
|
@ -86,6 +86,10 @@ in {
|
|||
default = 4444;
|
||||
};
|
||||
kpasswd = mkOption {
|
||||
type = port;
|
||||
default = 464;
|
||||
};
|
||||
kadmin = mkOption {
|
||||
type = port;
|
||||
default = 749;
|
||||
};
|
||||
|
|
@ -108,46 +112,58 @@ in {
|
|||
};
|
||||
config = {
|
||||
services.nginx = {
|
||||
access.ldap = {
|
||||
enable = mkDefault true;
|
||||
host = mkDefault access.host;
|
||||
port = mkDefault 389;
|
||||
sslPort = mkDefault access.ldapPort;
|
||||
useACMEHost = mkDefault virtualHosts.freeipa.ssl.cert.name;
|
||||
bind.sslPort = mkIf access.preread.enable (mkDefault access.preread.ldapPort);
|
||||
access.freeipa = {
|
||||
host = mkOptionDefault (config.lib.access.getAddressFor (config.lib.access.systemForService "freeipa").name "lan");
|
||||
};
|
||||
resolver.addresses = mkIf access.preread.enable (mkMerge [
|
||||
(mkDefault [ "[::1]:5353" "127.0.0.1:5353" ])
|
||||
(mkIf config.systemd.network.enable [ "127.0.0.53" ])
|
||||
]);
|
||||
defaultSSLListenPort = mkIf access.preread.enable access.preread.port;
|
||||
streamConfig = let
|
||||
upstreams' = {
|
||||
freeipa = "${access.host}:${toString access.port}";
|
||||
ldap_freeipa = "${nginx.access.ldap.host}:${toString nginx.access.ldap.sslPort}";
|
||||
ldap = "localhost:${toString nginx.access.ldap.bind.sslPort}";
|
||||
nginx = "localhost:${toString nginx.defaultSSLListenPort}";
|
||||
samba = if config.services.samba.enable
|
||||
then "localhost:445"
|
||||
else "smb.local.${config.networking.domain}:445";
|
||||
stream = {
|
||||
upstreams = {
|
||||
freeipa.servers.access = let
|
||||
system = config.lib.access.systemForService "freeipa";
|
||||
inherit (system.exports.services) freeipa;
|
||||
in {
|
||||
addr = mkDefault (config.lib.access.getAddressFor system.name "lan");
|
||||
port = mkOptionDefault freeipa.ports.default.port;
|
||||
};
|
||||
samba_access.servers.access = let
|
||||
system = config.lib.access.systemForService "samba";
|
||||
inherit (system.exports.services) samba;
|
||||
in {
|
||||
addr = mkDefault (config.lib.access.getAddressFor system.name "lan");
|
||||
port = mkOptionDefault samba.ports.default.port;
|
||||
};
|
||||
ldaps_access.servers.access = {
|
||||
addr = mkDefault "localhost";
|
||||
port = mkOptionDefault nginx.stream.servers.ldap.listen.ldaps.port;
|
||||
};
|
||||
nginx.servers.access = {
|
||||
addr = mkDefault "localhost";
|
||||
port = mkOptionDefault nginx.defaultSSLListenPort;
|
||||
};
|
||||
};
|
||||
servers = {
|
||||
ldap = {
|
||||
listen = {
|
||||
ldaps.port = mkIf access.preread.enable (mkDefault access.preread.ldapPort);
|
||||
};
|
||||
proxy.upstream = mkDefault "ldap";
|
||||
ssl.cert.copyFromVhost = mkDefault "freeipa";
|
||||
};
|
||||
};
|
||||
};
|
||||
streamConfig = let
|
||||
upstreams = {
|
||||
freeipa = "freeipa";
|
||||
ldap = "ldaps_access";
|
||||
ldap_freeipa = "ldaps";
|
||||
samba = "samba_access";
|
||||
nginx = "nginx";
|
||||
};
|
||||
upstreams = builtins.mapAttrs (name: _: name) upstreams';
|
||||
preread = ''
|
||||
upstream freeipa {
|
||||
server ${upstreams'.freeipa};
|
||||
}
|
||||
upstream ldap_freeipa {
|
||||
server ${upstreams'.ldap_freeipa};
|
||||
}
|
||||
upstream ldap {
|
||||
server ${upstreams'.ldap};
|
||||
}
|
||||
upstream samba {
|
||||
server ${upstreams'.samba};
|
||||
}
|
||||
upstream nginx {
|
||||
server ${upstreams'.nginx};
|
||||
}
|
||||
map $ssl_preread_server_name $ssl_server_name {
|
||||
hostnames;
|
||||
${virtualHosts.freeipa.serverName} ${upstreams.freeipa};
|
||||
|
|
@ -204,6 +220,11 @@ in {
|
|||
listen [::]:${toString access.kerberos.ports.kpasswd} udp;
|
||||
proxy_pass ${access.host}:${toString access.kerberos.ports.kpasswd};
|
||||
}
|
||||
server {
|
||||
listen 0.0.0.0:${toString access.kerberos.ports.kadmin};
|
||||
listen [::]:${toString access.kerberos.ports.kadmin};
|
||||
proxy_pass ${access.host}:${toString access.kerberos.ports.kadmin};
|
||||
}
|
||||
'';
|
||||
in mkMerge [
|
||||
(mkIf access.preread.enable preread)
|
||||
|
|
@ -265,6 +286,7 @@ in {
|
|||
(mkIf access.kerberos.enable [
|
||||
access.kerberos.ports.ticket
|
||||
access.kerberos.ports.kpasswd
|
||||
access.kerberos.ports.kadmin
|
||||
])
|
||||
(mkIf access.preread.enable [
|
||||
636
|
||||
|
|
|
|||
|
|
@ -1,49 +1,21 @@
|
|||
{
|
||||
config,
|
||||
access,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
inherit (lib.lists) head optional;
|
||||
inherit (lib.strings) splitString;
|
||||
inherit (lib.lists) optional;
|
||||
inherit (config.services) nginx;
|
||||
access = nginx.access.freepbx;
|
||||
hasSsl = nginx.virtualHosts.freepbx'ucp.listen'.ucpSsl.enable;
|
||||
system = access.systemForService "freepbx";
|
||||
inherit (system.exports.services) freepbx;
|
||||
in {
|
||||
options.services.nginx.access.freepbx = with lib.types; {
|
||||
host = mkOption {
|
||||
type = str;
|
||||
default = config.lib.access.getHostnameFor "freepbx" "lan";
|
||||
};
|
||||
url = mkOption {
|
||||
type = str;
|
||||
default = "https://${access.host}";
|
||||
};
|
||||
asteriskPort = mkOption {
|
||||
type = port;
|
||||
default = 8088;
|
||||
};
|
||||
asteriskSslPort = mkOption {
|
||||
type = port;
|
||||
default = 8089;
|
||||
};
|
||||
ucpPort = mkOption {
|
||||
type = port;
|
||||
default = 8001;
|
||||
};
|
||||
ucpSslPort = mkOption {
|
||||
type = port;
|
||||
default = 8003;
|
||||
};
|
||||
ucpUrl = mkOption {
|
||||
type = str;
|
||||
default = "https://${access.host}:${toString access.ucpSslPort}";
|
||||
};
|
||||
};
|
||||
config.services.nginx = {
|
||||
virtualHosts = let
|
||||
proxyScheme = head (splitString ":" access.url);
|
||||
proxyScheme = "https";
|
||||
url = access.proxyUrlFor { serviceName = "freepbx"; portName = proxyScheme; };
|
||||
ucpUrl = access.proxyUrlFor { serviceName = "freepbx"; portName = "ucp-ssl"; };
|
||||
# TODO: ports.asterisk/asterisk-ssl?
|
||||
extraConfig = ''
|
||||
proxy_buffer_size 128k;
|
||||
proxy_buffers 4 256k;
|
||||
|
|
@ -57,11 +29,11 @@ in {
|
|||
'';
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = access.url;
|
||||
proxyPass = mkDefault url;
|
||||
};
|
||||
"/socket.io" = {
|
||||
proxy.websocket.enable = true;
|
||||
proxyPass = "${access.ucpUrl}/socket.io";
|
||||
proxyPass = mkDefault "${ucpUrl}/socket.io";
|
||||
extraConfig = ''
|
||||
proxy_hide_header Access-Control-Allow-Origin;
|
||||
add_header Access-Control-Allow-Origin $pbx_scheme://$host;
|
||||
|
|
@ -81,11 +53,11 @@ in {
|
|||
ssl.cert.copyFromVhost = "freepbx";
|
||||
listen' = {
|
||||
ucp = {
|
||||
port = access.ucpPort;
|
||||
port = mkDefault freepbx.ports.ucp.port;
|
||||
extraParameters = [ "default_server" ];
|
||||
};
|
||||
ucpSsl = {
|
||||
port = access.ucpSslPort;
|
||||
port = mkDefault freepbx.ports.ucp-ssl.port;
|
||||
ssl = true;
|
||||
extraParameters = [ "default_server" ];
|
||||
};
|
||||
|
|
@ -93,8 +65,9 @@ in {
|
|||
proxy.websocket.enable = true;
|
||||
vouch.enable = mkDefault true;
|
||||
local.denyGlobal = mkDefault nginx.virtualHosts.freepbx.local.denyGlobal;
|
||||
locations = {
|
||||
inherit (locations) "/socket.io";
|
||||
locations."/socket.io" = {
|
||||
inherit (locations."/socket.io") proxy extraConfig;
|
||||
proxyPass = mkDefault nginx.virtualHosts.freepbx.locations."/socket.io".proxyPass;
|
||||
};
|
||||
inherit extraConfig kTLS;
|
||||
};
|
||||
|
|
@ -103,23 +76,34 @@ in {
|
|||
http = { };
|
||||
https.ssl = true;
|
||||
ucp = {
|
||||
port = access.ucpPort;
|
||||
port = mkDefault nginx.virtualHosts.freepbx'ucp.listen'.ucp.port;
|
||||
};
|
||||
ucpSsl = {
|
||||
port = access.ucpSslPort;
|
||||
port = mkDefault nginx.virtualHosts.freepbx'ucp.listen'.ucpSsl.port;
|
||||
ssl = true;
|
||||
};
|
||||
};
|
||||
ssl.cert.copyFromVhost = "freepbx";
|
||||
local.enable = true;
|
||||
inherit name locations extraConfig kTLS;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = mkDefault nginx.virtualHosts.freepbx.locations."/".proxyPass;
|
||||
};
|
||||
"/socket.io" = {
|
||||
inherit (locations."/socket.io") proxy extraConfig;
|
||||
proxyPass = mkDefault nginx.virtualHosts.freepbx.locations."/socket.io".proxyPass;
|
||||
};
|
||||
};
|
||||
inherit name extraConfig kTLS;
|
||||
};
|
||||
};
|
||||
};
|
||||
config.networking.firewall = let
|
||||
websocketPorts = [access.ucpPort] ++ optional hasSsl access.ucpSslPort;
|
||||
websocketPorts = virtualHost: [
|
||||
virtualHost.listen'.ucp.port
|
||||
] ++ optional virtualHost.listen'.ucpSsl.enable virtualHost.listen'.ucpSsl.port;
|
||||
in {
|
||||
interfaces.local.allowedTCPPorts = websocketPorts;
|
||||
allowedTCPPorts = mkIf (!nginx.virtualHosts.freepbx'ucp.local.denyGlobal) websocketPorts;
|
||||
interfaces.local.allowedTCPPorts = websocketPorts nginx.virtualHosts.freepbx'local;
|
||||
allowedTCPPorts = mkIf (!nginx.virtualHosts.freepbx'ucp.local.denyGlobal) (websocketPorts nginx.virtualHosts.freepbx'ucp);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
access,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
inherit (lib.modules) mkDefault;
|
||||
inherit (config.services) home-assistant nginx;
|
||||
name.shortServer = mkDefault "home";
|
||||
listen' = {
|
||||
|
|
@ -24,8 +25,9 @@ in {
|
|||
websocket.enable = true;
|
||||
headers.enableRecommended = true;
|
||||
};
|
||||
proxyPass = mkIf home-assistant.enable (mkDefault
|
||||
"http://localhost:${toString home-assistant.config.http.server_port}"
|
||||
proxyPass = mkDefault (
|
||||
if home-assistant.enable then "http://localhost:${toString home-assistant.config.http.server_port}"
|
||||
else access.proxyUrlFor { serviceName = "home-assistant"; }
|
||||
);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
config,
|
||||
access,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
|
||||
inherit (lib.modules) mkMerge mkBefore mkDefault;
|
||||
inherit (lib.strings) replaceStrings concatStringsSep concatMapStringsSep escapeRegex;
|
||||
inherit (config.services.nginx) virtualHosts;
|
||||
cfg = config.services.invidious;
|
||||
|
|
@ -86,8 +87,9 @@ in {
|
|||
location
|
||||
{
|
||||
vouch.requireAuth = true;
|
||||
proxyPass = mkIf cfg.enable (
|
||||
mkDefault "http://localhost:${toString cfg.port}"
|
||||
proxyPass = mkDefault (if cfg.enable
|
||||
then "http://localhost:${toString cfg.port}"
|
||||
else access.proxyUrlFor { serviceName = "invidious"; }
|
||||
);
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
access,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
inherit (lib.modules) mkDefault;
|
||||
cfg = config.services.keycloak;
|
||||
inherit (config.services) nginx;
|
||||
in {
|
||||
|
|
@ -13,11 +14,11 @@ in {
|
|||
name.shortServer = mkDefault "sso";
|
||||
ssl.force = mkDefault true;
|
||||
locations."/".proxyPass = let
|
||||
url = mkDefault (if cfg.sslCertificate != null
|
||||
then "https://localhost:${toString cfg.settings.https-port}"
|
||||
else "http://localhost:${toString cfg.settings.http-port}"
|
||||
);
|
||||
in mkIf cfg.enable (mkDefault url);
|
||||
url = mkDefault "${cfg.protocol}://localhost:${toString cfg.port}";
|
||||
in mkDefault (
|
||||
if cfg.enable then url
|
||||
else access.proxyUrlFor { serviceName = "keycloak"; portName = "https"; }
|
||||
);
|
||||
};
|
||||
keycloak'local = {
|
||||
name.shortServer = mkDefault "sso";
|
||||
|
|
|
|||
|
|
@ -1,60 +1,44 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
access,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkDefault;
|
||||
inherit (lib.lists) concatMap;
|
||||
inherit (lib.modules) mkDefault;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
inherit (config.services) nginx;
|
||||
inherit (config.services.nginx) virtualHosts;
|
||||
access = config.services.nginx.access.kitchencam;
|
||||
system = access.systemForServiceId "kitchen";
|
||||
inherit (system.exports.services) motion;
|
||||
in {
|
||||
options.services.nginx.access.kitchencam = with lib.types; {
|
||||
streamPort = mkOption {
|
||||
type = port;
|
||||
default = 8081;
|
||||
};
|
||||
host = mkOption {
|
||||
type = str;
|
||||
default = "kitchencam.local.${config.networking.domain}";
|
||||
};
|
||||
url = mkOption {
|
||||
type = str;
|
||||
default = "http://${access.host}:8080";
|
||||
};
|
||||
streamUrl = mkOption {
|
||||
type = str;
|
||||
default = "http://${access.host}:${toString access.streamPort}";
|
||||
};
|
||||
useACMEHost = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
config.services.nginx = {
|
||||
virtualHosts = let
|
||||
url = access.proxyUrlFor { inherit system; service = motion; };
|
||||
streamUrl = access.proxyUrlFor { inherit system; service = motion; portName = "stream"; };
|
||||
extraConfig = ''
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
'';
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = access.url;
|
||||
proxyPass = mkDefault url;
|
||||
};
|
||||
"~ ^/[0-9]+/(stream|motion|substream|current|source|status\\.json)$" = {
|
||||
proxyPass = access.streamUrl;
|
||||
proxyPass = mkDefault streamUrl;
|
||||
inherit extraConfig;
|
||||
};
|
||||
"~ ^/(stream|motion|substream|current|source|cameras\\.json|status\\.json)$" = {
|
||||
proxyPass = access.streamUrl;
|
||||
proxyPass = mkDefault streamUrl;
|
||||
inherit extraConfig;
|
||||
};
|
||||
};
|
||||
listen' = {
|
||||
http = { };
|
||||
https.ssl = true;
|
||||
stream.port = mkDefault access.streamPort;
|
||||
stream = {
|
||||
enable = mkDefault motion.ports.stream.enable;
|
||||
port = mkDefault motion.ports.stream.port;
|
||||
};
|
||||
};
|
||||
name.shortServer = mkDefault "kitchen";
|
||||
kTLS = mkDefault true;
|
||||
|
|
@ -64,13 +48,18 @@ in {
|
|||
vouch.enable = true;
|
||||
};
|
||||
kitchencam'local = {
|
||||
inherit name locations listen' kTLS;
|
||||
inherit name listen' kTLS;
|
||||
ssl.cert.copyFromVhost = "kitchencam";
|
||||
local.enable = true;
|
||||
locations = mapAttrs (name: location: location // {
|
||||
proxyPass = mkDefault nginx.virtualHosts.kitchencam.locations.${name}.proxyPass;
|
||||
}) locations;
|
||||
};
|
||||
};
|
||||
};
|
||||
config.networking.firewall.allowedTCPPorts = [
|
||||
access.streamPort
|
||||
config.networking.firewall.allowedTCPPorts = let
|
||||
inherit (nginx.virtualHosts.kitchencam) listen';
|
||||
in [
|
||||
listen'.stream.port
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,21 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
gensokyo-zone,
|
||||
access,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge;
|
||||
inherit (lib.strings) concatMapStringsSep optionalString;
|
||||
inherit (config.services.nginx) virtualHosts;
|
||||
inherit (config.networking.access) cidrForNetwork localaddrs;
|
||||
access = config.services.nginx.access.ldap;
|
||||
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (lib.modules) mkIf mkOptionDefault;
|
||||
inherit (config.services) nginx;
|
||||
portPlaintext = 389;
|
||||
portSsl = 636;
|
||||
allows = let
|
||||
mkAllow = cidr: "allow ${cidr};";
|
||||
allows = concatMapStringsSep "\n" mkAllow cidrForNetwork.allLocal.all + optionalString localaddrs.enable ''
|
||||
include ${localaddrs.stateDir}/*.nginx.conf;
|
||||
'';
|
||||
in ''
|
||||
${allows}
|
||||
deny all;
|
||||
'';
|
||||
system = access.systemForService "ldap";
|
||||
inherit (system.exports.services) ldap;
|
||||
in {
|
||||
options.services.nginx.access.ldap = with lib.types; {
|
||||
enable = mkEnableOption "LDAP proxy";
|
||||
host = mkOption {
|
||||
type = str;
|
||||
};
|
||||
domain = mkOption {
|
||||
type = str;
|
||||
default = "ldap.${config.networking.domain}";
|
||||
|
|
@ -43,67 +32,49 @@ in {
|
|||
type = str;
|
||||
default = "ldap.tail.${config.networking.domain}";
|
||||
};
|
||||
port = mkOption {
|
||||
type = port;
|
||||
default = portSsl;
|
||||
};
|
||||
sslPort = mkOption {
|
||||
type = port;
|
||||
default = portSsl;
|
||||
};
|
||||
bind = {
|
||||
sslPort = mkOption {
|
||||
type = port;
|
||||
default = portSsl;
|
||||
};
|
||||
port = mkOption {
|
||||
type = port;
|
||||
default = portPlaintext;
|
||||
};
|
||||
};
|
||||
useACMEHost = mkOption {
|
||||
type = nullOr str;
|
||||
default = virtualHosts.${access.domain}.useACMEHost or null;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
services.nginx = {
|
||||
streamConfig = let
|
||||
cert = config.security.acme.certs.${access.useACMEHost};
|
||||
proxySsl = port: optionalString (port == portSsl) ''
|
||||
proxy_ssl on;
|
||||
proxy_ssl_verify off;
|
||||
'';
|
||||
in mkIf access.enable (mkMerge [
|
||||
''
|
||||
server {
|
||||
listen 0.0.0.0:${toString access.bind.port};
|
||||
listen [::]:${toString access.bind.port};
|
||||
${allows}
|
||||
proxy_pass ${access.host}:${toString access.port};
|
||||
${proxySsl access.port}
|
||||
}
|
||||
''
|
||||
(mkIf (access.useACMEHost != null) ''
|
||||
server {
|
||||
listen 0.0.0.0:${toString access.bind.sslPort} ssl;
|
||||
listen [::]:${toString access.bind.sslPort} ssl;
|
||||
ssl_certificate ${cert.directory}/fullchain.pem;
|
||||
ssl_certificate_key ${cert.directory}/key.pem;
|
||||
ssl_trusted_certificate ${cert.directory}/chain.pem;
|
||||
proxy_pass ${access.host}:${toString access.sslPort};
|
||||
${proxySsl access.sslPort}
|
||||
}
|
||||
'')
|
||||
]);
|
||||
stream = {
|
||||
upstreams = let
|
||||
addr = mkAlmostOptionDefault (access.getAddressFor system.name "lan");
|
||||
in {
|
||||
ldap.servers.access = {
|
||||
inherit addr;
|
||||
port = mkOptionDefault ldap.ports.default.port;
|
||||
};
|
||||
ldaps = {
|
||||
enable = mkAlmostOptionDefault ldap.ports.ssl.enable;
|
||||
ssl.enable = mkAlmostOptionDefault true;
|
||||
servers.access = {
|
||||
inherit addr;
|
||||
port = mkOptionDefault ldap.ports.ssl.port;
|
||||
};
|
||||
};
|
||||
};
|
||||
servers.ldap = {
|
||||
listen = {
|
||||
ldap.port = mkOptionDefault portPlaintext;
|
||||
ldaps = {
|
||||
port = mkOptionDefault portSsl;
|
||||
ssl = true;
|
||||
};
|
||||
};
|
||||
proxy.upstream = mkAlmostOptionDefault (
|
||||
if nginx.stream.upstreams.ldaps.enable then "ldaps" else "ldap"
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
networking.firewall = let
|
||||
inherit (nginx.stream.servers.ldap) listen;
|
||||
in {
|
||||
interfaces.local.allowedTCPPorts = [
|
||||
access.bind.port
|
||||
listen.ldap.port
|
||||
];
|
||||
allowedTCPPorts = [
|
||||
access.bind.sslPort
|
||||
allowedTCPPorts = mkIf listen.ldaps.enable [
|
||||
listen.ldaps.port
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,72 +1,59 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
access,
|
||||
gensokyo-zone,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (inputs.self.lib.lib) mkAlmostOptionDefault;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
|
||||
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkIf mkOptionDefault;
|
||||
inherit (config.services) nginx;
|
||||
access = nginx.access.mosquitto;
|
||||
portPlaintext = 1883;
|
||||
portSsl = 8883;
|
||||
system = access.systemForService "mosquitto";
|
||||
inherit (system.exports.services) mosquitto;
|
||||
in {
|
||||
options.services.nginx.access.mosquitto = with lib.types; {
|
||||
enable = mkEnableOption "MQTT proxy";
|
||||
host = mkOption {
|
||||
type = str;
|
||||
};
|
||||
port = mkOption {
|
||||
type = port;
|
||||
default = portPlaintext;
|
||||
};
|
||||
bind = {
|
||||
sslPort = mkOption {
|
||||
type = port;
|
||||
default = portSsl;
|
||||
};
|
||||
port = mkOption {
|
||||
type = port;
|
||||
default = portPlaintext;
|
||||
};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
services.nginx = {
|
||||
stream = {
|
||||
upstreams.mosquitto = {
|
||||
servers.access = {
|
||||
addr = mkAlmostOptionDefault access.host;
|
||||
port = mkOptionDefault access.port;
|
||||
upstreams = let
|
||||
addr = mkAlmostOptionDefault (access.getAddressFor system.name "lan");
|
||||
in {
|
||||
mqtt.servers.access = {
|
||||
inherit addr;
|
||||
port = mkOptionDefault mosquitto.ports.default.port;
|
||||
};
|
||||
mqtts = {
|
||||
enable = mkAlmostOptionDefault mosquitto.ports.ssl.enable;
|
||||
ssl.enable = true;
|
||||
servers.access = {
|
||||
inherit addr;
|
||||
port = mkOptionDefault mosquitto.ports.ssl.port;
|
||||
};
|
||||
};
|
||||
};
|
||||
servers.mosquitto = {
|
||||
listen = {
|
||||
mqtt.port = portPlaintext;
|
||||
mqtt.port = mkOptionDefault portPlaintext;
|
||||
mqtts = {
|
||||
ssl = true;
|
||||
port = portSsl;
|
||||
port = mkOptionDefault portSsl;
|
||||
};
|
||||
};
|
||||
extraConfig = let
|
||||
proxySsl = port: mkIf (port == portSsl) ''
|
||||
proxy_ssl on;
|
||||
proxy_ssl_verify off;
|
||||
'';
|
||||
in mkMerge [
|
||||
"proxy_pass ${nginx.stream.upstreams.mosquitto.name};"
|
||||
(proxySsl access.port)
|
||||
];
|
||||
proxy.upstream = mkAlmostOptionDefault (
|
||||
if nginx.stream.upstreams.mqtts.enable then "mqtts" else "mqtt"
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
interfaces.local.allowedTCPPorts = [
|
||||
access.bind.port
|
||||
(mkIf nginx.stream.servers.mosquitto.listen.mqtts.enable access.bind.sslPort)
|
||||
interfaces.local.allowedTCPPorts = let
|
||||
inherit (nginx.stream.servers.mosquitto) listen;
|
||||
in [
|
||||
listen.mqtt.port
|
||||
(mkIf listen.mqtts.enable listen.mqtts.port)
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,27 +1,14 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
access,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
inherit (config.services) nginx;
|
||||
cfg = config.services.plex;
|
||||
access = nginx.access.plex;
|
||||
in {
|
||||
options.services.nginx.access.plex = with lib.types; {
|
||||
url = mkOption {
|
||||
type = str;
|
||||
};
|
||||
externalPort = mkOption {
|
||||
type = nullOr port;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
config.services.nginx = {
|
||||
access.plex = mkIf cfg.enable {
|
||||
url = mkOptionDefault "http://localhost:${toString cfg.port}";
|
||||
};
|
||||
virtualHosts = let
|
||||
extraConfig = ''
|
||||
# Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause
|
||||
|
|
@ -44,8 +31,11 @@ in {
|
|||
proxy_buffering off;
|
||||
'';
|
||||
locations."/" = {
|
||||
proxy.websocket.enable = true;
|
||||
proxyPass = access.url;
|
||||
proxy.websocket.enable = mkDefault true;
|
||||
proxyPass = mkDefault (if cfg.enable
|
||||
then "http://localhost:${toString cfg.port}"
|
||||
else access.proxyUrlFor { serviceName = "plex"; }
|
||||
);
|
||||
};
|
||||
name.shortServer = mkDefault "plex";
|
||||
kTLS = mkDefault true;
|
||||
|
|
@ -56,8 +46,8 @@ in {
|
|||
http = { };
|
||||
https.ssl = true;
|
||||
external = {
|
||||
enable = mkDefault (access.externalPort != null);
|
||||
port = mkDefault access.externalPort;
|
||||
enable = mkDefault false;
|
||||
port = mkDefault 32400;
|
||||
extraParameters = [ "default_server" ];
|
||||
};
|
||||
};
|
||||
|
|
@ -69,7 +59,9 @@ in {
|
|||
};
|
||||
};
|
||||
};
|
||||
config.networking.firewall.allowedTCPPorts = mkIf (access.externalPort != null) [
|
||||
access.externalPort
|
||||
config.networking.firewall.allowedTCPPorts = let
|
||||
inherit (nginx.virtualHosts.plex) listen';
|
||||
in mkIf listen'.external.enable [
|
||||
listen'.external.port
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
access,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkMerge mkDefault;
|
||||
inherit (lib.modules) mkDefault;
|
||||
inherit (lib.strings) escapeRegex;
|
||||
inherit (config.services) nginx tailscale;
|
||||
proxyPass = "https://reisen.local.${config.networking.domain}:8006/";
|
||||
proxyPass = access.proxyUrlFor { serviceName = "proxmox"; } + "/";
|
||||
in {
|
||||
config.services.nginx.virtualHosts = let
|
||||
locations."/" = {
|
||||
|
|
|
|||
|
|
@ -1,70 +1,37 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
access,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
||||
inherit (config.services) nginx tailscale unifi;
|
||||
access = nginx.access.unifi;
|
||||
inherit (lib.modules) mkDefault;
|
||||
inherit (config.services) nginx;
|
||||
in {
|
||||
options.services.nginx.access.unifi = with lib.types; {
|
||||
global = {
|
||||
management = mkEnableOption "global management port access";
|
||||
};
|
||||
host = mkOption {
|
||||
type = str;
|
||||
};
|
||||
url = mkOption {
|
||||
type = str;
|
||||
default = "https://${access.host}:${toString access.managementPort}";
|
||||
};
|
||||
managementPort = mkOption {
|
||||
type = port;
|
||||
default = 8443;
|
||||
};
|
||||
};
|
||||
config.services.nginx = {
|
||||
access.unifi = mkIf unifi.enable {
|
||||
host = mkOptionDefault "localhost";
|
||||
};
|
||||
virtualHosts = let
|
||||
extraConfig = ''
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
'';
|
||||
locations."/" = {
|
||||
proxyPass = mkDefault access.url;
|
||||
};
|
||||
name.shortServer = mkDefault "unifi";
|
||||
kTLS = mkDefault true;
|
||||
in {
|
||||
unifi'management = mkIf access.global.management {
|
||||
listen'.management = {
|
||||
port = access.managementPort;
|
||||
ssl = true;
|
||||
extraParameters = [ "default_server" ];
|
||||
};
|
||||
ssl = {
|
||||
force = true;
|
||||
cert.copyFromVhost = "unifi";
|
||||
};
|
||||
inherit name locations extraConfig kTLS;
|
||||
};
|
||||
unifi = {
|
||||
inherit name locations extraConfig kTLS;
|
||||
inherit name extraConfig kTLS;
|
||||
vouch.enable = mkDefault true;
|
||||
ssl.force = mkDefault true;
|
||||
locations."/" = {
|
||||
proxyPass = mkDefault (access.proxyUrlFor { serviceName = "unifi"; portName = "management"; });
|
||||
};
|
||||
};
|
||||
unifi'local = {
|
||||
inherit name locations extraConfig kTLS;
|
||||
inherit name extraConfig kTLS;
|
||||
ssl.cert.copyFromVhost = "unifi";
|
||||
local.enable = true;
|
||||
locations."/" = {
|
||||
proxyPass = mkDefault nginx.virtualHosts.unifi.locations."/".proxyPass;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
config.networking.firewall = {
|
||||
interfaces.local.allowedTCPPorts = [access.managementPort];
|
||||
allowedTCPPorts = mkIf access.global.management [access.managementPort];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,16 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
access,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||
inherit (lib.modules) mkIf mkMerge mkDefault;
|
||||
inherit (config) networking;
|
||||
inherit (config.services) tailscale nginx;
|
||||
cfg = config.services.vouch-proxy;
|
||||
in {
|
||||
config.services.nginx = {
|
||||
virtualHosts = let
|
||||
localVouchUrl = let
|
||||
inherit (cfg.settings.vouch) listen;
|
||||
host =
|
||||
if listen == "0.0.0.0" || listen == "[::]"
|
||||
then "localhost"
|
||||
else listen;
|
||||
in
|
||||
"http://${host}:${toString cfg.settings.vouch.port}";
|
||||
locations = {
|
||||
"/" = {
|
||||
ssl.force = true;
|
||||
|
|
@ -54,7 +47,9 @@ in {
|
|||
locations = mkMerge [
|
||||
locations
|
||||
{
|
||||
"/".proxyPass = mkIf cfg.enable (mkDefault localVouchUrl);
|
||||
"/".proxyPass = mkDefault (
|
||||
access.proxyUrlFor { serviceName = "vouch-proxy"; serviceId = "login"; }
|
||||
);
|
||||
}
|
||||
];
|
||||
};
|
||||
|
|
@ -73,7 +68,9 @@ in {
|
|||
locations = mkMerge [
|
||||
locations
|
||||
{
|
||||
"/".proxyPass = mkDefault nginx.virtualHosts.vouch.locations."/".proxyPass;
|
||||
"/".proxyPass = mkDefault (
|
||||
access.proxyUrlFor { serviceName = "vouch-proxy"; serviceId = "login.local"; }
|
||||
);
|
||||
}
|
||||
(localLocations "sso.local.${networking.domain}")
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
access,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
inherit (lib.modules) mkDefault;
|
||||
inherit (config.services) nginx zigbee2mqtt;
|
||||
name.shortServer = mkDefault "z2m";
|
||||
in {
|
||||
|
|
@ -12,8 +13,9 @@ in {
|
|||
zigbee2mqtt = {
|
||||
locations."/" = {
|
||||
proxy.websocket.enable = true;
|
||||
proxyPass = mkIf zigbee2mqtt.enable (
|
||||
mkDefault "http://localhost:${toString zigbee2mqtt.settings.frontend.port}"
|
||||
proxyPass = mkDefault (
|
||||
if zigbee2mqtt.enable then "http://localhost:${toString zigbee2mqtt.settings.frontend.port}"
|
||||
else access.proxyUrlFor { serviceName = "zigbee2mqtt"; }
|
||||
);
|
||||
};
|
||||
inherit name;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{config, lib, access, ...}: let
|
||||
{lib, access, ...}: let
|
||||
inherit (lib.modules) mkDefault;
|
||||
in {
|
||||
config = {
|
||||
|
|
@ -9,7 +9,7 @@ in {
|
|||
ipv6SendRAConfig = {
|
||||
Managed = mkDefault false;
|
||||
EmitDNS = mkDefault true;
|
||||
DNS = [ (access.getAddress6For "utsuho" "int") ];
|
||||
DNS = [ (access.systemForService "dnsmasq").access.address6ForNetwork.int ];
|
||||
# Domains = [ "int.${networking.domain}" ];
|
||||
EmitDomains = mkDefault false;
|
||||
RouterPreference = mkDefault "low";
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ in {
|
|||
invidious_hmac_key = commonSecret;
|
||||
};
|
||||
|
||||
networking.firewall.interfaces.local.allowedTCPPorts = [cfg.port];
|
||||
networking.firewall.interfaces.int.allowedTCPPorts = [cfg.port];
|
||||
users.groups.invidious = {};
|
||||
users.users.invidious = {
|
||||
isSystemUser = true;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ in {
|
|||
};
|
||||
|
||||
networking.firewall.interfaces.int.allowedTCPPorts = mkIf cfg.enable [
|
||||
(if cfg.sslCertificate != null then cfg.settings.https-port else cfg.settings.http-port)
|
||||
cfg.port
|
||||
];
|
||||
systemd.services.keycloak = mkIf cfg.enable {
|
||||
serviceConfig.DynamicUser = mkForce false;
|
||||
|
|
@ -52,7 +52,7 @@ in {
|
|||
|
||||
settings = {
|
||||
hostname = mkDefault (if hostname-strict then hostname else null);
|
||||
proxy = mkDefault (if cfg.sslCertificate != null then "reencrypt" else "edge");
|
||||
proxy = mkDefault (if cfg.protocol == "https" then "reencrypt" else "edge");
|
||||
hostname-strict = mkDefault hostname-strict;
|
||||
hostname-strict-https = mkDefault hostname-strict;
|
||||
proxy-headers = mkDefault "xforwarded";
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@ in {
|
|||
};
|
||||
gensokyo-zone = let
|
||||
toLdap = replaceStrings [ "idp." ] [ "ldap." ];
|
||||
lanName = access.getHostnameFor "freeipa" "lan";
|
||||
localName = access.getHostnameFor "freeipa" "local";
|
||||
system = access.systemForService "kerberos";
|
||||
lanName = access.getHostnameFor system.name "lan";
|
||||
localName = access.getHostnameFor system.name "local";
|
||||
ldapLan = toLdap lanName;
|
||||
ldapLocal = toLdap localName;
|
||||
in {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ in {
|
|||
networkConfig.MulticastDNS = true;
|
||||
};
|
||||
networking.nameservers' = mkIf enableDns (mkBefore [
|
||||
{ address = access.getAddressFor "utsuho" "lan"; }
|
||||
{ address = access.getAddressFor (access.systemForService "dnsmasq").name "lan"; }
|
||||
]);
|
||||
# prioritize our resolver over systemd-resolved!
|
||||
system.nssDatabases.hosts = let
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{ gensokyo-zone, access, config, lib, ... }: let
|
||||
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkIf mkBefore mkAfter mkDefault;
|
||||
inherit (lib.strings) replaceStrings;
|
||||
inherit (lib.lists) tail;
|
||||
inherit (lib.strings) splitString concatStringsSep;
|
||||
cfg = config.services.sssd;
|
||||
in {
|
||||
imports = [
|
||||
|
|
@ -12,29 +13,34 @@ in {
|
|||
services.sssd = {
|
||||
enable = (mkDefault true);
|
||||
gensokyo-zone = let
|
||||
toService = service: replaceStrings [ "idp." ] [ "${service}." ];
|
||||
serviceFragment = service: service;
|
||||
toService = service: hostname: let
|
||||
segments = splitString "." hostname;
|
||||
in concatStringsSep "." ([ (serviceFragment service) ] ++ tail segments);
|
||||
toFreeipa = toService "freeipa";
|
||||
toLdap = toService "ldap";
|
||||
lanName = access.getHostnameFor "freeipa" "lan";
|
||||
localName = access.getHostnameFor "freeipa" "local";
|
||||
tailName = access.getHostnameFor "hakurei" "tail";
|
||||
localToo = lanName != localName;
|
||||
servers = mkBefore [
|
||||
lanName
|
||||
(mkIf localToo localName)
|
||||
];
|
||||
backups = mkAlmostOptionDefault (mkAfter [
|
||||
(toFreeipa lanName)
|
||||
(mkIf config.services.tailscale.enable (toFreeipa tailName))
|
||||
]);
|
||||
in {
|
||||
krb5.servers = {
|
||||
inherit servers backups;
|
||||
mkServers = serviceName: let
|
||||
system = access.systemForService serviceName;
|
||||
lanName = access.getHostnameFor system.name "lan";
|
||||
localName = access.getHostnameFor system.name "local";
|
||||
localToo = lanName != localName;
|
||||
in {
|
||||
servers = mkBefore [
|
||||
lanName
|
||||
(mkIf localToo localName)
|
||||
];
|
||||
backups = mkAlmostOptionDefault (mkAfter [
|
||||
(toFreeipa lanName)
|
||||
(mkIf config.services.tailscale.enable (toFreeipa tailName))
|
||||
]);
|
||||
};
|
||||
in {
|
||||
krb5.servers = mkServers "kerberos";
|
||||
ipa.servers = mkServers "freeipa";
|
||||
ldap = {
|
||||
uris = {
|
||||
backups = mkAlmostOptionDefault (mkAfter [
|
||||
(mkIf config.services.tailscale.enable (toLdap tailName))
|
||||
(mkIf config.services.tailscale.enable (toService "ldap" tailName))
|
||||
]);
|
||||
};
|
||||
bind.passwordFile = mkIf (cfg.gensokyo-zone.backend == "ldap") config.sops.secrets.gensokyo-zone-peep-passwords.path;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf mkMerge mkDefault;
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
cfg = config.services.unifi;
|
||||
in {
|
||||
services.unifi = {
|
||||
|
|
@ -14,21 +14,25 @@ in {
|
|||
#mongodbPackage = mkDefault pkgs.mongodb-5_0;
|
||||
};
|
||||
|
||||
networking.firewall.interfaces.local = mkIf cfg.enable {
|
||||
allowedTCPPorts = mkMerge [
|
||||
[
|
||||
networking.firewall = mkIf cfg.enable {
|
||||
interfaces.int = {
|
||||
allowedTCPPorts = [
|
||||
8443 # remote login
|
||||
]
|
||||
(mkIf (!cfg.openFirewall) [
|
||||
];
|
||||
};
|
||||
interfaces.local = {
|
||||
allowedTCPPorts = mkIf (!cfg.openFirewall) [
|
||||
8080 # Port for UAP to inform controller.
|
||||
8880 # Port for HTTP portal redirect, if guest portal is enabled.
|
||||
8843 # Port for HTTPS portal redirect, ditto.
|
||||
6789 # Port for UniFi mobile speed test.
|
||||
])
|
||||
];
|
||||
];
|
||||
allowedUDPPorts = mkIf (!cfg.openFirewall) [
|
||||
10001 # UDP port used for device discovery.
|
||||
];
|
||||
};
|
||||
allowedUDPPorts = mkIf (!cfg.openFirewall) [
|
||||
3478 # UDP port used for STUN.
|
||||
10001 # UDP port used for device discovery.
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,9 @@ in {
|
|||
user = "z2m";
|
||||
password = "!secret z2m_pass";
|
||||
server = let
|
||||
utsuho = access.nixosFor "utsuho";
|
||||
mqttHost = access.getHostnameFor "utsuho" "lan";
|
||||
url = access.proxyUrlFor { serviceName = "mosquitto"; scheme = "mqtt"; };
|
||||
in mkIf (!config.services.mosquitto.enable) (
|
||||
assert utsuho.services.mosquitto.enable; mkAlmostDefault "mqtt://${mqttHost}:1883"
|
||||
mkAlmostDefault url
|
||||
);
|
||||
};
|
||||
homeassistant = true;
|
||||
|
|
|
|||
|
|
@ -7,5 +7,9 @@ _: {
|
|||
modules = [
|
||||
./nixos.nix
|
||||
];
|
||||
access.tailscale.enable = true;
|
||||
exports = {
|
||||
services = {
|
||||
tailscale.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
];
|
||||
specialArgs = {
|
||||
inherit name inputs std meta;
|
||||
inherit (inputs.self.lib) gensokyo-zone;
|
||||
};
|
||||
})
|
||||
(set.map (_: c: c) meta.systems);
|
||||
|
|
|
|||
|
|
@ -30,4 +30,11 @@ _: {
|
|||
mode = "0600";
|
||||
};
|
||||
};
|
||||
exports = {
|
||||
services = {
|
||||
freeipa.enable = true;
|
||||
ldap.enable = true;
|
||||
kerberos.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,9 @@ _: {
|
|||
};
|
||||
};
|
||||
};
|
||||
exports = {
|
||||
services = {
|
||||
freepbx.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,19 @@ _: {
|
|||
};
|
||||
};
|
||||
access = {
|
||||
tailscale.enable = true;
|
||||
global.enable = true;
|
||||
};
|
||||
exports = {
|
||||
services = {
|
||||
tailscale.enable = true;
|
||||
samba.enable = true;
|
||||
vouch-proxy = {
|
||||
enable = true;
|
||||
id = "login.local";
|
||||
};
|
||||
};
|
||||
exports = {
|
||||
plex.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,16 +3,11 @@
|
|||
meta,
|
||||
lib,
|
||||
access,
|
||||
gensokyo-zone,
|
||||
...
|
||||
}: let
|
||||
inherit (gensokyo-zone.lib) mkAddress6;
|
||||
inherit (lib.modules) mkIf mkMerge;
|
||||
keycloak = access.nixosFor "keycloak";
|
||||
mediabox = access.nixosFor "mediabox";
|
||||
tei = access.nixosFor "tei";
|
||||
utsuho = access.nixosFor "utsuho";
|
||||
inherit (mediabox.services) plex;
|
||||
inherit (tei.services) home-assistant zigbee2mqtt;
|
||||
inherit (utsuho.services) unifi mosquitto;
|
||||
inherit (config.services) nginx;
|
||||
inherit (nginx) virtualHosts;
|
||||
in {
|
||||
|
|
@ -218,29 +213,8 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
services.nginx = let
|
||||
inherit (nginx) access;
|
||||
#inherit (config.lib.access) getHostnameFor;
|
||||
getHostnameFor = config.lib.access.getAddress4For;
|
||||
in {
|
||||
services.nginx = {
|
||||
vouch.enableLocal = false;
|
||||
access.mosquitto = assert mosquitto.enable; {
|
||||
host = getHostnameFor "utsuho" "lan";
|
||||
};
|
||||
access.plex = assert plex.enable; {
|
||||
url = "http://${getHostnameFor "mediabox" "lan"}:${toString plex.port}";
|
||||
externalPort = 41324;
|
||||
};
|
||||
access.unifi = assert unifi.enable; {
|
||||
host = getHostnameFor "utsuho" "lan";
|
||||
};
|
||||
access.freeipa = {
|
||||
host = getHostnameFor "freeipa" "lan";
|
||||
kerberos.ports.kpasswd = 464;
|
||||
};
|
||||
access.kitchencam = {
|
||||
streamPort = 41081;
|
||||
};
|
||||
stream.servers = {
|
||||
mosquitto.ssl.cert.name = "mosquitto";
|
||||
};
|
||||
|
|
@ -254,18 +228,11 @@ in {
|
|||
# we're not the real sso record-holder, so don't respond globally..
|
||||
local.denyGlobal = true;
|
||||
ssl.cert.enable = true;
|
||||
locations."/".proxyPass = "https://${getHostnameFor "keycloak" "lan"}:8443";
|
||||
};
|
||||
vouch = let
|
||||
inherit (keycloak.services) vouch-proxy;
|
||||
in assert vouch-proxy.enable; {
|
||||
vouch = {
|
||||
ssl.cert.enable = true;
|
||||
locations."/".proxyPass = "http://${getHostnameFor "keycloak" "lan"}:${toString vouch-proxy.settings.vouch.port}";
|
||||
};
|
||||
vouch'local = let
|
||||
vouch-proxy = config.services.vouch-proxy;
|
||||
in assert vouch-proxy.enable; {
|
||||
locations."/".proxyPass = "http://localhost:${toString vouch-proxy.settings.vouch.port}";
|
||||
vouch'local = {
|
||||
# we're not running another for tailscale sorry...
|
||||
name.includeTailscale = true;
|
||||
};
|
||||
|
|
@ -274,29 +241,27 @@ in {
|
|||
local.denyGlobal = true;
|
||||
ssl.cert.enable = true;
|
||||
};
|
||||
home-assistant = assert home-assistant.enable; {
|
||||
home-assistant = {
|
||||
# not the real hass record-holder, so don't respond globally..
|
||||
local.denyGlobal = true;
|
||||
ssl.cert.enable = true;
|
||||
locations."/".proxyPass = "http://${getHostnameFor "tei" "lan"}:${toString home-assistant.config.http.server_port}";
|
||||
};
|
||||
zigbee2mqtt = assert zigbee2mqtt.enable; {
|
||||
zigbee2mqtt = {
|
||||
# not the real z2m record-holder, so don't respond globally..
|
||||
local.denyGlobal = true;
|
||||
ssl.cert.enable = true;
|
||||
locations."/".proxyPass = "http://${getHostnameFor "tei" "lan"}:${toString zigbee2mqtt.settings.frontend.port}";
|
||||
};
|
||||
grocy = {
|
||||
# not the real grocy record-holder, so don't respond globally..
|
||||
local.denyGlobal = true;
|
||||
ssl.cert.enable = true;
|
||||
locations."/".proxyPass = "http://${getHostnameFor "tei" "lan"}";
|
||||
locations."/".proxyPass = "http://${mkAddress6 (access.getAddressFor "tei" "lan")}";
|
||||
};
|
||||
barcodebuddy = {
|
||||
# not the real bbuddy record-holder, so don't respond globally..
|
||||
local.denyGlobal = true;
|
||||
ssl.cert.enable = true;
|
||||
locations."/".proxyPass = "http://${getHostnameFor "tei" "lan"}";
|
||||
locations."/".proxyPass = "http://${mkAddress6 (access.getAddressFor "tei" "lan")}";
|
||||
};
|
||||
freepbx = {
|
||||
ssl.cert.enable = true;
|
||||
|
|
@ -305,14 +270,17 @@ in {
|
|||
proxied.enable = "cloudflared";
|
||||
ssl.cert.enable = true;
|
||||
};
|
||||
plex.ssl.cert.enable = true;
|
||||
plex = {
|
||||
ssl.cert.enable = true;
|
||||
listen'.external = {
|
||||
enable = true;
|
||||
port = 41324;
|
||||
};
|
||||
};
|
||||
kitchencam.ssl.cert.enable = true;
|
||||
invidious = {
|
||||
ssl.cert.enable = true;
|
||||
};
|
||||
invidious'int = {
|
||||
locations."/".proxyPass = "http://${getHostnameFor "mediabox" "lan"}:${toString mediabox.services.invidious.port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
services.samba.tls = {
|
||||
|
|
|
|||
|
|
@ -7,5 +7,10 @@ _: {
|
|||
modules = [
|
||||
./nixos.nix
|
||||
];
|
||||
access.tailscale.enable = true;
|
||||
exports = {
|
||||
services = {
|
||||
keycloak.enable = true;
|
||||
vouch-proxy.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{meta, config, ...}: {
|
||||
{meta, config, access, ...}: {
|
||||
imports = let
|
||||
inherit (meta) nixos;
|
||||
in [
|
||||
|
|
@ -13,21 +13,25 @@
|
|||
|
||||
services.cloudflared = let
|
||||
tunnelId = "c9a4b8c9-42d9-4566-8cff-eb63ca26809d";
|
||||
inherit (config.services) keycloak vouch-proxy;
|
||||
in {
|
||||
tunnels.${tunnelId} = {
|
||||
default = "http_status:404";
|
||||
credentialsFile = config.sops.secrets.cloudflared-tunnel-keycloak.path;
|
||||
ingress = let
|
||||
keycloakHost = if keycloak.settings.hostname != null then keycloak.settings.hostname else "sso.${config.networking.domain}";
|
||||
keyCloakScheme = if keycloak.sslCertificate != null then "https" else "http";
|
||||
keycloakPort = keycloak.settings."${keyCloakScheme}-port";
|
||||
keycloak'system = access.systemForService "keycloak";
|
||||
inherit (keycloak'system.exports.services) keycloak;
|
||||
vouch'system = access.systemForServiceId "login";
|
||||
inherit (vouch'system.exports.services) vouch-proxy;
|
||||
in {
|
||||
${keycloakHost} = assert keycloak.enable; {
|
||||
service = "${keyCloakScheme}://localhost:${toString keycloakPort}";
|
||||
originRequest.${if keyCloakScheme == "https" then "noTLSVerify" else null} = true;
|
||||
"${keycloak.id}.${config.networking.domain}" = let
|
||||
portName = if keycloak.ports.https.enable then "https" else "http";
|
||||
in {
|
||||
service = access.proxyUrlFor { system = keycloak'system; service = keycloak; inherit portName; };
|
||||
originRequest.${if keycloak.ports.${portName}.protocol == "https" then "noTLSVerify" else null} = true;
|
||||
};
|
||||
"${vouch-proxy.id}.${config.networking.domain}" = {
|
||||
service = access.proxyUrlFor { system = vouch'system; service = vouch-proxy; };
|
||||
};
|
||||
${vouch-proxy.domain}.service = assert vouch-proxy.enable; "http://localhost:${toString vouch-proxy.settings.vouch.port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,4 +15,13 @@ _: {
|
|||
address6 = "fd0a::ba27:ebff:fea8:f4ff";
|
||||
};
|
||||
};
|
||||
exports = {
|
||||
services = {
|
||||
motion = {
|
||||
id = "kitchen";
|
||||
enable = true;
|
||||
ports.stream.port = 41081;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,5 +7,9 @@ _: {
|
|||
modules = [
|
||||
./nixos.nix
|
||||
];
|
||||
access.tailscale.enable = true;
|
||||
exports = {
|
||||
services = {
|
||||
tailscale.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,10 @@ _: {
|
|||
modules = [
|
||||
./nixos.nix
|
||||
];
|
||||
exports = {
|
||||
services = {
|
||||
plex.enable = true;
|
||||
invidious.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,5 +7,10 @@ _: {
|
|||
modules = [
|
||||
./nixos.nix
|
||||
];
|
||||
access.tailscale.enable = true;
|
||||
exports = {
|
||||
services = {
|
||||
tailscale.enable = true;
|
||||
nfs.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,4 +10,9 @@ _: {
|
|||
address6 = "fd0c::2";
|
||||
};
|
||||
};
|
||||
exports = {
|
||||
services = {
|
||||
proxmox.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,46 +1,14 @@
|
|||
{
|
||||
access,
|
||||
config,
|
||||
lib,
|
||||
access,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.attrsets) listToAttrs nameValuePair;
|
||||
inherit (access) nixosFor;
|
||||
inherit (config.networking) hostName;
|
||||
inherit (config.services) nginx;
|
||||
inherit (config.services) home-assistant nginx;
|
||||
cfg = config.services.cloudflared;
|
||||
apartment = "5e85d878-c6b2-4b15-b803-9aeb63d63543";
|
||||
accessHostFor = {
|
||||
hostName,
|
||||
system ? nixosFor hostName,
|
||||
network ? "lan",
|
||||
...
|
||||
}: let
|
||||
host = access.getHostnameFor hostName network;
|
||||
in
|
||||
if hostName == config.networking.hostName
|
||||
then "localhost"
|
||||
else host;
|
||||
ingressForNginx = {
|
||||
host ? system.networking.fqdn,
|
||||
port ? 80,
|
||||
hostName,
|
||||
system ? nixosFor hostName,
|
||||
} @ args:
|
||||
nameValuePair host {
|
||||
service = "http://${accessHostFor args}:${toString port}";
|
||||
};
|
||||
ingressForHass = {
|
||||
host ? system.services.home-assistant.domain,
|
||||
port ? system.services.home-assistant.config.http.server_port,
|
||||
hostName,
|
||||
system ? nixosFor hostName,
|
||||
...
|
||||
} @ args:
|
||||
nameValuePair host {
|
||||
service = "http://${accessHostFor args}:${toString port}";
|
||||
};
|
||||
localNginx = "http://localhost:${toString nginx.defaultHTTPListenPort}";
|
||||
in {
|
||||
sops.secrets.cloudflared-tunnel-apartment.owner = cfg.user;
|
||||
services.cloudflared = {
|
||||
|
|
@ -48,21 +16,20 @@ in {
|
|||
${apartment} = {
|
||||
credentialsFile = config.sops.secrets.cloudflared-tunnel-apartment.path;
|
||||
default = "http_status:404";
|
||||
ingress = listToAttrs [
|
||||
(ingressForNginx {
|
||||
host = nginx.virtualHosts.zigbee2mqtt.serverName;
|
||||
inherit hostName;
|
||||
})
|
||||
(ingressForNginx {
|
||||
host = nginx.virtualHosts.grocy.serverName;
|
||||
inherit hostName;
|
||||
})
|
||||
(ingressForNginx {
|
||||
host = nginx.virtualHosts.barcodebuddy.serverName;
|
||||
inherit hostName;
|
||||
})
|
||||
(ingressForHass {inherit hostName;})
|
||||
];
|
||||
ingress = {
|
||||
${nginx.virtualHosts.zigbee2mqtt.serverName} = {
|
||||
service = localNginx;
|
||||
};
|
||||
${nginx.virtualHosts.grocy.serverName} = {
|
||||
service = localNginx;
|
||||
};
|
||||
${nginx.virtualHosts.barcodebuddy.serverName} = {
|
||||
service = localNginx;
|
||||
};
|
||||
${home-assistant.domain} = assert home-assistant.enable; {
|
||||
service = access.proxyUrlFor { serviceName = "home-assistant"; };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,5 +7,12 @@ _: {
|
|||
modules = [
|
||||
./nixos.nix
|
||||
];
|
||||
access.tailscale.enable = true;
|
||||
exports = {
|
||||
services = {
|
||||
tailscale.enable = true;
|
||||
home-assistant.enable = true;
|
||||
zigbee2mqtt.enable = true;
|
||||
postgresql.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,11 @@ _: {
|
|||
modules = [
|
||||
./nixos.nix
|
||||
];
|
||||
exports = {
|
||||
services = {
|
||||
unifi.enable = true;
|
||||
mosquitto.enable = true;
|
||||
dnsmasq.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ in {
|
|||
];
|
||||
|
||||
services.cloudflared = let
|
||||
inherit (config.services) unifi;
|
||||
inherit (nginx) virtualHosts defaultHTTPListenPort;
|
||||
tunnelId = "28bcd3fc-3467-4997-806b-546ba9995028";
|
||||
localNginx = "http://localhost:${toString defaultHTTPListenPort}";
|
||||
|
|
@ -27,7 +26,7 @@ in {
|
|||
default = "http_status:404";
|
||||
credentialsFile = config.sops.secrets.cloudflared-tunnel-utsuho.path;
|
||||
ingress = {
|
||||
${virtualHosts.unifi.serverName} = assert unifi.enable; {
|
||||
${virtualHosts.unifi.serverName} = {
|
||||
service = localNginx;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ module "tewi" {
|
|||
zone_id = cloudflare_zone.gensokyo-zone_zone.id
|
||||
subdomains = [
|
||||
"home",
|
||||
"id",
|
||||
"z2m",
|
||||
"grocy",
|
||||
"bbuddy",
|
||||
|
|
|
|||
1
tree.nix
1
tree.nix
|
|
@ -67,6 +67,7 @@
|
|||
"modules/system/network".functor.enable = true;
|
||||
"modules/system/proxmox".functor.enable = true;
|
||||
"modules/system/extern".functor.enable = true;
|
||||
"modules/system/exports".functor.enable = true;
|
||||
"modules/home".functor.enable = true;
|
||||
"modules/type".functor.enable = true;
|
||||
"modules/extern/home".functor.enable = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue