mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 04:19:19 -08:00
feat(hakurei): kanidm access
This commit is contained in:
parent
a8cd175500
commit
b85e850dd6
10 changed files with 322 additions and 35 deletions
|
|
@ -9,6 +9,7 @@ let
|
||||||
inherit (lib.strings) concatMapStringsSep;
|
inherit (lib.strings) concatMapStringsSep;
|
||||||
inherit (lib.lists) optionals;
|
inherit (lib.lists) optionals;
|
||||||
inherit (config.services) tailscale;
|
inherit (config.services) tailscale;
|
||||||
|
inherit (config.services.nginx) virtualHosts;
|
||||||
inherit (config.networking.access) cidrForNetwork;
|
inherit (config.networking.access) cidrForNetwork;
|
||||||
cfg = config.services.kanidm;
|
cfg = config.services.kanidm;
|
||||||
access = config.services.nginx.access.kanidm;
|
access = config.services.nginx.access.kanidm;
|
||||||
|
|
@ -39,17 +40,26 @@ in {
|
||||||
};
|
};
|
||||||
domain = mkOption {
|
domain = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
|
default = "id.${config.networking.domain}";
|
||||||
};
|
};
|
||||||
localDomain = mkOption {
|
localDomain = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "id.local.${config.networking.domain}";
|
default = "id.local.${config.networking.domain}";
|
||||||
};
|
};
|
||||||
|
tailDomain = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "id.tail.${config.networking.domain}";
|
||||||
|
};
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
type = port;
|
type = port;
|
||||||
};
|
};
|
||||||
ldapPort = mkOption {
|
ldapPort = mkOption {
|
||||||
type = port;
|
type = port;
|
||||||
};
|
};
|
||||||
|
useACMEHost = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = virtualHosts.${access.domain}.useACMEHost;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
|
|
@ -59,7 +69,17 @@ in {
|
||||||
port = mkOptionDefault cfg.server.frontend.port;
|
port = mkOptionDefault cfg.server.frontend.port;
|
||||||
ldapPort = mkOptionDefault cfg.server.ldap.port;
|
ldapPort = mkOptionDefault cfg.server.ldap.port;
|
||||||
};
|
};
|
||||||
streamConfig = ''
|
streamConfig = let
|
||||||
|
inherit (config.security.acme) certs;
|
||||||
|
sslConfig = if access.useACMEHost != null then ''
|
||||||
|
ssl_certificate ${certs.${access.useACMEHost}.directory}/fullchain.pem;
|
||||||
|
ssl_certificate_key ${certs.${access.useACMEHost}.directory}/key.pem;
|
||||||
|
ssl_trusted_certificate ${certs.${access.useACMEHost}.directory}/chain.pem;
|
||||||
|
'' else ''
|
||||||
|
ssl_certificate ${cfg.serverSettings.tls_chain};
|
||||||
|
ssl_certificate_key ${cfg.serverSettings.tls_key};
|
||||||
|
'';
|
||||||
|
in ''
|
||||||
server {
|
server {
|
||||||
listen 0.0.0.0:389;
|
listen 0.0.0.0:389;
|
||||||
listen [::]:389;
|
listen [::]:389;
|
||||||
|
|
@ -71,8 +91,7 @@ in {
|
||||||
server {
|
server {
|
||||||
listen 0.0.0.0:636 ssl;
|
listen 0.0.0.0:636 ssl;
|
||||||
listen [::]:636 ssl;
|
listen [::]:636 ssl;
|
||||||
ssl_certificate ${cfg.serverSettings.tls_chain};
|
${sslConfig}
|
||||||
ssl_certificate_key ${cfg.serverSettings.tls_key};
|
|
||||||
proxy_pass ${access.host}:${toString access.ldapPort};
|
proxy_pass ${access.host}:${toString access.ldapPort};
|
||||||
proxy_ssl on;
|
proxy_ssl on;
|
||||||
proxy_ssl_verify off;
|
proxy_ssl_verify off;
|
||||||
|
|
@ -84,10 +103,14 @@ in {
|
||||||
inherit locations;
|
inherit locations;
|
||||||
};
|
};
|
||||||
${access.localDomain} = {
|
${access.localDomain} = {
|
||||||
|
inherit (virtualHosts.${access.domain}) useACMEHost;
|
||||||
|
addSSL = mkDefault (access.useACMEHost != null || virtualHosts.${access.domain}.forceSSL);
|
||||||
local.enable = true;
|
local.enable = true;
|
||||||
inherit locations;
|
inherit locations;
|
||||||
};
|
};
|
||||||
"id.tail.${config.networking.domain}" = mkIf config.services.tailscale.enable {
|
${access.tailDomain} = mkIf config.services.tailscale.enable {
|
||||||
|
inherit (virtualHosts.${access.domain}) useACMEHost;
|
||||||
|
addSSL = mkDefault (access.useACMEHost != null || virtualHosts.${access.domain}.forceSSL);
|
||||||
local.enable = true;
|
local.enable = true;
|
||||||
inherit locations;
|
inherit locations;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,20 +4,39 @@
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkIf mkDefault;
|
inherit (lib.options) mkOption;
|
||||||
|
inherit (lib.modules) mkIf mkMerge mkDefault;
|
||||||
inherit (lib.strings) escapeRegex;
|
inherit (lib.strings) escapeRegex;
|
||||||
inherit (lib.lists) singleton optional;
|
inherit (lib.lists) singleton optional;
|
||||||
inherit (config.services) tailscale;
|
inherit (config.services) tailscale;
|
||||||
|
inherit (config.services.nginx) virtualHosts;
|
||||||
|
access = config.services.nginx.access.proxmox;
|
||||||
proxyPass = "https://reisen.local.gensokyo.zone:8006/";
|
proxyPass = "https://reisen.local.gensokyo.zone:8006/";
|
||||||
unencrypted = pkgs.mkSnakeOil {
|
unencrypted = pkgs.mkSnakeOil {
|
||||||
name = "prox-local-cert";
|
name = "prox-local-cert";
|
||||||
domain = singleton "prox.local.${config.networking.domain}"
|
domain = singleton "prox.local.${config.networking.domain}"
|
||||||
++ optional tailscale.enable "prox.tail.${config.networking.domain}";
|
++ optional tailscale.enable "prox.tail.${config.networking.domain}";
|
||||||
};
|
};
|
||||||
sslCertificate = unencrypted.fullchain;
|
sslHost = { config, ... }: {
|
||||||
sslCertificateKey = unencrypted.key;
|
sslCertificate = mkIf (!config.enableACME && config.useACMEHost == null) unencrypted.fullchain;
|
||||||
|
sslCertificateKey = mkIf (!config.enableACME && config.useACMEHost == null) unencrypted.key;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
services.nginx.virtualHosts."prox.${config.networking.domain}" = {
|
options.services.nginx.access.proxmox = with lib.types; {
|
||||||
|
domain = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "prox.${config.networking.domain}";
|
||||||
|
};
|
||||||
|
localDomain = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "prox.local.${config.networking.domain}";
|
||||||
|
};
|
||||||
|
tailDomain = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "prox.tail.${config.networking.domain}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config.services.nginx.virtualHosts = let
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
if ($http_x_forwarded_proto = http) {
|
if ($http_x_forwarded_proto = http) {
|
||||||
|
|
@ -65,26 +84,31 @@ in {
|
||||||
internal;
|
internal;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
in {
|
||||||
|
${access.domain} = {
|
||||||
|
inherit locations;
|
||||||
};
|
};
|
||||||
services.nginx.virtualHosts."prox.local.${config.networking.domain}" = {
|
${access.localDomain} = mkMerge [ {
|
||||||
|
inherit (virtualHosts.${access.domain}) useACMEHost;
|
||||||
local.enable = mkDefault true;
|
local.enable = mkDefault true;
|
||||||
forceSSL = mkDefault true;
|
forceSSL = mkDefault true;
|
||||||
inherit sslCertificate sslCertificateKey;
|
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxy.websocket.enable = true;
|
proxy.websocket.enable = true;
|
||||||
inherit proxyPass;
|
inherit proxyPass;
|
||||||
};
|
};
|
||||||
};
|
} sslHost ];
|
||||||
services.nginx.virtualHosts."prox.tail.${config.networking.domain}" = mkIf tailscale.enable {
|
${access.tailDomain} = mkIf tailscale.enable (mkMerge [ {
|
||||||
|
inherit (virtualHosts.${access.domain}) useACMEHost;
|
||||||
|
addSSL = mkDefault true;
|
||||||
local.enable = mkDefault true;
|
local.enable = mkDefault true;
|
||||||
inherit sslCertificate sslCertificateKey;
|
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxy.websocket.enable = true;
|
proxy.websocket.enable = true;
|
||||||
inherit proxyPass;
|
inherit proxyPass;
|
||||||
};
|
};
|
||||||
|
} sslHost ]);
|
||||||
};
|
};
|
||||||
|
|
||||||
sops.secrets.access-proxmox = {
|
config.sops.secrets.access-proxmox = {
|
||||||
sopsFile = mkDefault ../secrets/access-proxmox.yaml;
|
sopsFile = mkDefault ../secrets/access-proxmox.yaml;
|
||||||
owner = config.services.nginx.user;
|
owner = config.services.nginx.user;
|
||||||
group = config.services.nginx.group;
|
group = config.services.nginx.group;
|
||||||
|
|
|
||||||
51
nixos/acme.nix
Normal file
51
nixos/acme.nix
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.modules) mkMerge mkDefault;
|
||||||
|
inherit (lib.strings) removePrefix splitString concatStringsSep;
|
||||||
|
inherit (lib.lists) head optional;
|
||||||
|
cfg = config.security.acme;
|
||||||
|
mkHash = with builtins; val: substring 0 20 (hashString "sha256" val);
|
||||||
|
mkAccountHash = { server ? null, keyType, email }: mkHash "${toString server} ${keyType} ${email}";
|
||||||
|
mkHost = server: head (splitString "/" (removePrefix "https://" server));
|
||||||
|
mkAccountDir = { server ? null, email, keyType }: concatStringsSep "/" ([
|
||||||
|
accountDirRoot
|
||||||
|
(mkAccountHash { inherit server email keyType; })
|
||||||
|
] ++ optional (server != null) (
|
||||||
|
mkHost server
|
||||||
|
) ++ [
|
||||||
|
cfg.defaults.email
|
||||||
|
]);
|
||||||
|
accountDirRoot = "/var/lib/acme/.lego/accounts";
|
||||||
|
addr = concatStringsSep "@" [ "gensokyo" "arcn.mx" ];
|
||||||
|
in {
|
||||||
|
security.acme = {
|
||||||
|
acceptTerms = true;
|
||||||
|
defaults = {
|
||||||
|
email = mkDefault addr;
|
||||||
|
server = mkDefault "https://acme-v02.api.letsencrypt.org/directory";
|
||||||
|
keyType = mkDefault "ec384";
|
||||||
|
dnsProvider = mkDefault "cloudflare";
|
||||||
|
credentialFiles = {
|
||||||
|
CLOUDFLARE_EMAIL_FILE = config.sops.secrets.acme_cloudflare_email.path;
|
||||||
|
CLOUDFLARE_API_KEY_FILE = config.sops.secrets.acme_cloudflare_api_key.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
sops.secrets = let
|
||||||
|
accountDir = mkAccountDir { inherit (cfg.defaults) server email keyType; };
|
||||||
|
acmeSecret = {
|
||||||
|
sopsFile = mkDefault ./secrets/acme.yaml;
|
||||||
|
owner = "acme";
|
||||||
|
group = "nginx";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
acme_account_key = mkMerge [ acmeSecret {
|
||||||
|
path = accountDir + "/keys/${cfg.defaults.email}.key";
|
||||||
|
} ];
|
||||||
|
acme_cloudflare_email = acmeSecret;
|
||||||
|
acme_cloudflare_api_key = acmeSecret;
|
||||||
|
};
|
||||||
|
}
|
||||||
78
nixos/secrets/acme.yaml
Normal file
78
nixos/secrets/acme.yaml
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
acme_account_key: ENC[AES256_GCM,data:2UobeSLGw/GMXEeB+fdjG4jnDhWtm1j3U5SOZYwwJEF70g5z9DW1r2yqkj2/nBBgYUR6UvDo2f66iRCurRJtBPIf3KOOwtef1+MiD7QARgqDQoKCf8IUTS4SittHC0nYLFp08uZ3zXI8P4aqXwZdQT+DH5ARtZo4CaRWXa7JW2fkCe5v/Myz7LhvDZmpcitvPFTOpsZoHnUdPC2/cnTdUw/h2rEt1iNYVnchhHAt+AF9IMLZT5USotc9H4vpfXAqTcMwgI6tHvsJnnxorSVg7yfSYJUEiaFgYaqO6sITZffW+CXeuWdrg+EZB03VHmxJ5fwee2tCDyogSQyB6fDcnySK/bdzZhJBIE5fsfr9D7xuR6bUptuqjR/5STnqCYGO,iv:wJe/ta9hxeppqUI5hBErBS6rffhki8eiogSGwPDI/nE=,tag:gzJz4guO/hz9zxwSbs85Uw==,type:str]
|
||||||
|
acme_account_url: ENC[AES256_GCM,data:wsZvniUCTS8EcjCCKzUjKgeTCUiNNS5nGI4jq1N7R9tzr+Ng2o2rpMLkXsQhVHHlEA38pvLA/+pe,iv:XxS2kzFEWA33QQR+RkHQo0JN22MIliETYOqNSnS7rTc=,tag:GOJ9sgRx5u+7siCN7Fb3LQ==,type:str]
|
||||||
|
acme_cloudflare_email: ENC[AES256_GCM,data:AwOryq31gjMWyEbEOA==,iv:SHNpv3d8fj47o0t/k3Q5JwjJwlA+UKW8pJC5uUJjuJw=,tag:AZbV8wciD0b6o3lcRnywcQ==,type:str]
|
||||||
|
acme_cloudflare_api_key: ENC[AES256_GCM,data:nadEPYM6QTgRiP2gmER1wN9tPBiW6ToKaIcIOGfQkBXZvzrlMw==,iv:a+3ujE4Cobvh3VSXmSH4iLsXggM5m4uOPj8ygQvPRGc=,tag:h+ZwCPUiMca42nK1JybLFQ==,type:str]
|
||||||
|
sops:
|
||||||
|
shamir_threshold: 1
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age12ze362pu5mza6ef9akrptr7hfe4auaqul4rkta7kyy2tnrstqensgmujeq
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzVldrQU16K0tMYTlFcFoz
|
||||||
|
cVV0ZnJQbThFbncxdUdGaS84OHF0VXZmREZFCkdzcEc2elpZTHIwMWVKeS9KNnZp
|
||||||
|
RG9aM0cwYXgyczhXOWhOSXFhOTJEVjQKLS0tIDJ6cDNzaCtFVjBjeFp6cFNiUGtM
|
||||||
|
eFpJSzFtN3hrZnRSeHRPT1lqc2JhOXMKCu/RpSyXajKtbSqEUJwLH2KfxV8D88q3
|
||||||
|
KSD5j7oKxZvaX+41B5GKqKw9aIj2Tbsif6BlI8OLaF6o2JkDSEvUvA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1a2quf2ekkj94ygu7wgvhrvh44fwn32c0l2cwvgvjh23wst90s54szdsvgr
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHbXRDbk0yRmh6TUFvOVVC
|
||||||
|
YjM0Qno0eWRyT3d0eXp4eXhtR0drN252aW53CjVJdk9SMkd5dHhTdFQ0TzVBamlW
|
||||||
|
bG1SN1pBU0tCRDJyZGRZb0JIeDNNb2MKLS0tIENYOWd2d0psL2l3WWs0Slg1eHR0
|
||||||
|
NW54YTF0a1VOdDdjYjNXSjg3T0phd0UKgQR/MgKOm/WtjQBWxDxNkHshens3bARL
|
||||||
|
NE+CsmOmmpUtgbCPXO2oS1pPLZvd5v6Lgv6TQFradklDZcvdQvRaUg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age16klpkaut5759dut8mdm3jn0rnp8w6kxyvs9n6ntqrdsayjtd7upqlvw489
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArakp2SHpzT3NDd0tMcmZB
|
||||||
|
R3JLMUNHZWprbHNLa2E1QWZpaU92V1hpb1RNCmFaM3NGRGl6T0F5d2E5aEpQQnoz
|
||||||
|
Slc0ODdmVm9KWmdsZXpWM25pdDczbk0KLS0tIGt1TGM4ODZCd0lzVm54TWVzS2pq
|
||||||
|
TEdEOGdyQ2tBUEkxS0h0Yk1UbjJDWFUKtLA3MJAWMjfd03rKBaW3aIIMJS/OkRqL
|
||||||
|
Tu4JrcL5Lw/Tj7SU0dwxTsp+fGHuXsvQSO2z9BQmy9h7k7hSgSrRSw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2024-01-23T18:41:11Z"
|
||||||
|
mac: ENC[AES256_GCM,data:45SskHZXCnEMERHc3R4hD4cQ/ihWnUdFunTPgrBGYdo2fyCMbWyAdSQOMl0u6FkC+NbG66lzgBVXBPnNfw2GX8iVLJ3VQyRW5WA4YW1x1wLbocO+XkMtJmwtiPiOrJfjbs3mZfWmt5hQZI/gQsonQrccD9/UxWip+Hal4prhY50=,iv:1ka9lW88NoaAEgRp5TxC2L6q+kVR25HxxQGVsPlaGho=,tag:gPYKvKcZp5k4TA1Dfl8C8Q==,type:str]
|
||||||
|
pgp:
|
||||||
|
- created_at: "2024-01-23T17:18:24Z"
|
||||||
|
enc: |-
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
|
hQIMA82M54yws73UARAAmBYoYHSUmHR1gRvVlfaSaj2fu1Q4UxBfhj1gvu4SdvAZ
|
||||||
|
g6bZ108uFJR8XZX/P9SveA9ZBCmtu2Yrdtmp88q79l4A/pGWB15xF2TYFegjarED
|
||||||
|
ARGAry0yH9oxSOo30lB+1C21nwiJZg3NTOty6kE5Y01vsM7pddp8tvkIemJ4+MO0
|
||||||
|
aOkTrPCkoV7K9DTQ0OoEUI6U09F01hpFAOegHFWh6XAv3NDQXGA3tY1hYbi5SZ70
|
||||||
|
i1uSEljL2dQTajbcssoT8G+2238kbmT+qjIiIOD0I/BmjR3/4z1VwOY1mndHo63C
|
||||||
|
dTdZaXweG06HwJxlUoO1tvwcf5mw8ImQ10+qfpzBtAHF8JChRRPAgPta4yBUo334
|
||||||
|
XcspomSPIOcp1gLoRd37z4whdzc8UXseTzdF72gRlH/t6+cL0EMIapoIwcK+jKfZ
|
||||||
|
0Hw0vNyK2RCAnYI82vxzj56iGgNx4RMVsruibFIDqXqy4i8ZdBnTuJ2rsM1suaE6
|
||||||
|
q0/pjb0qtaUSaV5WNpXcH1Um5sc2zWzXg4au/fMFsLkWF+7EJuubz4cT86HSBBXG
|
||||||
|
OPssQI4ODxBI0YPPT+uBdEqE3O23zZ2Onv92KFGfuu/3ybKTBvRun4uv8vaBHecN
|
||||||
|
4bEVjeVtYu9DnAKVsRkvj207G3KYPEjQB2R1Jjqn9Wd8nSg8QmlkDFAaye6+tB7S
|
||||||
|
XgHkTeeVgCZD/EKSyDWm9zZ/2/JpL0BiBFY4lWhVnqczS+kPFyJpdX1UgTJUnhBr
|
||||||
|
ZyLY5IIQT0d/FYUHPAuhOF6ziLIV1ZYqN0/TMb96kWXT730lnPMn9Avt7bJFlvQ=
|
||||||
|
=31ty
|
||||||
|
-----END PGP MESSAGE-----
|
||||||
|
fp: CD8CE78CB0B3BDD4
|
||||||
|
- created_at: "2024-01-23T17:18:24Z"
|
||||||
|
enc: |-
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
|
hQEMA2W9MER3HLb7AQf9EP7uWwz9NmO3Cgvsw+dVKhGO4Ym2aNS2OfxuEf8nXlL3
|
||||||
|
dKf8M9FEF7daSlH0wETE5ZfwSE+UMqjJCxP+A9cCm9YW+5Y+4YAy/4oOPCCn4ggj
|
||||||
|
t5rwaVj9gfy8UzFibo060WOnBA0QCufChdm0FKAC6CdulrUGsi8NMFz48oVzPRoj
|
||||||
|
TPzetpVFIa9x7XpcVUo4lbt34JYvDnlVKsZA+wvNMzbnjwS2a5KBwDjsTlNdCyr/
|
||||||
|
5ayhifUUBcXRn/nGCRQ4zvL6ze09jkqwABNkGB9O37WnOFoyX1hfeDqMOHeQVstK
|
||||||
|
96VIa+H7LJamBZneAtQBUX8Wel07Sr/3JIkHcfg8K9JeAXePG5SIM251zkLkBOJj
|
||||||
|
zV3P98h2zAOBcJ3FBw0VlIJtegYSv/UxsmPaxxEghvBC4WVvDMahPw9lT/YlkUne
|
||||||
|
U4GZO3rNC+KFEUx1tlf3qE8IbioVJ9SJ+967uCmzng==
|
||||||
|
=i3ou
|
||||||
|
-----END PGP MESSAGE-----
|
||||||
|
fp: 65BD3044771CB6FB
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.8.1
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
meta,
|
meta,
|
||||||
|
lib,
|
||||||
access,
|
access,
|
||||||
...
|
...
|
||||||
}: {
|
}: let
|
||||||
|
inherit (lib.modules) mkIf mkMerge;
|
||||||
|
mediabox = access.systemFor "mediabox";
|
||||||
|
tei = access.systemFor "tei";
|
||||||
|
in {
|
||||||
imports = let
|
imports = let
|
||||||
inherit (meta) nixos;
|
inherit (meta) nixos;
|
||||||
in [
|
in [
|
||||||
|
|
@ -12,7 +17,10 @@
|
||||||
nixos.reisen-ct
|
nixos.reisen-ct
|
||||||
nixos.tailscale
|
nixos.tailscale
|
||||||
nixos.cloudflared
|
nixos.cloudflared
|
||||||
|
nixos.acme
|
||||||
nixos.nginx
|
nixos.nginx
|
||||||
|
nixos.access.global
|
||||||
|
nixos.access.kanidm
|
||||||
nixos.access.proxmox
|
nixos.access.proxmox
|
||||||
nixos.access.plex
|
nixos.access.plex
|
||||||
];
|
];
|
||||||
|
|
@ -33,10 +41,56 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.access = {
|
security.acme.certs = let
|
||||||
plex.url = let
|
inherit (config.services) nginx;
|
||||||
system = access.systemFor "mediabox";
|
inherit (nginx) access;
|
||||||
in "http://${system.networking.access.hostnameForNetwork.local}:32400";
|
in {
|
||||||
|
${access.kanidm.domain} = {
|
||||||
|
inherit (nginx) group;
|
||||||
|
extraDomainNames = mkMerge [
|
||||||
|
[ access.kanidm.localDomain ]
|
||||||
|
(mkIf config.services.tailscale.enable [ access.kanidm.tailDomain ])
|
||||||
|
];
|
||||||
|
};
|
||||||
|
${access.proxmox.domain} = {
|
||||||
|
inherit (nginx) group;
|
||||||
|
extraDomainNames = mkMerge [
|
||||||
|
[ access.proxmox.localDomain ]
|
||||||
|
(mkIf config.services.tailscale.enable [ access.proxmox.tailDomain ])
|
||||||
|
];
|
||||||
|
};
|
||||||
|
${access.plex.domain} = {
|
||||||
|
inherit (nginx) group;
|
||||||
|
extraDomainNames = [ access.plex.localDomain ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = let
|
||||||
|
inherit (config.services.nginx) access;
|
||||||
|
inherit (mediabox.services) plex;
|
||||||
|
inherit (tei.services) kanidm;
|
||||||
|
in {
|
||||||
|
access.plex = assert plex.enable; {
|
||||||
|
url = "http://${mediabox.networking.access.hostnameForNetwork.local}:32400";
|
||||||
|
};
|
||||||
|
access.kanidm = assert kanidm.enableServer; {
|
||||||
|
domain = kanidm.server.frontend.domain;
|
||||||
|
host = tei.networking.access.hostnameForNetwork.local;
|
||||||
|
port = kanidm.server.frontend.port;
|
||||||
|
ldapPort = kanidm.server.ldap.port;
|
||||||
|
};
|
||||||
|
virtualHosts = {
|
||||||
|
${access.kanidm.domain} = {
|
||||||
|
useACMEHost = access.kanidm.domain;
|
||||||
|
};
|
||||||
|
${access.proxmox.domain} = {
|
||||||
|
useACMEHost = access.proxmox.domain;
|
||||||
|
};
|
||||||
|
${access.plex.domain} = {
|
||||||
|
addSSL = true;
|
||||||
|
useACMEHost = access.plex.domain;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.network.networks.eth0 = {
|
systemd.network.networks.eth0 = {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
nixos.access.gensokyo
|
nixos.access.gensokyo
|
||||||
nixos.access.zigbee2mqtt
|
nixos.access.zigbee2mqtt
|
||||||
nixos.access.home-assistant
|
nixos.access.home-assistant
|
||||||
nixos.access.kanidm
|
|
||||||
nixos.vouch
|
nixos.vouch
|
||||||
nixos.kanidm
|
nixos.kanidm
|
||||||
nixos.mosquitto
|
nixos.mosquitto
|
||||||
|
|
@ -26,6 +25,10 @@
|
||||||
|
|
||||||
sops.defaultSopsFile = ./secrets.yaml;
|
sops.defaultSopsFile = ./secrets.yaml;
|
||||||
|
|
||||||
|
services.kanidm = {
|
||||||
|
server.openFirewall = true;
|
||||||
|
};
|
||||||
|
|
||||||
systemd.network.networks.eth0 = {
|
systemd.network.networks.eth0 = {
|
||||||
name = "eth0";
|
name = "eth0";
|
||||||
matchConfig = {
|
matchConfig = {
|
||||||
|
|
|
||||||
|
|
@ -20,3 +20,8 @@ output "acme_account_key" {
|
||||||
sensitive = true
|
sensitive = true
|
||||||
value = tls_private_key.acme_account_key.private_key_pem
|
value = tls_private_key.acme_account_key.private_key_pem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "acme_account_url" {
|
||||||
|
sensitive = true
|
||||||
|
value = tls_private_key.acme_account_key.id
|
||||||
|
}
|
||||||
|
|
|
||||||
49
tf/cloudflare_dns.tf
Normal file
49
tf/cloudflare_dns.tf
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
resource "cloudflare_api_token" "dyndns" {
|
||||||
|
name = "infra-dyndns"
|
||||||
|
policy {
|
||||||
|
# https://developers.cloudflare.com/api/tokens/create/permissions
|
||||||
|
permission_groups = [
|
||||||
|
"c8fed203ed3043cba015a93ad1616f1f", # Zone Read
|
||||||
|
"82e64a83756745bbbb1c9c2701bf816b", # DNS Read
|
||||||
|
"4755a26eedb94da69e1066d98aa820be", # DNS Write
|
||||||
|
]
|
||||||
|
resources = {
|
||||||
|
"com.cloudflare.api.account.zone.${cloudflare_zone.gensokyo-zone_zone.id}" = "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "cloudflare_dyndns_token" {
|
||||||
|
sensitive = true
|
||||||
|
value = cloudflare_api_token.dyndns.value
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "dyndns_record_name" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "cloudflare_record" "dyndns_a" {
|
||||||
|
name = var.dyndns_record_name
|
||||||
|
proxied = false
|
||||||
|
ttl = 300
|
||||||
|
type = "A"
|
||||||
|
value = "127.0.0.1"
|
||||||
|
zone_id = cloudflare_zone.gensokyo-zone_zone.id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "cloudflare_record" "dyndns_aaaa" {
|
||||||
|
name = var.dyndns_record_name
|
||||||
|
proxied = false
|
||||||
|
ttl = 300
|
||||||
|
type = "AAAA"
|
||||||
|
value = "::1"
|
||||||
|
zone_id = cloudflare_zone.gensokyo-zone_zone.id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "cloudflare_dyndns_record_a" {
|
||||||
|
value = cloudflare_record.dyndns_a.id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "cloudflare_dyndns_record_aaaa" {
|
||||||
|
value = cloudflare_record.dyndns_aaaa.id
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@ module "hakurei_system_records" {
|
||||||
local_v6 = "fd0a::be24:11ff:fec4:66a7"
|
local_v6 = "fd0a::be24:11ff:fec4:66a7"
|
||||||
local_subdomains = [
|
local_subdomains = [
|
||||||
"prox",
|
"prox",
|
||||||
|
"id",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,7 +31,6 @@ module "tewi_system_records" {
|
||||||
local_v4 = "10.1.1.39"
|
local_v4 = "10.1.1.39"
|
||||||
local_v6 = "fd0a::be24:11ff:fecc:6657"
|
local_v6 = "fd0a::be24:11ff:fecc:6657"
|
||||||
local_subdomains = [
|
local_subdomains = [
|
||||||
"id",
|
|
||||||
"mqtt",
|
"mqtt",
|
||||||
"z2m",
|
"z2m",
|
||||||
"home",
|
"home",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"data": "ENC[AES256_GCM,data:+OLe87CIr0i0eyw8xav9LVglS3SUF+CD5A7wr2EqOItsZhOnFyC3JzC/FR5GLlHQuix2Jdv6RWC6Qubsj6CVV+Ojxk5y1MFBYHTRSSvCR2NErb5mFn96NsPx0pUKtiYtDhk31GZClBrICNZd9J/CBWpcEuD8KQlvZHu/9lIp3dRepG9mo1F/bJC0NUO+eS9zds0tz0SmVNZn7FIz6+XK4DFUqCiFwMxqEAM9tkbRitkgaJFzP0nfVdtGSEnvvapnsFvneIW7yCPDBqNOjwIeyRgM1vyewvlf9lW2iL1dhv4gKvYmRvtEC8eq6LD9yK04N709SZUqxPpn9jO8QNIqHZgUsU0+9HymxSJmVvRZqaI1zS0HDAr4q+JuO+t1druEjZzyO5Pb9yNbXKcLK5x0ANOxhODnt5iQOnteq2KgSQWlgm5p0ol3WcDzlObMXXW+2R9KYwJ157AkkJck8d1QEtU8eSBsnJRBrdZwsaYzyfZ9M/GppzUIzHOGMIEByhskLIB7U+uR8K5eP70VvUyV4y2iQFdY5MxRrdtLMiQAe5RtLOMTTq5i6pZXpEF3hkGcYSVu2cHnioy1g4K4TPF4t3uiPZfGCQaz7jPssgwExpbkggz9efKYxADCV1otcqW3+0GUTHy+ZZorFJYhhINezQ8URXkGNr8b5rX12m1fb3i9HPb6AY0p10Oh5eetvBXVQK3oqrBYC63ZKCjMXHGkxAMFF/bLsjrppHaADTLld++u8ipVcamXBqBlVfIQGCpQkWRLcWX6MnPwkCNQQbWPYIHlEEjznF7S3jMKpBE56H+Pbaclejrr/ee7lFqcEBN5+P+WTVJqvTQ0f5W5Krq1O/Ouyrtp3ml00N+wZH3BMy/t+c03sE5rIv+/mdtF+wy0As5ibpC4ttTZ604N0bZwmd7PBhKHTXBvecOC8xofTvym7yoee23e5Q8WUVfOaz6Ph0rW/QvQSXUmdarPC2epz+9iTenGFvQ2gCKqUA==,iv:ZItahuq3XUdZdit6jpsTbedKPwb2cYw0omx33Rf6o9s=,tag:9sX7LQ58Z0qk9SSoPVuiCw==,type:str]",
|
"data": "ENC[AES256_GCM,data:B0yK5oRKy09y+IgkxVQgrTn4J1fD5crc8GPoJQfhaEi0iMmN7QhuVag8dyDAYVSQgeH/689hV5ugD11SKQqGqrpZ6VKMta7sATn4jykf6QD38R4jXbmRrvoEdgLzvCum+SAQ6DWR29uPaAKJt/02aOM5X+D2M+abwMEyW5CRfri2EvlQWlORd0PO/vSCJjgPbsXvXnJkzGj/mOjdMocL8e+d0uIkN57qSqSHdlZ1bFV/tqTjfTBaJ7wjJi1G8NywYl4cA8lyYyHqmTvWCvJ63OvDTfwQ7JjObjhcGAHvF4RyZV6nl9gBSwnYTdSd3aAbIBEPZwc5DQ6hO3i8p31XHcea2RbpHijjCY4CwxxplShlFGu5aYzwXGYQlDT5iOj9eir16Lx2B5wV8k8HP2wWzmo6gGziJDVa3bpeAnHxrWyfxUwVFXy/d5jbWmUkS7fUXqw9h0MdBmhERAylbQGLAEy4/kir74dlCxincIbVuRSpOWqGS4qDEvvBv7vYyWSjcOL/5df/azouMUwfXTb5JP5tZN2dx732SA4/e1nlGG5t+REM7XpXgUNjxoeh06eUN//3FhupEFbz9BnOeRdNNCPRhWZXSvTZjIXWT56bku+1+FJXojrH6y+yp253cVPN+pYKbSXWnqGUsPcr8d/nJgE71ICHNr+p3h2JpTYJM8vvOpdQI6fzz60dLbBcI13M3FC6ocsfPehXFo4n+HVzRNrMrzlrgJ44F2cQ1ZYr7OBKgBIf7i+3BnJ7UXEx9rSQ7RImyXN7i8ocD87vkUvr0og+7+IscYlaIsmhpr1cflI5oHkXsS3rVxBeiPH9P7TOc+5Pf1z5UCABW9Zg9yWBj+DGHS7/OnbrqkM+W8C7oojYDz+5AZSEiZMT0NCHbKp3UJzsn6jBLcdJWFk4t/Fh2+HBpj/5hlCPxh17dI2X6HBbSClPh3z6p37/WrMsnwg3Z5oJTK0wk+YEQv/NhD4VLGW3QvVOSKudQdI0nOcCMXxQ+2SG8pbQqPs86e7lXi8NI/uz6PQ+bT2gaQ==,iv:cdIQxTvksnA5ODSUcey/gWG/lluvFbzYLGkeBpW2vh0=,tag:A3ifsd2SsoS7tzjNsauczg==,type:str]",
|
||||||
"sops": {
|
"sops": {
|
||||||
"shamir_threshold": 1,
|
"shamir_threshold": 1,
|
||||||
"kms": null,
|
"kms": null,
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
"azure_kv": null,
|
"azure_kv": null,
|
||||||
"hc_vault": null,
|
"hc_vault": null,
|
||||||
"age": null,
|
"age": null,
|
||||||
"lastmodified": "2024-01-23T17:02:46Z",
|
"lastmodified": "2024-01-23T19:16:29Z",
|
||||||
"mac": "ENC[AES256_GCM,data:+Oh6p7p325mSuHEWSC2aSD/WvSCelTpY7RV9fBli2TCxeFLdDGt6XTLZykFDjMq+5kHmJU2z3qTZm2bs0IbQ2h3pN5O5vL2+jJ17o3iKGwWvoim+2Nj3JChrzmUCLzqx04ZxojMrli2Af4eF/hDSHS4dcqTSxh/GiZeIPnoQwdA=,iv:veIp9YJ/CADUHpitvg3WMBiYzC1pEvevC14AhytfiE4=,tag:k6oYO2g1ng3gFLt6AbGSrg==,type:str]",
|
"mac": "ENC[AES256_GCM,data:EiUCkJ3G8I2KzTgiL64ijJf0Xwx5Q+Fau/UfaI/4D3LRRj5/vvl/Y5am80C44Yf19GqX7TxGdaK2vWItVaGzAOBIi7WRG4xjWGUEFUBZjtmL2hsN3fc76VMmaLb1OoSYvTf+CfgUcji8ddBhbj1olB490yROWxKQ5C1YFsr2Ksw=,iv:KR4joteYBKh22U5UkWKeVO8df6k3yCEP6/vcoZE2E0k=,tag:CsfBWCWUtUz+Dyk5pbp43A==,type:str]",
|
||||||
"pgp": [
|
"pgp": [
|
||||||
{
|
{
|
||||||
"created_at": "2024-01-14T19:49:29Z",
|
"created_at": "2024-01-14T19:49:29Z",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue