chore(keycloak): cloudflared and vouch

This commit is contained in:
arcnmx 2024-03-18 19:10:43 -07:00
parent b8714cc674
commit 2eef6e5508
15 changed files with 303 additions and 229 deletions

View file

@ -138,6 +138,11 @@ in {
}; };
} }
(mkIf cfg.enable { (mkIf cfg.enable {
networking.firewall.interfaces.local = {
allowedTCPPorts = mkIf (cfg.settings.vouch.listen != "127.0.0.1") [
cfg.settings.vouch.port
];
};
systemd.services.vouch-proxy = { systemd.services.vouch-proxy = {
description = "Vouch-proxy"; description = "Vouch-proxy";
after = ["network.target"]; after = ["network.target"];

View file

@ -1,5 +1,12 @@
{config, lib, ...}: let {config, lib, ...}: let
inherit (lib.modules) mkForce; inherit (lib.modules) mkIf mkForce mkDefault;
inherit (config.lib.access) mkSnakeOil;
cfg = config.services.keycloak;
cert = mkSnakeOil {
name = "keycloak-selfsigned";
domain = hostname;
};
hostname = "sso.${config.networking.domain}";
in { in {
sops.secrets = let sops.secrets = let
commonSecret = { commonSecret = {
@ -9,13 +16,18 @@ in {
in { in {
keycloak_db_password = commonSecret; keycloak_db_password = commonSecret;
}; };
users.users.keycloak = { users = mkIf cfg.enable {
isSystemUser = true; users.keycloak = {
group = "keycloak"; isSystemUser = true;
group = "keycloak";
};
groups.keycloak = {
};
}; };
networking.firewall.interfaces.local.allowedTCPPorts = [ 80 ]; networking.firewall.interfaces.local.allowedTCPPorts = mkIf cfg.enable [
users.groups.keycloak = {}; (if cfg.sslCertificate != null then 443 else 80)
];
systemd.services.keycloak.serviceConfig.DynamicUser = mkForce false; systemd.services.keycloak.serviceConfig.DynamicUser = mkForce false;
services.keycloak = { services.keycloak = {
@ -29,8 +41,11 @@ in {
}; };
settings = { settings = {
hostname = "sso.${config.networking.domain}"; hostname = mkDefault hostname;
proxy = "edge"; proxy = mkDefault (if cfg.sslCertificate != null then "reencrypt" else "edge");
}; };
sslCertificate = mkDefault "${cert}/fullchain.pem";
sslCertificateKey = mkDefault "${cert}/key.pem";
}; };
} }

View file

@ -10,66 +10,102 @@ sops:
- recipient: age12ze362pu5mza6ef9akrptr7hfe4auaqul4rkta7kyy2tnrstqensgmujeq - recipient: age12ze362pu5mza6ef9akrptr7hfe4auaqul4rkta7kyy2tnrstqensgmujeq
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkRlA5L2JnSkpNVzZEOVNS YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXd1paVkdKa2NyL2NQVnc2
L3FLTlczZlhrZUxtbEpJcHVJdjFtYmJLeEdVCnA3WG5XSHpGaVlPT08ya3dCVnpa MXlvRTVYT1NIelZxc2g4WHE4bkoyeWVRK2hrClJCdk1Gck9RNGFHSEdCMkhXZXpq
aXorSHVndUUxRDFDdEttWURuNllxMWcKLS0tIFEycEtvK3REb1dyZDZxcHJheXU1 Z3Blcjl5MGRVVWUxRVdLVzNPeUhYVGMKLS0tIDcyQ0llbXhXVFMwMC9WOWlxYk51
U1pYY2ZTaDdheUZSc0V3bWNsNzNtMGcKi6F+m36wc4Sgn5lfa2GC6LQdGUqCPJ7g N3ZqbGtGMUp5UjhicUFCVmJtS0xyZ0EKp7ygEx0BkhNF55wkII4MUSnMILb7TR5m
jZVo/iNLE2gg2lIBFkFY1xBZJB0uPSeNnqWWc0eXm6kZL5u9WOvTXA== 2bzew7r7T000xEYLku8vf5nZCq6Bs3ei+BoD5/UZqpoaZGfaSjfPXQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age176uyyyk7veqnzmm8xzwfhf0u23m6hm02cldlfkldunqe6std0gcq6lg057
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxNkJWOW1rTldZZkg0TDhL
bzVrTnZFNVdrZXRMUk1MaUNNYlArMnJOc2hVCmJQai93eHE2UGp4c0M5d1RkTWlN
WmR4NG1VUFdTSWdmTnk3aWV5U1c2TlkKLS0tIEIweHNVOFdnU0JkcVBGMVJsTU0w
Y2EvUGU2N1FEUE53SXhFZ2lXL01zVEUKmKCWlLj09SZejQ6vRXug3BtsihbosSKS
Wdd8UTa+ejgSLwW21J1vaBKzfI/g+Icep9X/dZtXRnSufiyh6wbE2A==
-----END AGE ENCRYPTED FILE-----
- recipient: age10t6kc5069cyky929vvxk8aznqyxpkx3k5h5rmlyz83xtjmr22ahqe8mzes
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvSXNISCs5dDcxZnNLU0JB
Tjg4aWttalFYVElqSDIvbHFtcWhpWXlkSXlBClJmMVJQTVBQaldlV0NRTmZHNXFU
cWN6WjF1K0E1anJ2dXIvUUsySDBNSG8KLS0tIFFmM1ZiT0hxOC9qeHJ1TTBGVUlY
NlRnRk5IeGphWVg2L0lYckgvbGlQL3cKhzIjobf4AIXX9uYphJopPkbabElcLXxB
7u1lawclcOExBJ2TMxwBAaF/TpiBE5nF9yfF37+BMWW2czVw6bwZLA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1a2quf2ekkj94ygu7wgvhrvh44fwn32c0l2cwvgvjh23wst90s54szdsvgr - recipient: age1a2quf2ekkj94ygu7wgvhrvh44fwn32c0l2cwvgvjh23wst90s54szdsvgr
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxVU0zclMvSXdsYTRoUm9n YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTMzNkZTJaSFNuQ3hyYWVY
NTFhN05QOVgrM3B1UHR6ME1wUWF2cWRqUFdvCi8xY2JLK1lYUklRbngxWXBXcUF2 c3AxWEZLNk4yQjhrdDZocTVqSlhnbUdmWDBzCkJtNzQxNDFjUG1qb0NLblprNlJZ
RUE3eVJxdklKeXQvSDdDNDVNakRsTWcKLS0tIDJFUGFRU2pYeUdYVlVydm9QRzJp MWdHODFMeU54TUl0V3lOVVo4cjhySlUKLS0tIHJMT21JajZOSCtHOGFpVTM1MXEv
TFNvOERxTkUyQnhJZVZqR1pKa3I0TE0Kh4OqiSCyZm5cMyVjHabP6I0FN2hhME0l RFlIcnd2ZEE2aGs4eWZCU2pCV0poZ1EKweqd24UCyUwnfeltrL+ZJJS91Ufnmqjs
k2k0ssHtExdtewGvnuWIv+uYQMj86VGlCW3FDVTFRtWTFQ7n5eom/w== FPdOo2FDhdSHH+iv5B6ekd0JIpEV1sRwoxbLOzfXbx8xqWyyiQzAfw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age16klpkaut5759dut8mdm3jn0rnp8w6kxyvs9n6ntqrdsayjtd7upqlvw489 - recipient: age16klpkaut5759dut8mdm3jn0rnp8w6kxyvs9n6ntqrdsayjtd7upqlvw489
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4cmRRa3RlSG9UWnRqakgw YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCRWJ0c3VyNUYxK0M1b01K
K2twVHhwRENIbDhPblp1R1lxV1BqTk1pSG5jCkpqT2Z1VXVWc3Z4YlFZRWJybWV4 QnRYa1BhUmNTNVllakZTSlRlYUpvVnVjUWswCnJhaExMM3kySE9XS2pJYndCbjA3
MTh6Tmw5dHFGQkZ3aHZVa3Y0UFlZTWsKLS0tIDloRmFGbjNhUHBYRjg5OTZ3QWZJ cUJPZDA0TDVweCtRaVhVVmNBS0VIeGcKLS0tIDN5ME12WFBwL0FsdkJLMzNUM2lt
V2xpcDFjcVY0MTBPcFU1ZnNiSDlac0EKQGBx++pF7S8L/wC29sE+J/JZYTgZykZJ Wk5mYy85eW9IZFJXZzhhZGZYRndsV2MK8o7uJBtcm3WARDq6cIQxcN0lMFkijpEq
iRW6PMAxGci7WZx0GRqmDq2VL5GekHhmjlUDp9fSNAc3LIl3r9i8og== 0pGMN7cunnN3sa32GA6SP2lFa9ncn0AHkI8/c8h3q46o5VluJWH5+A==
-----END AGE ENCRYPTED FILE-----
- recipient: age13qgddr326g5je0fpq2r3k940vsr3fh9nlvl9xtcxk3xg2x0k3vsq7pvzaj
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCU1J0NFpDanNjWmcvYWw5
M25JcXRZdTN2ak5FTXNKNjJhaCtzcTIzaFJFCkVWWG9uSFNVckdFRzk0QUNydTZ5
U2hCcDQ1U3IrWnZQaUxTU2ErM1Iza1kKLS0tIFZ2dzNHSXZhMk9xNzd1bnQ4Y3J2
MmRFVStpUHZFQm5KVS9JT2UzandQUDAKzdRiWNaIDKhEczGLaRYONZXjCU9g9/V8
NOUXtD/S0nGR1csgur//q+rVknEoSkrX76Xj/wkKyDImkKMaPSMGjA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ktmx2szedfnpe5xumnzs8vkk0ffqgga6ved3drtksg9pye6ndsnsnqq488
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzbWlaTWorL3NWOGJSbFh0
YUZtMEQ2bkFtckZUemhmNXJQd3dGemxoT244Cm9GWFhMZ0NJbDE2WkQrU3VESldD
aHhvaGNCKzNzNllZZFlRWEpFWkpPU1EKLS0tIG5TdVRxSzBzcnpOUU9talRnT3U5
RkQvakRmdjB3ME1rbnNTWjVDQU5QSmcKi1KhB8zpSLlaCgSelaEYdtOGHFLlc+Z3
hagYdJqojaOYbTGVBkWAYK0Zfh++1/QbDYJH6ySjDC8mFFCqEdSuYQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2024-01-16T19:11:11Z" lastmodified: "2024-01-16T19:11:11Z"
mac: ENC[AES256_GCM,data:1J3dCx5ptr2ah2LbvoP/rcUzPlzm3wZvpWLffIvh7PriNJ6vx2xj5fFK9s2AhIunxAaef0KJLzwzcfNwxEkJO3M6QSf0UUw3wopah1W3ZKLE2H/Z8bNncaNzSuh6QODbYShSG2yK4HmQApd8R9NfKlAHsDno+aRhuh7OYM7CaLI=,iv:KzMfJDJOqYm2epLM6Epd44aRoU7uJcusCl6m6/+cDtQ=,tag:tQ8MQ1NWey4E1dFu2YnOQw==,type:str] mac: ENC[AES256_GCM,data:1J3dCx5ptr2ah2LbvoP/rcUzPlzm3wZvpWLffIvh7PriNJ6vx2xj5fFK9s2AhIunxAaef0KJLzwzcfNwxEkJO3M6QSf0UUw3wopah1W3ZKLE2H/Z8bNncaNzSuh6QODbYShSG2yK4HmQApd8R9NfKlAHsDno+aRhuh7OYM7CaLI=,iv:KzMfJDJOqYm2epLM6Epd44aRoU7uJcusCl6m6/+cDtQ=,tag:tQ8MQ1NWey4E1dFu2YnOQw==,type:str]
pgp: pgp:
- created_at: "2024-01-19T19:08:57Z" - created_at: "2024-03-19T02:39:12Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA82M54yws73UAQ//e7dXTAfUuvYIil1Z1xewbxo3Hu73cvlKMFyezV3Q/+Sg hQIMA82M54yws73UAQ//U7Yp3mV1AOEy2Nu0e3dnaoUiDcvUfoiHL+HVrPKFaDPO
NMDmw8sY1LDjrSdmiQIeJrl4If3ekU3ClR/3ZbjuZf/vuHx/Ys58P/wRc4PkKYgL +cvNyNYWvlGSYCJRHWviVJ+bSFr3yaxm7O/MN98JjyQwzmeQvsYOlzWo/6/3GlMG
XUmU8PVRmbMsGwP/eDCdPetX8Er8ja2+O+4pM3JGDRhrNJIq4hZba8kghFCzZAHX Cvhdad/AI3YQDIWbQw987zlP2Fs2lh3JXI0vKnTVXHcTE+GbqIO6NQOe4T+muG2H
xaSf+rjUjuEr95VbiTLQf3ss978qCKwnCwYHET78sdOocAhuwrrRJ9ejCj7bb8RZ FB9B+GU6yOxjdQKDs33tuai03VPZvSI3vAhDo2XRKjcfRjbvqGEXyrxYniq5L4hu
+Z3ehpTRniHtogJkwu3E/tAP9eI01Q4fM492flbMJ28Xs1XljJnpVsjvrc5P5jEx Ueb1qUZXKqiBCB7jxe7WKKwW/8h36yQ5mRtw9+CiH3xfYpUD65xmso2WB69UEBam
gP2p6O7Vduu5AXoBpjtNNxa2hlclTcfyqkTfeItsC5rrw2NQi+/8f9WP2nyne+6o jUzIRK8ltk0N2qjyrqgiIvksmon78L+f3AJZjp4dfOiwvr6rIJWt32YngHhxlZRT
TSIu92WaP2Bz5bBu8i4gZUcnIX3YaF5rXIyN2PAD66qkyWhWVjKKCmgj4+xftPKR K6hIihxfgPQ0ykque5gDk1fdXmhcBe5HEnyeqEXGeXqXdzZvh2Kr8+1dVrZJ2iHs
9/6BfpRDggrQx5kyMyJrT5jKTNctf5hU1Z+D+IpKnTeAxoJzAox1+hkumMXOkxLF NPQPPsnsAkWCe9VJyS0mcdv0IS1AEPvvEjvPHf8juYJRfv+jknllPagLjL1fa1Gz
5dTOQ2o3Ldkm5G58f3K/MqwFhh7wf1ilCWtJrCZ8UnppmH2iSlyBGhm1x62ac8YP e9p/VCguswwewp1LYtuhUF4atX36YKaL0c1NcnPYYAFKc8mmElCNaFK/V8YTOmWk
O0luHEDmjQ440VpJHszWEaC9j77J3weJORWaLOCAA7zsUvhggpuA7UXKlPZWkvzz OvDDcxBNlFKv8GO/vrAi4wTc8bkE1k+RMK78fPcv+Q2Y39vERZ2CpA6QWGcSCkBx
/+FYLs+u7CVKzlATenDMdhkZN+hYbb3bplPn/FKsfYG/DyTxh1z+nEcReEyPW2DS MfordIRj3zEUz2ZVL8B3sbdcmTfUGvO9RZJdBb9JGUlsfxw7slSRxejQRHCsnZHS
XgER8BSgT7bQjXW3PCy165Y0iJjG+LIsNsfLwt4DTZipXE4yssZXiIG0trYiQtY5 XgHtjB9nynq50IYygoiXRxB00JSwuvkz2pwRlWRlzWfYAMHwUZDeoRcP5VhBRXTu
ssSL3WJ0FX0O2iVBtDnMqAt4rNHBtzMmkNn+B7p57N5cejMQWCJy4zAm3t/0e7M= zEdcArNfsyKbqSymWkEaI01UBHoWzGO3mRwpwlzzzO328CT8e+d/Shlfr5rFgzs=
=c1Gq =C/Qz
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: CD8CE78CB0B3BDD4 fp: CD8CE78CB0B3BDD4
- created_at: "2024-01-19T19:08:57Z" - created_at: "2024-03-19T02:39:12Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQEMA2W9MER3HLb7AQf/bNiEr/4QggEnmB7uRoLatYt9HqZiL3CaFuT9zzEndwZy hQEMA2W9MER3HLb7AQf/c8LLLVhZ2Oax5gtFfnAbw3b9k7T/fNmxazzImzES5jIN
wAAiBj+Wvc+nCZfdBpntPvzeexFABJUhVbxC9x/DYLaThmXds1TrODL/7zC7l/Ta Bu8MIwyVGmPAqEsREMyiDMMsj0cWVOKQev5AxVX8UYWyw8PS8yR3/j5nZKhqWNnf
aL/C8JFj0U2zolmQ17mL6AyITJFbEnoLuHwcqRA6GHLHUf4wWp8m9bIbw2qem32d pQ6lgxRKElc+31kNbOZwnTc7dplRdq0LxQQCHYi+5bGeAY5YPlJRLYSh65AqjyA/
40QSmt6+zYjMjvVCJ3+nXHz4hv4Djld6FYKAQvLqzDi5l5xDTHmPtT2R58ZOwzs5 0iHDsGBfaJ/+ayzNQ8RGrEzCxkL62v5k8a88rPDt5MDy9M8zMOgXdip2InJ5SMCx
uuknL/B6WCSfBdKEJElcKY32yc2sy24qPlISfYlRgHK+YM3tHD9iNUlaQU1YZCrR EbsD2a7eEltFct+cAiBpgeKUjGa7e0+jthA5TIPD5UQLaanu328n0K1I/mn79J19
la4p70YfFxw8zsPMtmkbrnx+LuhCJJx/VQrbnG32DNJeAYm6LZSdqszbz73GyCRL VY/g/MA3OGCyDd1Buhc2inz2Aa4K8miCh2E0I4La/9JeAWOI08o/PRn0mjLlINk8
gtxd/Ka1AzGBnxVpqKMjghujomSf2AvaAhY+0xSr8ImY/CgSmfEprd+b+1naok4f qtmTAJP+CEcsIkW8pphzk5w66YfAUPUWKDPHHlG581EknIhXg2M8ecUIMSUNGsCm
ARVCCSZEQW1j3MLE2W5An4z2hdIaB0YNp2RUGAL9Jg== PrgY+5Mc07ttJmxO/uAmh+LTimWfdcCOFrozyebr4w==
=EXaM =Hodp
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 65BD3044771CB6FB fp: 65BD3044771CB6FB
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted

View file

@ -10,7 +10,7 @@
mediabox = access.nixosFor "mediabox"; mediabox = access.nixosFor "mediabox";
tei = access.nixosFor "tei"; tei = access.nixosFor "tei";
inherit (mediabox.services) plex; inherit (mediabox.services) plex;
inherit (tei.services) kanidm vouch-proxy; inherit (keycloak.services) vouch-proxy;
inherit (config.services) nginx tailscale; inherit (config.services) nginx tailscale;
in { in {
imports = let imports = let
@ -32,7 +32,6 @@ in {
nixos.access.global nixos.access.global
nixos.access.gensokyo nixos.access.gensokyo
nixos.access.vouch nixos.access.vouch
nixos.access.kanidm
nixos.access.freeipa nixos.access.freeipa
nixos.access.freepbx nixos.access.freepbx
nixos.access.unifi nixos.access.unifi
@ -72,22 +71,6 @@ in {
]) ])
]; ];
}; };
${access.kanidm.domain} = {
inherit (nginx) group;
extraDomainNames = mkMerge [
[access.kanidm.localDomain]
(mkIf access.kanidm.ldapEnable [
access.kanidm.ldapDomain
access.kanidm.ldapLocalDomain
])
(mkIf tailscale.enable [
access.kanidm.tailDomain
])
(mkIf (access.kanidm.ldapEnable && tailscale.enable) [
access.kanidm.ldapTailDomain
])
];
};
${access.unifi.domain} = { ${access.unifi.domain} = {
inherit (nginx) group; inherit (nginx) group;
extraDomainNames = mkMerge [ extraDomainNames = mkMerge [
@ -159,9 +142,6 @@ in {
]) ])
]; ];
}; };
"sso.${config.networking.domain}" = {
inherit (nginx) group;
};
}; };
services.nginx = let services.nginx = let
@ -172,14 +152,9 @@ in {
externalPort = 41324; externalPort = 41324;
}; };
access.vouch = assert vouch-proxy.enable; { access.vouch = assert vouch-proxy.enable; {
url = "http://${tei.lib.access.hostnameForNetwork.tail}:${toString vouch-proxy.settings.vouch.port}"; url = "http://${keycloak.lib.access.hostnameForNetwork.local}:${toString vouch-proxy.settings.vouch.port}";
useACMEHost = access.vouch.localDomain; useACMEHost = access.vouch.localDomain;
}; };
access.kanidm = assert kanidm.enableServer; {
inherit (kanidm.server.frontend) domain port;
host = tei.lib.access.hostnameForNetwork.local;
ldapEnable = false;
};
access.unifi = { access.unifi = {
host = tei.lib.access.hostnameForNetwork.local; host = tei.lib.access.hostnameForNetwork.local;
useACMEHost = access.unifi.domain; useACMEHost = access.unifi.domain;
@ -200,14 +175,6 @@ in {
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 = {
"sso.${config.networking.domain}" = {
useACMEHost = "sso.${config.networking.domain}";
locations."/".proxyPass = "http://${keycloak.lib.access.hostnameForNetwork.local}:80";
forceSSL = true;
};
${access.kanidm.domain} = {
useACMEHost = access.kanidm.domain;
};
${access.freepbx.domain} = { ${access.freepbx.domain} = {
local.enable = true; local.enable = true;
}; };

19
systems/keycloak/lxc.json Normal file
View file

@ -0,0 +1,19 @@
{
"lxc": {
"lxc.mount.entry": [
"/dev/net/tun dev/net/tun none bind,optional,create=file"
],
"lxc.idmap": [
"u 0 100000 8000",
"g 0 100000 8000",
"u 8000 8000 128",
"g 8000 8000 256",
"u 8128 108128 57406",
"g 8256 108256 57278",
"u 65534 65534 1",
"g 65534 65534 1",
"u 65535 165535 1",
"g 65535 165535 1"
]
}
}

View file

@ -1,4 +1,4 @@
{meta, ...}: { {meta, config, ...}: {
imports = let imports = let
inherit (meta) nixos; inherit (meta) nixos;
in [ in [
@ -6,8 +6,33 @@
nixos.base nixos.base
nixos.reisen-ct nixos.reisen-ct
nixos.keycloak nixos.keycloak
nixos.cloudflared
nixos.vouch
]; ];
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 = {
${keycloak.settings.hostname} = assert keycloak.enable; let
scheme = if keycloak.sslCertificate != null then "https" else "http";
port = keycloak.settings."${scheme}-port";
in {
service = "${scheme}://localhost:${toString port}";
originRequest.${if scheme == "https" then "noTLSVerify" else null} = true;
};
${vouch-proxy.domain}.service = assert vouch-proxy.enable; "http://localhost:${toString vouch-proxy.settings.vouch.port}";
};
};
};
sops.secrets.cloudflared-tunnel-keycloak = {
owner = config.services.cloudflared.user;
};
sops.defaultSopsFile = ./secrets.yaml; sops.defaultSopsFile = ./secrets.yaml;
systemd.network.networks.eth0 = { systemd.network.networks.eth0 = {

View file

@ -1,4 +1,4 @@
hello: ENC[AES256_GCM,data:RUCrfjPq790szP+p/etEBYjsJbVq+wGaquYc5EBEEeGH6lrxo7mQwmgtDtxEOQ==,iv:aNOzr8HjPVTADpWZS1J7LlSGM5cWW2dgYUPvsrQuOvM=,tag:aQoPsIqUmVaa6pEBAdxxxw==,type:str] cloudflared-tunnel-keycloak: ENC[AES256_GCM,data:nXqz6gys7c9UsOy1oiFGFIl/ra/Cf2hb+LLjXI4agEy9mXCAJlKKg7YzuNaHGAXkTKlrpp2lC0P7qNmI3zryTQKBa+LHTq5Lcj9ZSbSW9zhVVS6e155RcdDv/7j1lcZnVmynX+Dz5m8bz490IEuVme985+L9W/5/ksCnjNzUFiCkaxKwe/w2gGv6GdBVYqCFv1j4XBTNAA9D62uZLM5IATtbaam3yZvygWcDLZLpnI+D1Cd5UvOMpgEvdyvKxfaZEzbgkX6BP2mcw+jC9XM=,iv:1rJgyfj+0vIO9hi5U1IarWlaK/tlpAFHn/q7bhtqogg=,tag:fCCY9lxnFt/ImqDeBH0hvw==,type:str]
sops: sops:
shamir_threshold: 1 shamir_threshold: 1
kms: [] kms: []
@ -15,8 +15,8 @@ sops:
WkhIeEh1amh5K0hIb2FKZ0ppSGpBZlEKjF9ysJCX40H5vH4UuZSXryAThk3ipdlP WkhIeEh1amh5K0hIb2FKZ0ppSGpBZlEKjF9ysJCX40H5vH4UuZSXryAThk3ipdlP
RML2if3bz+uMXgw+zdEx8Ac6IcOM25K0gco6g/6r20WYbKz9og5JuA== RML2if3bz+uMXgw+zdEx8Ac6IcOM25K0gco6g/6r20WYbKz9og5JuA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2024-03-13T22:39:15Z" lastmodified: "2024-03-19T02:38:20Z"
mac: ENC[AES256_GCM,data:14X+ClZ3Rsvi9aETzjSvjIiKKq6cPOe7t3LrB+ln3FTB4Wf7Fsbhd8aOdYff3yKqTfcnZU2VzEAEFJGNNlkCLQe9PgbKwzfKMH2i5dc9WpgJ6wY2btAUMRp3ocLwGwiRj0Nx8XsvTBL/8qzccHZL0A7I/MmwMiqsIyVWycj679c=,iv:zL8/3+XdVbvWrC5ODKurwtVoY921kQqwocc/hPgDLWI=,tag:HSDA4nCyoKaYBdNNg0+9bA==,type:str] mac: ENC[AES256_GCM,data:OqqsVE2xKsCpIZqszpdBWl9jEToImVW/Vdb5p0HyqjUOL1NSdyRThxx7fft7RlL9Iqd340WrQ/F4kmQHr+4pIEBsKkwrWUh0sbVNz1uLXFasr1nXuhB32zCu6/gxW9fofT11aHBjnH6rLy6KTnXK56jiyaXKPc25EgzKC9aomR4=,iv:hmADJiouxO4dznlSbKXJcAJgRJKtiR5QlypWt3/I7o0=,tag:HBP0G5o30rZsj+2YpM5gkw==,type:str]
pgp: pgp:
- created_at: "2024-03-13T22:39:09Z" - created_at: "2024-03-13T22:39:09Z"
enc: |- enc: |-

View file

@ -40,27 +40,6 @@
nameValuePair host { nameValuePair host {
service = "http://${accessHostFor args}:${toString port}"; service = "http://${accessHostFor args}:${toString port}";
}; };
ingressForVouch = {
host ? system.services.vouch-proxy.domain,
port ? system.services.vouch-proxy.settings.vouch.port,
hostName,
system ? nixosFor hostName,
...
} @ args:
nameValuePair host {
service = "http://${accessHostFor args}:${toString port}";
};
ingressForKanidm = {
host ? system.services.kanidm.server.frontend.domain,
port ? system.services.kanidm.server.frontend.port,
hostName,
system ? nixosFor hostName,
...
} @ args:
nameValuePair host {
service = "https://${accessHostFor args}:${toString port}";
originRequest.noTLSVerify = true;
};
in { in {
sops.secrets.cloudflared-tunnel-apartment.owner = cfg.user; sops.secrets.cloudflared-tunnel-apartment.owner = cfg.user;
services.cloudflared = { services.cloudflared = {
@ -78,8 +57,6 @@ in {
inherit hostName; inherit hostName;
}) })
(ingressForHass {inherit hostName;}) (ingressForHass {inherit hostName;})
(ingressForVouch {inherit hostName;})
(ingressForKanidm {inherit hostName;})
]; ];
}; };
}; };

View file

@ -6,7 +6,6 @@
"/rpool/shared/mosquitto mnt/shared/mosquitto none bind,optional,create=dir", "/rpool/shared/mosquitto mnt/shared/mosquitto none bind,optional,create=dir",
"/rpool/shared/hass mnt/shared/hass none bind,optional,create=dir", "/rpool/shared/hass mnt/shared/hass none bind,optional,create=dir",
"/rpool/shared/postgresql mnt/shared/postgresql none bind,optional,create=dir", "/rpool/shared/postgresql mnt/shared/postgresql none bind,optional,create=dir",
"/rpool/shared/kanidm mnt/shared/kanidm none bind,optional,create=dir",
"/rpool/shared/unifi mnt/shared/unifi none bind,optional,create=dir", "/rpool/shared/unifi mnt/shared/unifi none bind,optional,create=dir",
"/dev/ttyZigbee dev/ttyZigbee none bind,optional,create=file", "/dev/ttyZigbee dev/ttyZigbee none bind,optional,create=file",
"/dev/net/tun dev/net/tun none bind,optional,create=file" "/dev/net/tun dev/net/tun none bind,optional,create=file"

View file

@ -5,7 +5,7 @@
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (config.services) kanidm mosquitto home-assistant; inherit (config.services) mosquitto home-assistant;
in { in {
imports = let imports = let
inherit (meta) nixos; inherit (meta) nixos;
@ -19,8 +19,6 @@ in {
nixos.access.zigbee2mqtt nixos.access.zigbee2mqtt
nixos.access.home-assistant nixos.access.home-assistant
nixos.access.unifi nixos.access.unifi
nixos.vouch
nixos.kanidm
nixos.unifi nixos.unifi
nixos.mosquitto nixos.mosquitto
nixos.home-assistant nixos.home-assistant
@ -43,10 +41,6 @@ in {
networking.firewall = { networking.firewall = {
interfaces.local.allowedTCPPorts = mkMerge [ interfaces.local.allowedTCPPorts = mkMerge [
(mkIf kanidm.enableServer [
kanidm.server.frontend.port
(mkIf kanidm.server.ldap.enable kanidm.server.ldap.port)
])
(mkIf home-assistant.enable [ (mkIf home-assistant.enable [
home-assistant.config.http.server_port home-assistant.config.http.server_port
]) ])

View file

@ -3,177 +3,177 @@ locals {
} }
resource "cloudflare_record" "kerberos_master_tcp" { resource "cloudflare_record" "kerberos_master_tcp" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "@" name = "@"
type = "SRV" type = "SRV"
ttl = 3600 ttl = 3600
data { data {
service = "_kerberos-master" service = "_kerberos-master"
proto = "_tcp" proto = "_tcp"
name = cloudflare_zone.gensokyo-zone_zone.zone name = cloudflare_zone.gensokyo-zone_zone.zone
priority = 0 priority = 0
weight = 100 weight = 100
port = 88 port = 88
target = local.idp_fqdn target = local.idp_fqdn
} }
} }
resource "cloudflare_record" "kerberos_master_udp" { resource "cloudflare_record" "kerberos_master_udp" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "@" name = "@"
type = "SRV" type = "SRV"
ttl = 3600 ttl = 3600
data { data {
service = "_kerberos-master" service = "_kerberos-master"
proto = "_udp" proto = "_udp"
name = cloudflare_zone.gensokyo-zone_zone.zone name = cloudflare_zone.gensokyo-zone_zone.zone
priority = 0 priority = 0
weight = 100 weight = 100
port = 88 port = 88
target = local.idp_fqdn target = local.idp_fqdn
} }
} }
resource "cloudflare_record" "kerberos_tcp" { resource "cloudflare_record" "kerberos_tcp" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "@" name = "@"
type = "SRV" type = "SRV"
ttl = 3600 ttl = 3600
data { data {
service = "_kerberos" service = "_kerberos"
proto = "_tcp" proto = "_tcp"
name = cloudflare_zone.gensokyo-zone_zone.zone name = cloudflare_zone.gensokyo-zone_zone.zone
priority = 0 priority = 0
weight = 100 weight = 100
port = 88 port = 88
target = local.idp_fqdn target = local.idp_fqdn
} }
} }
resource "cloudflare_record" "kerberos_udp" { resource "cloudflare_record" "kerberos_udp" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "@" name = "@"
type = "SRV" type = "SRV"
ttl = 3600 ttl = 3600
data { data {
service = "_kerberos" service = "_kerberos"
proto = "_udp" proto = "_udp"
name = cloudflare_zone.gensokyo-zone_zone.zone name = cloudflare_zone.gensokyo-zone_zone.zone
priority = 0 priority = 0
weight = 100 weight = 100
port = 88 port = 88
target = local.idp_fqdn target = local.idp_fqdn
} }
} }
resource "cloudflare_record" "kerberos_txt" { resource "cloudflare_record" "kerberos_txt" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "_kerberos" name = "_kerberos"
type = "TXT" type = "TXT"
ttl = 3600 ttl = 3600
value = "GENSOKYO.ZONE" value = "GENSOKYO.ZONE"
} }
resource "cloudflare_record" "kerberos_uri_tcp" { resource "cloudflare_record" "kerberos_uri_tcp" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "_kerberos" name = "_kerberos"
type = "URI" type = "URI"
priority = 0 priority = 0
data { data {
weight = 100 weight = 100
content = "krb5srv:m:tcp:${local.idp_fqdn}." content = "krb5srv:m:tcp:${local.idp_fqdn}."
} }
ttl = 3600 ttl = 3600
} }
resource "cloudflare_record" "kerberos_uri_udp" { resource "cloudflare_record" "kerberos_uri_udp" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "_kerberos" name = "_kerberos"
type = "URI" type = "URI"
priority = 0 priority = 0
data { data {
weight = 100 weight = 100
content = "krb5srv:m:udp:${local.idp_fqdn}." content = "krb5srv:m:udp:${local.idp_fqdn}."
} }
ttl = 3600 ttl = 3600
} }
resource "cloudflare_record" "kpasswd_tcp" { resource "cloudflare_record" "kpasswd_tcp" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "@" name = "@"
type = "SRV" type = "SRV"
ttl = 3600 ttl = 3600
data { data {
service = "_kpasswd" service = "_kpasswd"
proto = "_tcp" proto = "_tcp"
name = cloudflare_zone.gensokyo-zone_zone.zone name = cloudflare_zone.gensokyo-zone_zone.zone
priority = 0 priority = 0
weight = 100 weight = 100
port = 464 port = 464
target = local.idp_fqdn target = local.idp_fqdn
} }
} }
resource "cloudflare_record" "kpasswd_udp" { resource "cloudflare_record" "kpasswd_udp" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "@" name = "@"
type = "SRV" type = "SRV"
ttl = 3600 ttl = 3600
data { data {
service = "_kpasswd" service = "_kpasswd"
proto = "_udp" proto = "_udp"
name = cloudflare_zone.gensokyo-zone_zone.zone name = cloudflare_zone.gensokyo-zone_zone.zone
priority = 0 priority = 0
weight = 100 weight = 100
port = 464 port = 464
target = local.idp_fqdn target = local.idp_fqdn
} }
} }
resource "cloudflare_record" "kpasswd_uri_tcp" { resource "cloudflare_record" "kpasswd_uri_tcp" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "_kpasswd" name = "_kpasswd"
type = "URI" type = "URI"
priority = 0 priority = 0
data { data {
weight = 100 weight = 100
content = "krb5srv:m:tcp:${local.idp_fqdn}." content = "krb5srv:m:tcp:${local.idp_fqdn}."
} }
ttl = 3600 ttl = 3600
} }
resource "cloudflare_record" "kpasswd_uri_udp" { resource "cloudflare_record" "kpasswd_uri_udp" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "_kpasswd" name = "_kpasswd"
type = "URI" type = "URI"
priority = 0 priority = 0
data { data {
weight = 100 weight = 100
content = "krb5srv:m:udp:${local.idp_fqdn}." content = "krb5srv:m:udp:${local.idp_fqdn}."
} }
ttl = 3600 ttl = 3600
} }
resource "cloudflare_record" "ldap" { resource "cloudflare_record" "ldap" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "@" name = "@"
type = "SRV" type = "SRV"
ttl = 3600 ttl = 3600
data { data {
service = "_ldap" service = "_ldap"
proto = "_tcp" proto = "_tcp"
name = cloudflare_zone.gensokyo-zone_zone.zone name = cloudflare_zone.gensokyo-zone_zone.zone
priority = 0 priority = 0
weight = 100 weight = 100
port = 389 port = 389
target = local.idp_fqdn target = local.idp_fqdn
} }
} }
resource "cloudflare_record" "idp-ca" { resource "cloudflare_record" "idp-ca" {
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
name = "idp-ca" name = "idp-ca"
type = "CNAME" type = "CNAME"
ttl = 60 ttl = 60
value = local.idp_fqdn value = local.idp_fqdn
} }

View file

@ -33,7 +33,6 @@ module "hakurei_system_records" {
"freeipa", "freeipa",
"ldap", "ldap",
"pbx", "pbx",
"sso",
"smb", "smb",
"kitchen", "kitchen",
"yt", "yt",
@ -54,11 +53,12 @@ module "reimu_system_records" {
} }
module "keycloak_system_records" { module "keycloak_system_records" {
source = "./system/records" source = "./system/records"
name = "keycloak" name = "keycloak"
zone_id = cloudflare_zone.gensokyo-zone_zone.id zone_id = cloudflare_zone.gensokyo-zone_zone.id
zone_zone = cloudflare_zone.gensokyo-zone_zone.zone zone_zone = cloudflare_zone.gensokyo-zone_zone.zone
local_v4 = "10.1.1.48" local_v4 = "10.1.1.48"
local_v6 = "fd0a::be24:11ff:fec4:66ac"
} }
module "aya_system_records" { module "aya_system_records" {

View file

@ -28,6 +28,36 @@ output "cloudflare_tunnel_cname_hakurei" {
value = module.hakurei.cname value = module.hakurei.cname
} }
variable "cloudflare_tunnel_secret_keycloak" {
type = string
sensitive = true
}
module "keycloak" {
source = "./tunnel"
name = "keycloak"
secret = var.cloudflare_tunnel_secret_keycloak
account_id = var.cloudflare_account_id
zone_id = cloudflare_zone.gensokyo-zone_zone.id
subdomains = [
"sso",
"login",
]
}
output "cloudflare_tunnel_id_keycloak" {
value = module.keycloak.id
}
output "cloudflare_tunnel_token_keycloak" {
value = module.keycloak.token
sensitive = true
}
output "cloudflare_tunnel_cname_keycloak" {
value = module.keycloak.cname
}
variable "cloudflare_tunnel_secret_tewi" { variable "cloudflare_tunnel_secret_tewi" {
type = string type = string
sensitive = true sensitive = true
@ -42,7 +72,6 @@ module "tewi" {
subdomains = [ subdomains = [
"home", "home",
"id", "id",
"login",
"z2m", "z2m",
"unifi", "unifi",
] ]

View file

@ -4,9 +4,10 @@ variable "proxmox_container_template" {
} }
locals { locals {
proxmox_keycloak_vm_id = 107 proxmox_keycloak_vm_id = 107
proxmox_litterbox_vm_id = 106 proxmox_keycloak_config = jsondecode(file("${path.root}/../systems/keycloak/lxc.json"))
proxmox_litterbox_config = jsondecode(file("${path.root}/../systems/litterbox/lxc.json")) proxmox_litterbox_vm_id = 106
proxmox_litterbox_config = jsondecode(file("${path.root}/../systems/litterbox/lxc.json"))
proxmox_aya_vm_id = 105 proxmox_aya_vm_id = 105
proxmox_aya_config = jsondecode(file("${path.root}/../systems/aya/lxc.json")) proxmox_aya_config = jsondecode(file("${path.root}/../systems/aya/lxc.json"))
proxmox_reimu_vm_id = 104 proxmox_reimu_vm_id = 104
@ -367,7 +368,7 @@ EOT
} }
network_device { network_device {
bridge = "vmbr0" bridge = "vmbr0"
mac_address = "BC:24:11:3D:39:91" mac_address = "BC:24:11:3D:39:91"
} }
@ -493,7 +494,7 @@ EOT
} }
network_device { network_device {
bridge = "vmbr0" bridge = "vmbr0"
mac_address = "BC:24:11:33:19:04" mac_address = "BC:24:11:33:19:04"
} }
@ -573,3 +574,10 @@ EOT
ignore_changes = [started, unprivileged, initialization[0].dns, operating_system[0].template_file_id] ignore_changes = [started, unprivileged, initialization[0].dns, operating_system[0].template_file_id]
} }
} }
module "keycloak_config" {
source = "./system/proxmox/lxc/config"
connection = local.proxmox_reisen_connection
container = proxmox_virtual_environment_container.keycloak
config = local.proxmox_keycloak_config.lxc
}

View file

@ -1,5 +1,5 @@
{ {
"data": "ENC[AES256_GCM,data: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,iv:8whKSRvl1YFYXfZQpVTqrdUHcTg0Ar1vJygWG1cp2xc=,tag:uty8o9zad3AvS1teVSIDOg==,type:str]", "data": "ENC[AES256_GCM,data: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,iv:6vdvCs0371Zr1d/C6KHZkATVLFJRyyWuwtqEP8SkouU=,tag:QYh+Ufu8YIvvziHGLt/FZw==,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-03-04T16:53:42Z", "lastmodified": "2024-03-19T01:44:48Z",
"mac": "ENC[AES256_GCM,data:5L+DYEvVmO8RCQ7+dQVf9FT8Fud2Xys/xoo3s8UDS4a1H/dNTbPa9F4M5Tj8zVkVzms0+yerivpgl//LWteuXFWjHuT39Tcg8g5HCtHjijQz3bMcxp7Tx3CbrylK71ljO0LK6IeMF96s7B8VmfpueC5lmzmPUGFqaKZFtHGXhlg=,iv:bOjioDXBsQ0O+W5gArDm7W91LZWCzRAat0NYHnoqSEg=,tag:gIj85XVMKHt9zuPdZw15mQ==,type:str]", "mac": "ENC[AES256_GCM,data:c+4WUmXEs1r6C1riHHsMAwRyjf5Z58l1/f03Jc8L+komJevGpbSNTxBad3GOHnvFHB4M7ONZehlkEmaXEmTMJUN2LUs4ULU3wsRe/tD1BXs06Ktx8zuW3ym8ND/kfsu17/O5v951iZpDWWuk+ACsu4dnEDeIg27yXviUg4k3BVw=,iv:cVUlvEsXv8AAeDkw+B7aPNo+TQtNzUjO4lZHKge7pg8=,tag:WSRAk1xlVw8TaCxToAYr1g==,type:str]",
"pgp": [ "pgp": [
{ {
"created_at": "2024-01-14T19:49:29Z", "created_at": "2024-01-14T19:49:29Z",