mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 04:19:19 -08:00
refactor(nginx): ssl module
This commit is contained in:
parent
69c014b24e
commit
a7e35fbc88
28 changed files with 794 additions and 546 deletions
71
modules/nixos/nginx/listen.nix
Normal file
71
modules/nixos/nginx/listen.nix
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
|
inherit (lib.modules) mkIf mkDefault mkOptionDefault mkForce mkOverride;
|
||||||
|
inherit (lib.attrsets) mapAttrsToList filterAttrs removeAttrs;
|
||||||
|
inherit (lib.lists) concatMap;
|
||||||
|
mkAlmostOptionDefault = mkOverride 1250;
|
||||||
|
inherit (config.services) nginx;
|
||||||
|
extraListenAttrs = [ "enable" ];
|
||||||
|
listenModule = { config, virtualHost, ... }: {
|
||||||
|
options = with lib.types; {
|
||||||
|
enable = mkEnableOption "this port" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
ssl = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
port = mkOption {
|
||||||
|
type = nullOr port;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
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
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
hostModule = { config, ... }: let
|
||||||
|
cfg = config.listenPorts;
|
||||||
|
enabledPorts = filterAttrs (_: port: port.enable) cfg;
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
listenPorts = mkOption {
|
||||||
|
type = attrsOf (submoduleWith {
|
||||||
|
modules = [ listenModule ];
|
||||||
|
specialArgs = {
|
||||||
|
virtualHost = config;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
services.nginx.virtualHosts = mkOption {
|
||||||
|
type = attrsOf (submoduleWith {
|
||||||
|
modules = [ hostModule ];
|
||||||
|
shorthandOnlyDefinesConfig = true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
enable = mkOptionDefault virtualHost.local.enable;
|
enable = mkOptionDefault virtualHost.local.enable;
|
||||||
denyGlobal = mkOptionDefault virtualHost.local.denyGlobal;
|
denyGlobal = mkOptionDefault virtualHost.local.denyGlobal;
|
||||||
trusted = mkOptionDefault virtualHost.local.trusted;
|
trusted = mkOptionDefault virtualHost.local.trusted;
|
||||||
emitDenyGlobal = virtualHost.local.emitDenyGlobal;
|
emitDenyGlobal = config.local.denyGlobal && !virtualHost.local.emitDenyGlobal;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
hostModule = {config, ...}: {
|
hostModule = {config, ...}: {
|
||||||
|
|
|
||||||
69
modules/nixos/nginx/name.nix
Normal file
69
modules/nixos/nginx/name.nix
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.options) mkOption;
|
||||||
|
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
||||||
|
inherit (lib.strings) optionalString;
|
||||||
|
inherit (config.services) tailscale;
|
||||||
|
inherit (config) networking;
|
||||||
|
hostModule = {config, ...}: let
|
||||||
|
cfg = config.name;
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
name = {
|
||||||
|
shortServer = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
qualifier = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
};
|
||||||
|
includeLocal = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
includeTailscale = mkOption {
|
||||||
|
type = bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
allServerNames = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
name = {
|
||||||
|
qualifier = mkOptionDefault (
|
||||||
|
if config.local.enable then "local"
|
||||||
|
else null
|
||||||
|
);
|
||||||
|
includeTailscale = mkOptionDefault (
|
||||||
|
config.local.enable && tailscale.enable && cfg.qualifier != "tail"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
serverName = mkIf (cfg.shortServer != null) (mkDefault (
|
||||||
|
cfg.shortServer
|
||||||
|
+ optionalString (cfg.qualifier != null) ".${cfg.qualifier}"
|
||||||
|
+ ".${networking.domain}"
|
||||||
|
));
|
||||||
|
serverAliases = mkIf (cfg.shortServer != null) (mkDefault [
|
||||||
|
(mkIf cfg.includeLocal "${cfg.shortServer}.local.${networking.domain}")
|
||||||
|
(mkIf cfg.includeTailscale "${cfg.shortServer}.tail.${networking.domain}")
|
||||||
|
]);
|
||||||
|
allServerNames = mkOptionDefault (
|
||||||
|
[ config.serverName ] ++ config.serverAliases
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
services.nginx.virtualHosts = mkOption {
|
||||||
|
type = attrsOf (submoduleWith {
|
||||||
|
modules = [hostModule];
|
||||||
|
shorthandOnlyDefinesConfig = true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
204
modules/nixos/nginx/proxied.nix
Normal file
204
modules/nixos/nginx/proxied.nix
Normal file
|
|
@ -0,0 +1,204 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
|
inherit (lib.modules) mkIf mkMerge mkBefore mkAfter mkOrder mkDefault mkOptionDefault mkOverride;
|
||||||
|
inherit (lib.strings) optionalString splitString match;
|
||||||
|
inherit (lib.attrsets) attrValues;
|
||||||
|
inherit (lib.lists) length head /*optional*/ any;
|
||||||
|
inherit (lib.trivial) mapNullable;
|
||||||
|
#inherit (config) networking;
|
||||||
|
inherit (config.services) nginx;
|
||||||
|
mkAlmostAfter = mkOrder 1250;
|
||||||
|
mkAlmostOptionDefault = mkOverride 1250;
|
||||||
|
schemeForUrl = url: let
|
||||||
|
parts = splitString ":" url;
|
||||||
|
in if length parts == 1 then null else head parts;
|
||||||
|
pathForUrl = url: let
|
||||||
|
parts = match ''[^:]+://[^/]+(.*)'' url;
|
||||||
|
in if parts == null then null else head parts;
|
||||||
|
hostForUrl = url: let
|
||||||
|
parts = match ''[^:]+://([^/]+).*'' url;
|
||||||
|
in if parts == null then null else head parts;
|
||||||
|
xHeadersDefaults = ''
|
||||||
|
set $x_scheme $scheme;
|
||||||
|
set $x_forwarded_for $remote_addr;
|
||||||
|
set $x_remote_addr $remote_addr;
|
||||||
|
set $x_forwarded_host $host;
|
||||||
|
set $x_forwarded_server $host;
|
||||||
|
set $x_host $host;
|
||||||
|
set $x_referer $http_referer;
|
||||||
|
set $x_proxy_host $x_host;
|
||||||
|
'';
|
||||||
|
xHeadersProxied = ''
|
||||||
|
set $x_forwarded_for $proxy_add_x_forwarded_for;
|
||||||
|
if ($http_x_forwarded_proto) {
|
||||||
|
set $x_scheme $http_x_forwarded_proto;
|
||||||
|
}
|
||||||
|
if ($http_x_real_ip) {
|
||||||
|
set $x_remote_addr $http_x_real_ip;
|
||||||
|
}
|
||||||
|
if ($http_x_forwarded_host) {
|
||||||
|
set $x_forwarded_host $http_x_forwarded_host;
|
||||||
|
}
|
||||||
|
if ($http_x_forwarded_server) {
|
||||||
|
set $x_forwarded_server $http_x_forwarded_server;
|
||||||
|
}
|
||||||
|
if ($x_referer ~ "^https?://([^/]*)/(.*)$") {
|
||||||
|
set $x_referer_host $1;
|
||||||
|
set $x_referer_path $2;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
locationModule = { config, virtualHost, ... }: let
|
||||||
|
cfg = config.proxied;
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
proxied = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = enum [ false true "cloudflared" ];
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
enabled = mkOption {
|
||||||
|
type = bool;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
xvars.enable = mkEnableOption "$x_variables";
|
||||||
|
redirectScheme = mkEnableOption "redirect to X-Forwarded-Proto" // {
|
||||||
|
default = cfg.enabled;
|
||||||
|
};
|
||||||
|
rewriteReferer = mkEnableOption "rewrite Referer header" // {
|
||||||
|
default = cfg.enabled;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
proxy = {
|
||||||
|
enabled = mkOption {
|
||||||
|
type = bool;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
scheme = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
};
|
||||||
|
path = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
};
|
||||||
|
host = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
};
|
||||||
|
headers.enableRecommended = mkOption {
|
||||||
|
type = enum [ true false "nixpkgs" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
force = mkEnableOption "redirect to SSL";
|
||||||
|
};
|
||||||
|
config = let
|
||||||
|
emitVars = cfg.enabled && !virtualHost.proxied.enabled;
|
||||||
|
emitRedirectScheme = config.proxy.enabled && cfg.redirectScheme;
|
||||||
|
emitRefererRewrite = config.proxy.enabled && cfg.rewriteReferer;
|
||||||
|
emitHeaders = config.proxy.enabled && config.proxy.headers.enableRecommended == true;
|
||||||
|
in {
|
||||||
|
proxied = {
|
||||||
|
enabled = mkOptionDefault (virtualHost.proxied.enabled || cfg.enable != false);
|
||||||
|
xvars.enable = mkIf (cfg.enabled || emitRedirectScheme || emitHeaders) true;
|
||||||
|
};
|
||||||
|
proxy = {
|
||||||
|
enabled = mkOptionDefault (config.proxyPass != null);
|
||||||
|
headers.enableRecommended = mkOptionDefault (
|
||||||
|
if !virtualHost.recommendedProxySettings then false
|
||||||
|
else if cfg.enabled then true
|
||||||
|
else "nixpkgs"
|
||||||
|
);
|
||||||
|
scheme = mkOptionDefault (
|
||||||
|
mapNullable schemeForUrl config.proxyPass
|
||||||
|
);
|
||||||
|
path = mkOptionDefault (
|
||||||
|
mapNullable pathForUrl config.proxyPass
|
||||||
|
);
|
||||||
|
host = mkOptionDefault (
|
||||||
|
mapNullable hostForUrl config.proxyPass
|
||||||
|
);
|
||||||
|
};
|
||||||
|
recommendedProxySettings = mkMerge [
|
||||||
|
(mkAlmostOptionDefault (config.proxy.headers.enableRecommended == "nixpkgs"))
|
||||||
|
];
|
||||||
|
extraConfig = mkMerge [
|
||||||
|
(mkIf emitVars (
|
||||||
|
mkBefore xHeadersProxied
|
||||||
|
))
|
||||||
|
(mkIf emitRedirectScheme ''
|
||||||
|
proxy_redirect ${config.proxy.scheme}://$host/ $x_scheme://$host/;
|
||||||
|
'')
|
||||||
|
(mkIf emitRefererRewrite ''
|
||||||
|
if ($x_referer_host = $host) {
|
||||||
|
set $x_referer "${config.proxy.scheme}://${config.proxy.host}/$x_referer_path";
|
||||||
|
}
|
||||||
|
'')
|
||||||
|
(mkIf emitHeaders (mkAlmostAfter ''
|
||||||
|
if ($x_proxy_host = "") {
|
||||||
|
set $x_proxy_host $proxy_host;
|
||||||
|
}
|
||||||
|
if ($x_proxy_host = "") {
|
||||||
|
set $x_proxy_host ${config.proxy.host};
|
||||||
|
}
|
||||||
|
proxy_set_header Host $x_proxy_host;
|
||||||
|
proxy_set_header Referer $x_referer;
|
||||||
|
proxy_set_header X-Real-IP $x_remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $x_scheme;
|
||||||
|
proxy_set_header X-Forwarded-Host $x_forwarded_host;
|
||||||
|
proxy_set_header X-Forwarded-Server $x_forwarded_server;
|
||||||
|
''))
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
hostModule = { config, ... }: let
|
||||||
|
cfg = config.proxied;
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
proxied = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = enum [ false true "cloudflared" ];
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
enabled = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = cfg.enable != false;
|
||||||
|
};
|
||||||
|
xvars.enable = mkEnableOption "$x_variables" // {
|
||||||
|
default = cfg.enabled;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
recommendedProxySettings = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = nginx.recommendedProxySettings;
|
||||||
|
};
|
||||||
|
locations = mkOption {
|
||||||
|
type = attrsOf (submoduleWith {
|
||||||
|
modules = [ locationModule ];
|
||||||
|
shorthandOnlyDefinesConfig = true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
proxied = {
|
||||||
|
xvars.enable = mkIf (any (loc: loc.proxied.xvars.enable) (attrValues config.locations)) true;
|
||||||
|
};
|
||||||
|
local.denyGlobal = mkIf (cfg.enable == "cloudflared") (mkDefault true);
|
||||||
|
extraConfig = mkIf cfg.xvars.enable (mkBefore ''
|
||||||
|
${xHeadersDefaults}
|
||||||
|
${optionalString cfg.enabled xHeadersProxied}
|
||||||
|
'');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
services.nginx.virtualHosts = mkOption {
|
||||||
|
type = attrsOf (submoduleWith {
|
||||||
|
modules = [ hostModule ];
|
||||||
|
shorthandOnlyDefinesConfig = true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
92
modules/nixos/nginx/ssl.nix
Normal file
92
modules/nixos/nginx/ssl.nix
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
|
inherit (lib.modules) mkIf mkDefault mkOptionDefault mkOverride;
|
||||||
|
mkAlmostOptionDefault = mkOverride 1250;
|
||||||
|
forceRedirectConfig = virtualHost: ''
|
||||||
|
if ($x_scheme = http) {
|
||||||
|
return ${toString virtualHost.redirectCode} https://$host$request_uri;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
locationModule = { config, virtualHost, ... }: let
|
||||||
|
cfg = config.ssl;
|
||||||
|
emitForce = cfg.force && !virtualHost.ssl.forced;
|
||||||
|
in {
|
||||||
|
options.ssl = {
|
||||||
|
force = mkEnableOption "redirect to SSL";
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
proxied.xvars.enable = mkIf emitForce true;
|
||||||
|
extraConfig = mkIf emitForce (forceRedirectConfig virtualHost);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
hostModule = { config, name, ... }: let
|
||||||
|
cfg = config.ssl;
|
||||||
|
emitForce = cfg.forced && config.proxied.enabled;
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
ssl = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = bool;
|
||||||
|
};
|
||||||
|
force = mkOption {
|
||||||
|
# TODO: "force-nonlocal"? exceptions for tailscale?
|
||||||
|
type = enum [ false true "only" "reject" ];
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
forced = mkOption {
|
||||||
|
type = bool;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
cert = {
|
||||||
|
name = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
keyPath = mkOption {
|
||||||
|
type = nullOr path;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
path = mkOption {
|
||||||
|
type = nullOr path;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
locations = mkOption {
|
||||||
|
type = attrsOf (submoduleWith {
|
||||||
|
modules = [ locationModule ];
|
||||||
|
shorthandOnlyDefinesConfig = true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
ssl = {
|
||||||
|
enable = mkOptionDefault (cfg.cert.name != null || cfg.cert.keyPath != null);
|
||||||
|
forced = mkOptionDefault (cfg.force != false && cfg.force != "reject");
|
||||||
|
};
|
||||||
|
addSSL = mkIf (cfg.enable && (cfg.force == false || emitForce)) (mkDefault true);
|
||||||
|
forceSSL = mkIf (cfg.enable && cfg.force == true && !emitForce) (mkDefault true);
|
||||||
|
onlySSL = mkIf (cfg.enable && cfg.force == "only" && !emitForce) (mkDefault true);
|
||||||
|
rejectSSL = mkIf (cfg.force == "reject") (mkDefault true);
|
||||||
|
useACMEHost = mkAlmostOptionDefault cfg.cert.name;
|
||||||
|
sslCertificate = mkIf (cfg.cert.path != null) (mkAlmostOptionDefault cfg.cert.path);
|
||||||
|
sslCertificateKey = mkIf (cfg.cert.keyPath != null) (mkAlmostOptionDefault cfg.cert.keyPath);
|
||||||
|
|
||||||
|
proxied.xvars.enable = mkIf emitForce true;
|
||||||
|
extraConfig = mkIf emitForce (forceRedirectConfig config);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
services.nginx.virtualHosts = mkOption {
|
||||||
|
type = attrsOf (submoduleWith {
|
||||||
|
modules = [ hostModule ];
|
||||||
|
shorthandOnlyDefinesConfig = true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -6,11 +6,123 @@
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
|
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
|
||||||
inherit (config) networking;
|
inherit (config) networking;
|
||||||
inherit (config.services) vouch-proxy tailscale;
|
inherit (config.services) vouch-proxy nginx tailscale;
|
||||||
vouchModule = {config, ...}: {
|
inherit (nginx) vouch;
|
||||||
|
locationModule = {config, virtualHost, ...}: {
|
||||||
|
options.vouch = with lib.types; {
|
||||||
|
requireAuth = mkEnableOption "require auth to access this location";
|
||||||
|
};
|
||||||
|
config = mkIf config.vouch.requireAuth {
|
||||||
|
proxied.xvars.enable = true;
|
||||||
|
extraConfig = assert virtualHost.vouch.enable; mkMerge [
|
||||||
|
''
|
||||||
|
add_header Access-Control-Allow-Origin ${vouch.url};
|
||||||
|
add_header Access-Control-Allow-Origin ${vouch.authUrl};
|
||||||
|
''
|
||||||
|
(mkIf (vouch.localSso.enable && config.local.enable) ''
|
||||||
|
add_header Access-Control-Allow-Origin ${vouch.localUrl};
|
||||||
|
'')
|
||||||
|
(mkIf (vouch.localSso.enable && config.local.enable && tailscale.enable) ''
|
||||||
|
add_header Access-Control-Allow-Origin $x_scheme://${vouch.tailDomain};
|
||||||
|
'')
|
||||||
|
''
|
||||||
|
proxy_set_header X-Vouch-User $auth_resp_x_vouch_user;
|
||||||
|
''
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
hostModule = {config, ...}: let
|
||||||
|
cfg = config.vouch;
|
||||||
|
in {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
|
locations = mkOption {
|
||||||
|
type = attrsOf (submodule locationModule);
|
||||||
|
};
|
||||||
vouch = {
|
vouch = {
|
||||||
enable = mkEnableOption "vouch auth proxy";
|
enable = mkEnableOption "vouch auth proxy";
|
||||||
|
requireAuth = mkEnableOption "require auth to access this host" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
errorLocation = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "@error401";
|
||||||
|
};
|
||||||
|
authRequestLocation = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "/validate";
|
||||||
|
};
|
||||||
|
authRequestDirective = mkOption {
|
||||||
|
type = lines;
|
||||||
|
default = ''
|
||||||
|
auth_request ${cfg.authRequestLocation};
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
extraConfig = mkIf (cfg.enable && cfg.requireAuth) ''
|
||||||
|
${cfg.authRequestDirective}
|
||||||
|
error_page 401 = ${cfg.errorLocation};
|
||||||
|
'';
|
||||||
|
locations = mkIf cfg.enable {
|
||||||
|
"/" = mkIf cfg.requireAuth {
|
||||||
|
vouch.requireAuth = true;
|
||||||
|
};
|
||||||
|
${cfg.errorLocation} = {
|
||||||
|
proxied.xvars.enable = true;
|
||||||
|
extraConfig = let
|
||||||
|
localVouchUrl = ''
|
||||||
|
if ($x_forwarded_host ~ "\.local\.${networking.domain}$") {
|
||||||
|
set $vouch_url ${vouch.localUrl};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
tailVouchUrl = ''
|
||||||
|
if ($x_forwarded_host ~ "\.tail\.${networking.domain}$") {
|
||||||
|
set $vouch_url $x_scheme://${vouch.tailDomain};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
mkMerge [
|
||||||
|
(mkBefore ''
|
||||||
|
set $vouch_url ${vouch.url};
|
||||||
|
'')
|
||||||
|
(mkIf (vouch.localSso.enable && config.local.enable or false) localVouchUrl)
|
||||||
|
(mkIf (vouch.localSso.enable && config.local.enable or false && tailscale.enable) tailVouchUrl)
|
||||||
|
''
|
||||||
|
return 302 $vouch_url/login?url=$x_scheme://$x_forwarded_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
|
||||||
|
''
|
||||||
|
];
|
||||||
|
};
|
||||||
|
${cfg.authRequestLocation} = {
|
||||||
|
proxyPass = "${vouch.proxyOrigin}/validate";
|
||||||
|
proxy.headers.enableRecommended = true;
|
||||||
|
extraConfig = let
|
||||||
|
# nginx-proxied vouch must use X-Forwarded-Host, but vanilla vouch requires Host
|
||||||
|
vouchProxyHost = if vouch.doubleProxy
|
||||||
|
then "''"
|
||||||
|
else "$x_forwarded_host";
|
||||||
|
in ''
|
||||||
|
set $x_proxy_host ${vouchProxyHost};
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
proxy_set_header Content-Length "";
|
||||||
|
auth_request_set $auth_resp_x_vouch_user $upstream_http_x_vouch_user;
|
||||||
|
auth_request_set $auth_resp_jwt $upstream_http_x_vouch_jwt;
|
||||||
|
auth_request_set $auth_resp_err $upstream_http_x_vouch_err;
|
||||||
|
auth_request_set $auth_resp_failcount $upstream_http_x_vouch_failcount;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
services.nginx = {
|
||||||
|
vouch = {
|
||||||
|
enable = mkEnableOption "vouch auth proxy";
|
||||||
|
localSso = {
|
||||||
|
# NOTE: this won't work without multiple vouch-proxy instances with different auth urls...
|
||||||
|
enable = mkEnableOption "lan-local auth";
|
||||||
|
};
|
||||||
proxyOrigin = mkOption {
|
proxyOrigin = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "https://login.local.${networking.domain}";
|
default = "https://login.local.${networking.domain}";
|
||||||
|
|
@ -35,117 +147,32 @@
|
||||||
type = str;
|
type = str;
|
||||||
default = "login.tail.${networking.domain}";
|
default = "login.tail.${networking.domain}";
|
||||||
};
|
};
|
||||||
authRequestDirective = mkOption {
|
};
|
||||||
type = lines;
|
virtualHosts = mkOption {
|
||||||
default = ''
|
type = attrsOf (submodule hostModule);
|
||||||
auth_request /validate;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = mkMerge [
|
};
|
||||||
|
config.services.nginx = {
|
||||||
|
vouch = mkMerge [
|
||||||
{
|
{
|
||||||
vouch = mkIf vouch-proxy.enable {
|
proxyOrigin = mkIf (tailscale.enable && !vouch-proxy.enable) (
|
||||||
proxyOrigin = let
|
mkDefault "http://login.tail.${networking.domain}"
|
||||||
inherit (vouch-proxy.settings.vouch) listen port;
|
|
||||||
host =
|
|
||||||
if listen == "0.0.0.0" || listen == "[::]"
|
|
||||||
then "localhost"
|
|
||||||
else listen;
|
|
||||||
in
|
|
||||||
mkDefault "http://${host}:${toString port}";
|
|
||||||
authUrl = mkDefault vouch-proxy.authUrl;
|
|
||||||
url = mkDefault vouch-proxy.url;
|
|
||||||
doubleProxy = mkDefault false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
vouch.proxyOrigin = mkIf (tailscale.enable && !vouch-proxy.enable) (
|
|
||||||
mkDefault
|
|
||||||
"http://login.tail.${networking.domain}"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
(mkIf config.vouch.enable {
|
(mkIf vouch-proxy.enable {
|
||||||
extraConfig = ''
|
proxyOrigin = let
|
||||||
${config.vouch.authRequestDirective}
|
inherit (vouch-proxy.settings.vouch) listen port;
|
||||||
error_page 401 = @error401;
|
host =
|
||||||
'';
|
if listen == "0.0.0.0" || listen == "[::]"
|
||||||
locations = {
|
then "localhost"
|
||||||
"/" = {
|
else listen;
|
||||||
extraConfig = mkMerge [
|
in
|
||||||
''
|
mkDefault "http://${host}:${toString port}";
|
||||||
add_header Access-Control-Allow-Origin ${config.vouch.url};
|
authUrl = mkDefault vouch-proxy.authUrl;
|
||||||
add_header Access-Control-Allow-Origin ${config.vouch.authUrl};
|
url = mkDefault vouch-proxy.url;
|
||||||
''
|
doubleProxy = mkDefault false;
|
||||||
(mkIf config.local.enable ''
|
|
||||||
add_header Access-Control-Allow-Origin ${config.vouch.localUrl};
|
|
||||||
'')
|
|
||||||
(mkIf (config.local.enable && tailscale.enable) ''
|
|
||||||
add_header Access-Control-Allow-Origin $scheme://${config.vouch.tailDomain};
|
|
||||||
'')
|
|
||||||
''
|
|
||||||
proxy_set_header X-Vouch-User $auth_resp_x_vouch_user;
|
|
||||||
''
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"@error401" = {
|
|
||||||
extraConfig = let
|
|
||||||
localVouchUrl = ''
|
|
||||||
if ($http_host ~ "\.local\.${networking.domain}$") {
|
|
||||||
set $vouch_url ${config.vouch.localUrl};
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
tailVouchUrl = ''
|
|
||||||
if ($http_host ~ "\.tail\.${networking.domain}$") {
|
|
||||||
set $vouch_url $vouch_scheme://${config.vouch.tailDomain};
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
mkMerge [
|
|
||||||
(mkBefore ''
|
|
||||||
set $vouch_url ${config.vouch.url};
|
|
||||||
set $vouch_scheme $scheme;
|
|
||||||
'')
|
|
||||||
(mkIf config.local.trusted (mkBefore ''
|
|
||||||
if ($http_x_forwarded_proto) {
|
|
||||||
set $vouch_scheme $http_x_forwarded_proto;
|
|
||||||
}
|
|
||||||
''))
|
|
||||||
(mkIf (config.local.enable or false) localVouchUrl)
|
|
||||||
(mkIf (config.local.enable or false && tailscale.enable) tailVouchUrl)
|
|
||||||
''
|
|
||||||
return 302 $vouch_url/login?url=$vouch_scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
|
|
||||||
''
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"/validate" = {
|
|
||||||
recommendedProxySettings = false;
|
|
||||||
proxyPass = "${config.vouch.proxyOrigin}/validate";
|
|
||||||
extraConfig = mkMerge [
|
|
||||||
(mkIf (!config.vouch.doubleProxy) ''
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
'')
|
|
||||||
(mkIf config.vouch.doubleProxy ''
|
|
||||||
proxy_set_header X-Host $host;
|
|
||||||
'')
|
|
||||||
''
|
|
||||||
proxy_pass_request_body off;
|
|
||||||
proxy_set_header Content-Length "";
|
|
||||||
auth_request_set $auth_resp_x_vouch_user $upstream_http_x_vouch_user;
|
|
||||||
auth_request_set $auth_resp_jwt $upstream_http_x_vouch_jwt;
|
|
||||||
auth_request_set $auth_resp_err $upstream_http_x_vouch_err;
|
|
||||||
auth_request_set $auth_resp_failcount $upstream_http_x_vouch_failcount;
|
|
||||||
''
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
in {
|
|
||||||
options = with lib.types; {
|
|
||||||
services.nginx.virtualHosts = mkOption {
|
|
||||||
type = attrsOf (submodule vouchModule);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
};
|
};
|
||||||
config = mkIf config.proxy.websocket.enable {
|
config = mkIf config.proxy.websocket.enable {
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
'';
|
'';
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
|
||||||
cfg = config.services.bazarr;
|
|
||||||
access = config.services.nginx.access.bazarr;
|
|
||||||
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
|
|
||||||
locations = {
|
|
||||||
"/" = {
|
|
||||||
inherit proxyPass;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
options.services.nginx.access.bazarr = with lib.types; {
|
|
||||||
host = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "bazarr.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
port = mkOption {
|
|
||||||
type = port;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config.services.nginx = {
|
|
||||||
access.bazarr = mkIf cfg.enable {
|
|
||||||
host = mkOptionDefault "localhost";
|
|
||||||
port = mkOptionDefault cfg.listenPort;
|
|
||||||
};
|
|
||||||
virtualHosts = {
|
|
||||||
${access.domain} = {
|
|
||||||
inherit locations;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -7,7 +7,8 @@
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkDefault;
|
inherit (lib.modules) mkDefault;
|
||||||
in {
|
in {
|
||||||
services.nginx.virtualHosts.${config.networking.domain} = {
|
services.nginx.virtualHosts.gensokyoZone = {
|
||||||
|
serverName = config.networking.domain;
|
||||||
locations = {
|
locations = {
|
||||||
"/" = {
|
"/" = {
|
||||||
root = inputs.website.packages.${pkgs.system}.gensokyoZone;
|
root = inputs.website.packages.${pkgs.system}.gensokyoZone;
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,29 @@
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkIf mkDefault;
|
inherit (lib.modules) mkIf mkMerge mkDefault;
|
||||||
inherit (config.services) home-assistant tailscale;
|
inherit (config.services) home-assistant nginx;
|
||||||
proxyPass = "http://localhost:${toString home-assistant.config.http.server_port}/";
|
name.shortServer = mkDefault "home";
|
||||||
|
listenPorts = {
|
||||||
|
http = { };
|
||||||
|
https.ssl = true;
|
||||||
|
hass = mkIf (!home-assistant.enable) { port = mkDefault home-assistant.config.http.server_port; };
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
services.nginx.virtualHosts."home.local.${config.networking.domain}" = mkIf home-assistant.enable {
|
config.services.nginx.virtualHosts = {
|
||||||
local.enable = mkDefault true;
|
home-assistant = {
|
||||||
locations."/" = {
|
inherit name listenPorts;
|
||||||
inherit proxyPass;
|
locations."/".proxyPass = mkIf home-assistant.enable (mkDefault
|
||||||
};
|
"http://localhost:${toString home-assistant.config.http.server_port}"
|
||||||
};
|
);
|
||||||
services.nginx.virtualHosts."home.tail.${config.networking.domain}" = mkIf (home-assistant.enable && tailscale.enable) {
|
};
|
||||||
local.enable = mkDefault true;
|
home-assistant'local = {
|
||||||
locations."/" = {
|
inherit name listenPorts;
|
||||||
inherit proxyPass;
|
local.enable = mkDefault true;
|
||||||
|
locations."/".proxyPass = mkIf home-assistant.enable (mkDefault
|
||||||
|
nginx.virtualHosts.home-assistant.locations."/".proxyPass
|
||||||
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
config.networking.firewall.allowedTCPPorts = [ home-assistant.config.http.server_port ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
|
||||||
cfg = config.services.jackett;
|
|
||||||
access = config.services.nginx.access.jackett;
|
|
||||||
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
|
|
||||||
locations = {
|
|
||||||
"/" = {
|
|
||||||
inherit proxyPass;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
options.services.nginx.access.jackett = with lib.types; {
|
|
||||||
host = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "jackett.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
port = mkOption {
|
|
||||||
type = port;
|
|
||||||
default = cfg.port;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config.services.nginx = {
|
|
||||||
access.jackett = mkIf cfg.enable {
|
|
||||||
host = mkOptionDefault "localhost";
|
|
||||||
};
|
|
||||||
virtualHosts = {
|
|
||||||
${access.domain} = {
|
|
||||||
inherit locations;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
54
nixos/access/keycloak.nix
Normal file
54
nixos/access/keycloak.nix
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.options) mkOption;
|
||||||
|
inherit (lib.modules) mkIf mkDefault;
|
||||||
|
cfg = config.services.keycloak;
|
||||||
|
inherit (config) networking;
|
||||||
|
inherit (config.services) nginx;
|
||||||
|
access = nginx.access.keycloak;
|
||||||
|
locations = {
|
||||||
|
"/" = {
|
||||||
|
proxyPass = mkDefault access.url;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options.services.nginx.access.keycloak = with lib.types; {
|
||||||
|
host = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "keycloak.local.${networking.domain}";
|
||||||
|
};
|
||||||
|
url = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "https://${access.host}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config.services.nginx = {
|
||||||
|
access.keycloak = mkIf cfg.enable {
|
||||||
|
host = mkDefault "localhost";
|
||||||
|
url = mkDefault (if cfg.sslCertificate != null then "https://${access.host}" else "http://${access.host}");
|
||||||
|
};
|
||||||
|
virtualHosts = {
|
||||||
|
keycloak = {
|
||||||
|
name.shortServer = mkDefault "sso";
|
||||||
|
ssl.force = mkDefault true;
|
||||||
|
inherit locations;
|
||||||
|
};
|
||||||
|
keycloak'local = {
|
||||||
|
name.shortServer = mkDefault "sso";
|
||||||
|
ssl.force = mkDefault true;
|
||||||
|
local.enable = true;
|
||||||
|
inherit locations;
|
||||||
|
extraConfig = mkIf nginx.vouch.localSso.enable ''
|
||||||
|
set $vouch_local_url ${nginx.vouch.localUrl};
|
||||||
|
if ($x_forwarded_host ~ "\.tail\.${networking.domain}$") {
|
||||||
|
set $vouch_local_url $x_scheme://${nginx.vouch.tailDomain};
|
||||||
|
}
|
||||||
|
proxy_redirect ${nginx.vouch.url}/ $vouch_local_url/;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -27,18 +27,6 @@ in {
|
||||||
type = str;
|
type = str;
|
||||||
default = "http://${access.host}:${toString access.streamPort}";
|
default = "http://${access.host}:${toString access.streamPort}";
|
||||||
};
|
};
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "kitchen.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
localDomain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "kitchen.local.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
tailDomain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "kitchen.tail.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
useACMEHost = mkOption {
|
useACMEHost = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
default = null;
|
default = null;
|
||||||
|
|
@ -46,7 +34,6 @@ in {
|
||||||
};
|
};
|
||||||
config.services.nginx = {
|
config.services.nginx = {
|
||||||
virtualHosts = let
|
virtualHosts = let
|
||||||
addSSL = access.useACMEHost != null || virtualHosts.${access.domain}.addSSL || virtualHosts.${access.domain}.forceSSL;
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
|
|
@ -64,47 +51,22 @@ in {
|
||||||
inherit extraConfig;
|
inherit extraConfig;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
streamListen = {config, ...}: {
|
listenPorts = {
|
||||||
listen =
|
http = { };
|
||||||
concatMap (addr: [
|
https.ssl = true;
|
||||||
(mkIf config.addSSL {
|
stream.port = mkDefault access.streamPort;
|
||||||
inherit addr;
|
|
||||||
port = nginx.defaultSSLListenPort;
|
|
||||||
ssl = true;
|
|
||||||
})
|
|
||||||
{
|
|
||||||
inherit addr;
|
|
||||||
port = nginx.defaultHTTPListenPort;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
inherit addr;
|
|
||||||
port = access.streamPort;
|
|
||||||
}
|
|
||||||
])
|
|
||||||
nginx.defaultListenAddresses;
|
|
||||||
};
|
};
|
||||||
|
name.shortServer = mkDefault "kitchen";
|
||||||
|
kTLS = mkDefault true;
|
||||||
in {
|
in {
|
||||||
${access.domain} = mkMerge [
|
kitchencam = {
|
||||||
{
|
inherit name locations listenPorts kTLS;
|
||||||
vouch.enable = true;
|
vouch.enable = true;
|
||||||
kTLS = mkDefault true;
|
};
|
||||||
inherit (access) useACMEHost;
|
kitchencam'local = {
|
||||||
addSSL = mkDefault (access.useACMEHost != null);
|
inherit name locations listenPorts kTLS;
|
||||||
inherit locations;
|
local.enable = true;
|
||||||
}
|
};
|
||||||
streamListen
|
|
||||||
];
|
|
||||||
${access.localDomain} = mkMerge [
|
|
||||||
{
|
|
||||||
serverAliases = mkIf config.services.tailscale.enable [access.tailDomain];
|
|
||||||
inherit (virtualHosts.${access.domain}) useACMEHost;
|
|
||||||
addSSL = mkDefault addSSL;
|
|
||||||
kTLS = mkDefault true;
|
|
||||||
local.enable = true;
|
|
||||||
inherit locations;
|
|
||||||
}
|
|
||||||
streamListen
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config.networking.firewall.allowedTCPPorts = [
|
config.networking.firewall.allowedTCPPorts = [
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
meta,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib; {
|
|
||||||
services.nginx.virtualHosts."cloud.${config.networking.domain}" = {
|
|
||||||
locations = {
|
|
||||||
"/".proxyPass = meta.tailnet.yukari.ppp 4 80 "nextcloud/";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
|
||||||
cfg = config.services.ombi;
|
|
||||||
access = config.services.nginx.access.ombi;
|
|
||||||
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
|
|
||||||
locations = {
|
|
||||||
"/" = {
|
|
||||||
inherit proxyPass;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
options.services.nginx.access.ombi = with lib.types; {
|
|
||||||
host = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "ombi.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
port = mkOption {
|
|
||||||
type = port;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config.services.nginx = {
|
|
||||||
access.ombi = mkIf cfg.enable {
|
|
||||||
host = mkOptionDefault "localhost";
|
|
||||||
port = mkOptionDefault cfg.port;
|
|
||||||
};
|
|
||||||
virtualHosts = {
|
|
||||||
${access.domain} = {
|
|
||||||
inherit locations;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -13,14 +13,6 @@ in {
|
||||||
url = mkOption {
|
url = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
};
|
};
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "plex.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
localDomain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "plex.local.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
externalPort = mkOption {
|
externalPort = mkOption {
|
||||||
type = nullOr port;
|
type = nullOr port;
|
||||||
default = null;
|
default = null;
|
||||||
|
|
@ -51,33 +43,25 @@ in {
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
'';
|
'';
|
||||||
location = {
|
locations."/" = {
|
||||||
proxy.websocket.enable = true;
|
proxy.websocket.enable = true;
|
||||||
proxyPass = access.url;
|
proxyPass = access.url;
|
||||||
};
|
};
|
||||||
|
name.shortServer = mkDefault "plex";
|
||||||
|
kTLS = mkDefault true;
|
||||||
in {
|
in {
|
||||||
${access.domain} = {
|
plex = {
|
||||||
locations."/" = location;
|
inherit name locations extraConfig kTLS;
|
||||||
kTLS = mkDefault true;
|
|
||||||
inherit extraConfig;
|
|
||||||
};
|
};
|
||||||
${access.localDomain} = {
|
plex'local = {
|
||||||
|
inherit name locations extraConfig kTLS;
|
||||||
local.enable = true;
|
local.enable = true;
|
||||||
locations."/" = location;
|
|
||||||
kTLS = mkDefault true;
|
|
||||||
inherit extraConfig;
|
|
||||||
};
|
};
|
||||||
plex-external = mkIf (access.externalPort != null) {
|
plex-external = mkIf (access.externalPort != null) {
|
||||||
serverName = mkDefault access.domain;
|
serverName = mkDefault "plex.${config.networking.domain}";
|
||||||
default = mkDefault true;
|
default = mkDefault true;
|
||||||
listen =
|
listenPorts.external.port = access.externalPort;
|
||||||
map (addr: {
|
inherit extraConfig locations;
|
||||||
inherit addr;
|
|
||||||
port = access.externalPort;
|
|
||||||
})
|
|
||||||
nginx.defaultListenAddresses;
|
|
||||||
locations."/" = location;
|
|
||||||
inherit extraConfig;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
|
||||||
cfg = config.services.radarr;
|
|
||||||
access = config.services.nginx.access.radarr;
|
|
||||||
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
|
|
||||||
locations = {
|
|
||||||
"/" = {
|
|
||||||
inherit proxyPass;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
options.services.nginx.access.radarr = with lib.types; {
|
|
||||||
host = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "radarr.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
port = mkOption {
|
|
||||||
type = port;
|
|
||||||
default = cfg.port;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config.services.nginx = {
|
|
||||||
access.radarr = mkIf cfg.enable {
|
|
||||||
host = mkOptionDefault "localhost";
|
|
||||||
};
|
|
||||||
virtualHosts = {
|
|
||||||
${access.domain} = {
|
|
||||||
inherit locations;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
|
||||||
cfg = config.services.sonarr;
|
|
||||||
access = config.services.nginx.access.sonarr;
|
|
||||||
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
|
|
||||||
locations = {
|
|
||||||
"/" = {
|
|
||||||
inherit proxyPass;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
options.services.nginx.access.sonarr = with lib.types; {
|
|
||||||
host = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "sonarr.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
port = mkOption {
|
|
||||||
type = port;
|
|
||||||
default = cfg.port;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config.services.nginx = {
|
|
||||||
access.sonarr = mkIf cfg.enable {
|
|
||||||
host = mkOptionDefault "localhost";
|
|
||||||
};
|
|
||||||
virtualHosts = {
|
|
||||||
${access.domain} = {
|
|
||||||
inherit locations;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
|
||||||
cfg = config.services.tautulli;
|
|
||||||
access = config.services.nginx.access.tautulli;
|
|
||||||
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
|
|
||||||
locations = {
|
|
||||||
"/" = {
|
|
||||||
inherit proxyPass;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
options.services.nginx.access.tautulli = with lib.types; {
|
|
||||||
host = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "tautulli.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
port = mkOption {
|
|
||||||
type = port;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config.services.nginx = {
|
|
||||||
access.tautulli = mkIf cfg.enable {
|
|
||||||
host = mkOptionDefault "localhost";
|
|
||||||
port = mkOptionDefault cfg.port;
|
|
||||||
};
|
|
||||||
virtualHosts = {
|
|
||||||
${access.domain} = {
|
|
||||||
inherit locations;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -14,22 +14,6 @@ in {
|
||||||
url = mkOption {
|
url = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
};
|
};
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "login.${networking.domain}";
|
|
||||||
};
|
|
||||||
localDomain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "login.local.${networking.domain}";
|
|
||||||
};
|
|
||||||
tailDomain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "login.tail.${networking.domain}";
|
|
||||||
};
|
|
||||||
useACMEHost = mkOption {
|
|
||||||
type = nullOr str;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
config.services.nginx = {
|
config.services.nginx = {
|
||||||
access.vouch = mkIf cfg.enable {
|
access.vouch = mkIf cfg.enable {
|
||||||
|
|
@ -51,42 +35,52 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
"/validate" = {config, ...}: {
|
"/validate" = {config, ...}: {
|
||||||
|
proxied.enable = true;
|
||||||
proxyPass = mkDefault (access.url + "/validate");
|
proxyPass = mkDefault (access.url + "/validate");
|
||||||
recommendedProxySettings = mkDefault false;
|
proxy.headers.enableRecommended = true;
|
||||||
extraConfig =
|
local.denyGlobal = true;
|
||||||
if config.local.trusted
|
extraConfig = ''
|
||||||
then ''
|
set $x_proxy_host $x_forwarded_host;
|
||||||
if ($http_x_host = ''') {
|
'';
|
||||||
set $http_x_host $host;
|
|
||||||
}
|
|
||||||
proxy_set_header Host $http_x_host;
|
|
||||||
''
|
|
||||||
else ''
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
localLocations = kanidmDomain: {
|
localLocations = kanidmDomain: mkIf nginx.vouch.localSso.enable {
|
||||||
"/".extraConfig = ''
|
"/" = {
|
||||||
proxy_redirect $scheme://sso.${networking.domain}/ $scheme://${kanidmDomain}/;
|
proxied.xvars.enable = true;
|
||||||
'';
|
extraConfig = ''
|
||||||
|
proxy_redirect https://sso.${networking.domain}/ $x_scheme://${kanidmDomain}/;
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
name.shortServer = mkDefault "login";
|
||||||
in {
|
in {
|
||||||
${access.localDomain} = mkIf (access.useACMEHost != null) {
|
vouch = {
|
||||||
local.enable = true;
|
inherit name locations;
|
||||||
locations = mkMerge [
|
ssl.force = true;
|
||||||
locations
|
|
||||||
];
|
|
||||||
useACMEHost = mkDefault access.useACMEHost;
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
};
|
||||||
${access.tailDomain} = mkIf tailscale.enable {
|
vouch'local = {
|
||||||
|
name = {
|
||||||
|
inherit (name) shortServer;
|
||||||
|
qualifier = mkDefault "local";
|
||||||
|
includeTailscale = false;
|
||||||
|
};
|
||||||
|
local.enable = true;
|
||||||
|
ssl.force = true;
|
||||||
|
locations = mkMerge [
|
||||||
|
locations
|
||||||
|
(localLocations "sso.local.${networking.domain}")
|
||||||
|
];
|
||||||
|
};
|
||||||
|
vouch'tail = mkIf tailscale.enable {
|
||||||
|
name = {
|
||||||
|
inherit (name) shortServer;
|
||||||
|
qualifier = mkDefault "tail";
|
||||||
|
};
|
||||||
local.enable = true;
|
local.enable = true;
|
||||||
locations = mkMerge [
|
locations = mkMerge [
|
||||||
locations
|
locations
|
||||||
|
(localLocations "sso.tail.${networking.domain}")
|
||||||
];
|
];
|
||||||
useACMEHost = mkDefault access.useACMEHost;
|
|
||||||
addSSL = mkIf (access.useACMEHost != null) (mkDefault true);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,47 +7,35 @@
|
||||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
||||||
cfg = config.services.zigbee2mqtt;
|
cfg = config.services.zigbee2mqtt;
|
||||||
access = config.services.nginx.access.zigbee2mqtt;
|
access = config.services.nginx.access.zigbee2mqtt;
|
||||||
location = {
|
locations."/" = {
|
||||||
proxy.websocket.enable = true;
|
proxy.websocket.enable = true;
|
||||||
proxyPass = mkDefault "http://${access.host}:${toString access.port}";
|
proxyPass = mkDefault "http://${access.host}:${toString access.port}";
|
||||||
};
|
};
|
||||||
|
name.shortServer = mkDefault "z2m";
|
||||||
in {
|
in {
|
||||||
options.services.nginx.access.zigbee2mqtt = with lib.types; {
|
options.services.nginx.access.zigbee2mqtt = with lib.types; {
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
};
|
};
|
||||||
domain = mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
localDomain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "z2m.local.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
tailDomain = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "z2m.tail.${config.networking.domain}";
|
|
||||||
};
|
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
type = port;
|
type = port;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config.services.nginx = {
|
config.services.nginx = {
|
||||||
access.zigbee2mqtt = mkIf cfg.enable {
|
access.zigbee2mqtt = mkIf cfg.enable {
|
||||||
domain = mkOptionDefault cfg.domain;
|
|
||||||
host = mkOptionDefault "localhost";
|
host = mkOptionDefault "localhost";
|
||||||
port = mkIf (cfg.settings ? frontend.port) (
|
port = mkIf (cfg.settings ? frontend.port) (
|
||||||
mkOptionDefault cfg.settings.frontend.port
|
mkOptionDefault cfg.settings.frontend.port
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
${access.domain} = {
|
zigbee2mqtt = {
|
||||||
|
inherit name locations;
|
||||||
vouch.enable = true;
|
vouch.enable = true;
|
||||||
locations."/" = location;
|
|
||||||
};
|
};
|
||||||
${access.localDomain} = {
|
zigbee2mqtt'local = {
|
||||||
serverAliases = mkIf config.services.tailscale.enable [access.tailDomain];
|
inherit name locations;
|
||||||
local.enable = true;
|
local.enable = true;
|
||||||
locations."/" = location;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ in {
|
||||||
settings = {
|
settings = {
|
||||||
hostname = mkDefault hostname;
|
hostname = mkDefault hostname;
|
||||||
proxy = mkDefault (if cfg.sslCertificate != null then "reencrypt" else "edge");
|
proxy = mkDefault (if cfg.sslCertificate != null then "reencrypt" else "edge");
|
||||||
|
proxy-headers = mkDefault "xforwarded";
|
||||||
};
|
};
|
||||||
|
|
||||||
sslCertificate = mkDefault "${cert}/fullchain.pem";
|
sslCertificate = mkDefault "${cert}/fullchain.pem";
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
vouch-client-secret: ENC[AES256_GCM,data:RWGjoC+L0FilUipBgvCy5t1bJEzDM8THc/m6RjwSPs9qPqfQCbSQWt/XXtQMR0VJ,iv:PJREZcXjLf3JVU4W5jD/6ruoaCIUV5TRocrmb1PjQeE=,tag:ZgKi+rI4ok7aIB3TOCXFKg==,type:str]
|
vouch-client-secret: ENC[AES256_GCM,data:gmCOrC3FDSUw/V1FZywiq0MWgKTK7j2ojb/fZahFS4g=,iv:D6UfdfeRaqzEhK9yVsc0TfIfQ/EBzWdtzLt/vUKPR8I=,tag:EZ+XHvi0gnhvJ6s1d6KviA==,type:str]
|
||||||
vouch-jwt: ENC[AES256_GCM,data:7G1/pzEmR7NM7eFb2wED4HR/A00TNdBjBs/OdziDgIuPttqp4AeLRnJ0UhRps5taEx2cTH0U5GyCR/A9ef9hfA==,iv:ugOuH35frzoT6lX9UTJjzoTm2OTCqS3sNJGq8TfViEY=,tag:jvv4DkLwMB9ytefpGpIqPQ==,type:str]
|
vouch-jwt: ENC[AES256_GCM,data:7G1/pzEmR7NM7eFb2wED4HR/A00TNdBjBs/OdziDgIuPttqp4AeLRnJ0UhRps5taEx2cTH0U5GyCR/A9ef9hfA==,iv:ugOuH35frzoT6lX9UTJjzoTm2OTCqS3sNJGq8TfViEY=,tag:jvv4DkLwMB9ytefpGpIqPQ==,type:str]
|
||||||
sops:
|
sops:
|
||||||
shamir_threshold: 1
|
shamir_threshold: 1
|
||||||
|
|
@ -70,8 +70,8 @@ sops:
|
||||||
RkQvakRmdjB3ME1rbnNTWjVDQU5QSmcKi1KhB8zpSLlaCgSelaEYdtOGHFLlc+Z3
|
RkQvakRmdjB3ME1rbnNTWjVDQU5QSmcKi1KhB8zpSLlaCgSelaEYdtOGHFLlc+Z3
|
||||||
hagYdJqojaOYbTGVBkWAYK0Zfh++1/QbDYJH6ySjDC8mFFCqEdSuYQ==
|
hagYdJqojaOYbTGVBkWAYK0Zfh++1/QbDYJH6ySjDC8mFFCqEdSuYQ==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2024-01-16T19:11:11Z"
|
lastmodified: "2024-03-20T00:39:56Z"
|
||||||
mac: ENC[AES256_GCM,data:1J3dCx5ptr2ah2LbvoP/rcUzPlzm3wZvpWLffIvh7PriNJ6vx2xj5fFK9s2AhIunxAaef0KJLzwzcfNwxEkJO3M6QSf0UUw3wopah1W3ZKLE2H/Z8bNncaNzSuh6QODbYShSG2yK4HmQApd8R9NfKlAHsDno+aRhuh7OYM7CaLI=,iv:KzMfJDJOqYm2epLM6Epd44aRoU7uJcusCl6m6/+cDtQ=,tag:tQ8MQ1NWey4E1dFu2YnOQw==,type:str]
|
mac: ENC[AES256_GCM,data:JY2ttbttavS4RqYEFf95BkiPrK1r4r6hXnoQMCqtoQmBhSbUF9X5gvxZuqBFF7as9KgwiWHXFJ6S0FccmDDcBA/QoGxI4IJoR4nEIp7Y/YHTY6Ni0vZfO27yAtGmnViXadOeVyFChVN6GjRnxLp/FaBdXxtjSH8x4sQqf/2VWCw=,iv:/pnWEOcclzw0xcpL6lwErJLOBE9tBk1pOZZe3ew20TM=,tag:WNWiSG7Buve8YxJb1XxFwg==,type:str]
|
||||||
pgp:
|
pgp:
|
||||||
- created_at: "2024-03-19T02:39:12Z"
|
- created_at: "2024-03-19T02:39:12Z"
|
||||||
enc: |-
|
enc: |-
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
tei = access.nixosFor "tei";
|
tei = access.nixosFor "tei";
|
||||||
inherit (mediabox.services) plex;
|
inherit (mediabox.services) plex;
|
||||||
inherit (keycloak.services) vouch-proxy;
|
inherit (keycloak.services) vouch-proxy;
|
||||||
|
inherit (tei.services) home-assistant;
|
||||||
inherit (config.services) nginx tailscale;
|
inherit (config.services) nginx tailscale;
|
||||||
in {
|
in {
|
||||||
imports = let
|
imports = let
|
||||||
|
|
@ -31,11 +32,13 @@ in {
|
||||||
nixos.access.nginx
|
nixos.access.nginx
|
||||||
nixos.access.global
|
nixos.access.global
|
||||||
nixos.access.gensokyo
|
nixos.access.gensokyo
|
||||||
|
nixos.access.keycloak
|
||||||
nixos.access.vouch
|
nixos.access.vouch
|
||||||
nixos.access.freeipa
|
nixos.access.freeipa
|
||||||
nixos.access.freepbx
|
nixos.access.freepbx
|
||||||
nixos.access.unifi
|
nixos.access.unifi
|
||||||
nixos.access.kitchencam
|
nixos.access.kitchencam
|
||||||
|
nixos.access.home-assistant
|
||||||
nixos.access.proxmox
|
nixos.access.proxmox
|
||||||
nixos.access.plex
|
nixos.access.plex
|
||||||
nixos.access.invidious
|
nixos.access.invidious
|
||||||
|
|
@ -61,14 +64,31 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
security.acme.certs = let
|
security.acme.certs = let
|
||||||
inherit (nginx) access;
|
inherit (nginx) access virtualHosts;
|
||||||
in {
|
in {
|
||||||
${access.vouch.localDomain} = {
|
keycloak = {
|
||||||
inherit (nginx) group;
|
inherit (nginx) group;
|
||||||
|
domain = virtualHosts.keycloak.serverName;
|
||||||
extraDomainNames = mkMerge [
|
extraDomainNames = mkMerge [
|
||||||
(mkIf tailscale.enable [
|
virtualHosts.keycloak.serverAliases
|
||||||
access.vouch.tailDomain
|
virtualHosts.keycloak'local.allServerNames
|
||||||
])
|
];
|
||||||
|
};
|
||||||
|
home-assistant = {
|
||||||
|
inherit (nginx) group;
|
||||||
|
domain = virtualHosts.home-assistant.serverName;
|
||||||
|
extraDomainNames = mkMerge [
|
||||||
|
virtualHosts.home-assistant.serverAliases
|
||||||
|
virtualHosts.home-assistant'local.allServerNames
|
||||||
|
];
|
||||||
|
};
|
||||||
|
vouch = {
|
||||||
|
inherit (nginx) group;
|
||||||
|
domain = virtualHosts.vouch.serverName;
|
||||||
|
extraDomainNames = mkMerge [
|
||||||
|
virtualHosts.vouch.serverAliases
|
||||||
|
virtualHosts.vouch'local.allServerNames
|
||||||
|
(mkIf tailscale.enable virtualHosts.vouch'tail.allServerNames)
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
${access.unifi.domain} = {
|
${access.unifi.domain} = {
|
||||||
|
|
@ -116,19 +136,20 @@ in {
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
${access.plex.domain} = {
|
plex = {
|
||||||
inherit (nginx) group;
|
|
||||||
extraDomainNames = [access.plex.localDomain];
|
|
||||||
};
|
|
||||||
${access.kitchencam.domain} = {
|
|
||||||
inherit (nginx) group;
|
inherit (nginx) group;
|
||||||
|
domain = virtualHosts.plex.serverName;
|
||||||
extraDomainNames = mkMerge [
|
extraDomainNames = mkMerge [
|
||||||
[
|
virtualHosts.plex.serverAliases
|
||||||
access.kitchencam.localDomain
|
virtualHosts.plex'local.allServerNames
|
||||||
]
|
];
|
||||||
(mkIf tailscale.enable [
|
};
|
||||||
access.kitchencam.tailDomain
|
kitchencam = {
|
||||||
])
|
inherit (nginx) group;
|
||||||
|
domain = virtualHosts.kitchencam.serverName;
|
||||||
|
extraDomainNames = mkMerge [
|
||||||
|
virtualHosts.kitchencam.serverAliases
|
||||||
|
virtualHosts.kitchencam'local.allServerNames
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
${access.invidious.domain} = {
|
${access.invidious.domain} = {
|
||||||
|
|
@ -153,7 +174,6 @@ in {
|
||||||
};
|
};
|
||||||
access.vouch = assert vouch-proxy.enable; {
|
access.vouch = assert vouch-proxy.enable; {
|
||||||
url = "http://${keycloak.lib.access.hostnameForNetwork.local}:${toString vouch-proxy.settings.vouch.port}";
|
url = "http://${keycloak.lib.access.hostnameForNetwork.local}:${toString vouch-proxy.settings.vouch.port}";
|
||||||
useACMEHost = access.vouch.localDomain;
|
|
||||||
};
|
};
|
||||||
access.unifi = {
|
access.unifi = {
|
||||||
host = tei.lib.access.hostnameForNetwork.local;
|
host = tei.lib.access.hostnameForNetwork.local;
|
||||||
|
|
@ -169,24 +189,40 @@ in {
|
||||||
};
|
};
|
||||||
access.kitchencam = {
|
access.kitchencam = {
|
||||||
streamPort = 41081;
|
streamPort = 41081;
|
||||||
useACMEHost = access.kitchencam.domain;
|
|
||||||
};
|
};
|
||||||
access.invidious = {
|
access.invidious = {
|
||||||
url = "http://${mediabox.lib.access.hostnameForNetwork.local}:${toString mediabox.services.invidious.port}";
|
url = "http://${mediabox.lib.access.hostnameForNetwork.local}:${toString mediabox.services.invidious.port}";
|
||||||
};
|
};
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
|
gensokyoZone.proxied.enable = "cloudflared";
|
||||||
|
keycloak = {
|
||||||
|
# we're not the real sso record-holder, so don't respond globally..
|
||||||
|
local.denyGlobal = true;
|
||||||
|
ssl.cert.name = "keycloak";
|
||||||
|
};
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
home-assistant = {
|
||||||
|
# not the real hass record-holder, so don't respond globally..
|
||||||
|
local.denyGlobal = true;
|
||||||
|
ssl.cert.name = "home-assistant";
|
||||||
|
locations."/".proxyPass = "http://${tei.lib.access.hostnameForNetwork.tail}:${toString home-assistant.config.http.server_port}";
|
||||||
|
};
|
||||||
|
home-assistant'local.ssl.cert.name = "home-assistant";
|
||||||
${access.freepbx.domain} = {
|
${access.freepbx.domain} = {
|
||||||
local.enable = true;
|
local.enable = true;
|
||||||
};
|
};
|
||||||
${access.proxmox.domain} = {
|
${access.proxmox.domain} = {
|
||||||
useACMEHost = access.proxmox.domain;
|
useACMEHost = access.proxmox.domain;
|
||||||
};
|
};
|
||||||
${access.plex.domain} = {
|
plex.ssl.cert.name = "plex";
|
||||||
addSSL = true;
|
plex'local.ssl.cert.name = "plex";
|
||||||
useACMEHost = access.plex.domain;
|
kitchencam.ssl.cert.name = "kitchencam";
|
||||||
};
|
kitchencam'local.ssl.cert.name = "kitchencam";
|
||||||
${access.kitchencam.domain} = {
|
|
||||||
};
|
|
||||||
${access.invidious.domain} = {
|
${access.invidious.domain} = {
|
||||||
useACMEHost = access.invidious.domain;
|
useACMEHost = access.invidious.domain;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,20 @@
|
||||||
tunnels.${tunnelId} = {
|
tunnels.${tunnelId} = {
|
||||||
default = "http_status:404";
|
default = "http_status:404";
|
||||||
credentialsFile = config.sops.secrets.cloudflared-tunnel-keycloak.path;
|
credentialsFile = config.sops.secrets.cloudflared-tunnel-keycloak.path;
|
||||||
ingress = {
|
ingress = let
|
||||||
${keycloak.settings.hostname} = assert keycloak.enable; let
|
keycloakHost = if keycloak.settings.hostname != null then keycloak.settings.hostname else "sso.${config.networking.domain}";
|
||||||
scheme = if keycloak.sslCertificate != null then "https" else "http";
|
keyCloakScheme = if keycloak.sslCertificate != null then "https" else "http";
|
||||||
port = keycloak.settings."${scheme}-port";
|
keycloakPort = keycloak.settings."${keyCloakScheme}-port";
|
||||||
in {
|
in {
|
||||||
service = "${scheme}://localhost:${toString port}";
|
${keycloakHost} = assert keycloak.enable; {
|
||||||
originRequest.${if scheme == "https" then "noTLSVerify" else null} = true;
|
service = "${keyCloakScheme}://localhost:${toString keycloakPort}";
|
||||||
|
originRequest.${if keyCloakScheme == "https" then "noTLSVerify" else null} = true;
|
||||||
};
|
};
|
||||||
${vouch-proxy.domain}.service = assert vouch-proxy.enable; "http://localhost:${toString vouch-proxy.settings.vouch.port}";
|
${vouch-proxy.domain}.service = assert vouch-proxy.enable; "http://localhost:${toString vouch-proxy.settings.vouch.port}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sops.secrets.cloudflared-tunnel-keycloak = {
|
sops.secrets.cloudflared-tunnel-keycloak = {
|
||||||
owner = config.services.cloudflared.user;
|
owner = config.services.cloudflared.user;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -153,9 +153,9 @@ chmod 0755 /rpool/caches/plex/tautulli/cache
|
||||||
mkshared hass 100286 100286 0700
|
mkshared hass 100286 100286 0700
|
||||||
mkshared kanidm 100994 100993 0700
|
mkshared kanidm 100994 100993 0700
|
||||||
mkshared mosquitto 100246 100246 0700
|
mkshared mosquitto 100246 100246 0700
|
||||||
mkshared plex 100193 100193 0755
|
mkshared plex 100193 100193 0750
|
||||||
mkshared postgresql 100071 100071 0750
|
mkshared postgresql 100071 100071 0750
|
||||||
mkshared unifi 100990 100990 0755
|
mkshared unifi 100990 100990 0750
|
||||||
mkshared zigbee2mqtt 100317 100317 0700
|
mkshared zigbee2mqtt 100317 100317 0700
|
||||||
|
|
||||||
ln -sf /lib/systemd/system/auth-rpcgss-module.service /etc/systemd/system/
|
ln -sf /lib/systemd/system/auth-rpcgss-module.service /etc/systemd/system/
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ in {
|
||||||
nixos.postgres
|
nixos.postgres
|
||||||
nixos.nginx
|
nixos.nginx
|
||||||
nixos.access.zigbee2mqtt
|
nixos.access.zigbee2mqtt
|
||||||
nixos.access.home-assistant
|
|
||||||
nixos.access.unifi
|
nixos.access.unifi
|
||||||
nixos.unifi
|
nixos.unifi
|
||||||
nixos.mosquitto
|
nixos.mosquitto
|
||||||
|
|
@ -27,13 +26,9 @@ in {
|
||||||
./cloudflared.nix
|
./cloudflared.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
services.nginx = let
|
services.nginx = {
|
||||||
inherit (config.services.nginx) access;
|
|
||||||
in {
|
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
${access.zigbee2mqtt.domain} = {
|
zigbee2mqtt.proxied.enable = "cloudflared";
|
||||||
local.denyGlobal = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,14 @@ module "hakurei_system_records" {
|
||||||
"prox",
|
"prox",
|
||||||
"id",
|
"id",
|
||||||
"login",
|
"login",
|
||||||
|
"sso",
|
||||||
"ldap",
|
"ldap",
|
||||||
"freeipa",
|
"freeipa",
|
||||||
"unifi",
|
"unifi",
|
||||||
"pbx",
|
"pbx",
|
||||||
"smb",
|
"smb",
|
||||||
"kitchen",
|
"kitchen",
|
||||||
|
"home",
|
||||||
"yt",
|
"yt",
|
||||||
]
|
]
|
||||||
global_subdomains = [
|
global_subdomains = [
|
||||||
|
|
@ -87,7 +89,6 @@ module "tewi_system_records" {
|
||||||
local_subdomains = [
|
local_subdomains = [
|
||||||
"mqtt",
|
"mqtt",
|
||||||
"z2m",
|
"z2m",
|
||||||
"home",
|
|
||||||
"postgresql",
|
"postgresql",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue