mirror of
https://github.com/nickolaj-jepsen/nixos.git
synced 2026-01-22 08:06:50 +01:00
feat(homelab): implement SSO
This commit is contained in:
parent
db85aeb044
commit
ab6f8e21dc
17 changed files with 245 additions and 48 deletions
|
|
@ -12,18 +12,15 @@
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://localhost:${toString port}";
|
proxyPass = "http://localhost:${toString port}";
|
||||||
};
|
};
|
||||||
basicAuthFile = "${config.age.secrets.arr-basic-auth.path}";
|
locations."/api" = {
|
||||||
|
proxyPass = "http://localhost:${toString port}";
|
||||||
|
extraConfig = ''
|
||||||
|
auth_request off;
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
# for linux ISOs
|
# for linux ISOs
|
||||||
age.secrets = {
|
|
||||||
arr-basic-auth = {
|
|
||||||
rekeyFile = ../../secrets/hosts/homelab/basic-auth.age;
|
|
||||||
owner = config.services.nginx.user;
|
|
||||||
inherit (config.services.nginx) group;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups."${group}" = {
|
users.groups."${group}" = {
|
||||||
members = [username];
|
members = [username];
|
||||||
};
|
};
|
||||||
|
|
@ -33,19 +30,37 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
|
oauth2-proxy.nginx.virtualHosts = {
|
||||||
|
"radarr.nickolaj.com".allowed_groups = ["arr"];
|
||||||
|
"sonarr.nickolaj.com".allowed_groups = ["arr"];
|
||||||
|
"prowlarr.nickolaj.com".allowed_groups = ["arr"];
|
||||||
|
"sabnzbd.nickolaj.com".allowed_groups = ["arr"];
|
||||||
|
"bazarr.nickolaj.com".allowed_groups = ["arr"];
|
||||||
|
};
|
||||||
nginx.virtualHosts = {
|
nginx.virtualHosts = {
|
||||||
"radarr.nickolaj.com" = mkVirtualHost 7878;
|
"radarr.nickolaj.com" = mkVirtualHost 7878;
|
||||||
"sonarr.nickolaj.com" = mkVirtualHost 8989;
|
"sonarr.nickolaj.com" = mkVirtualHost 8989;
|
||||||
"prowlarr.nickolaj.com" = mkVirtualHost 9696;
|
"prowlarr.nickolaj.com" = mkVirtualHost 9696;
|
||||||
"sabnzbd.nickolaj.com" = mkVirtualHost 8080;
|
"sabnzbd.nickolaj.com" = mkVirtualHost 8080;
|
||||||
|
"bazarr.nickolaj.com" = mkVirtualHost config.services.bazarr.listenPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
restic.backups.homelab.paths = [
|
restic.backups.homelab = {
|
||||||
"/var/lib/radarr"
|
paths = [
|
||||||
"/var/lib/sonarr"
|
"/var/lib/radarr"
|
||||||
"/var/lib/prowlarr"
|
"/var/lib/sonarr"
|
||||||
"/var/lib/sabnzbd"
|
"/var/lib/prowlarr"
|
||||||
];
|
"/var/lib/sabnzbd"
|
||||||
|
"/var/lib/bazarr"
|
||||||
|
];
|
||||||
|
exclude = [
|
||||||
|
# arrs logs and media cover
|
||||||
|
"/var/lib/*/.config/*/logs/"
|
||||||
|
"/var/lib/*/.config/*/MediaCover/"
|
||||||
|
"/var/lib/sabnzbd/Downloads/"
|
||||||
|
"/var/lib/sabnzbd/logs/"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
sabnzbd = {
|
sabnzbd = {
|
||||||
inherit user group;
|
inherit user group;
|
||||||
|
|
@ -59,6 +74,10 @@ in {
|
||||||
inherit user group;
|
inherit user group;
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
bazarr = {
|
||||||
|
inherit user group;
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
prowlarr.enable = true;
|
prowlarr.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@ _: let
|
||||||
dataDir = "/var/lib/flame";
|
dataDir = "/var/lib/flame";
|
||||||
domain = "flame.nickolaj.com";
|
domain = "flame.nickolaj.com";
|
||||||
in {
|
in {
|
||||||
services.restic.backups.homelab.paths = [dataDir];
|
services.restic.backups.homelab = {
|
||||||
|
paths = [dataDir];
|
||||||
|
exclude = ["/var/lib/flame/db_backups"];
|
||||||
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."${domain}" = {
|
services.nginx.virtualHosts."${domain}" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,6 @@ in {
|
||||||
owner = "zigbee2mqtt";
|
owner = "zigbee2mqtt";
|
||||||
group = "zigbee2mqtt";
|
group = "zigbee2mqtt";
|
||||||
};
|
};
|
||||||
z2m-basic-auth = {
|
|
||||||
rekeyFile = ../../secrets/hosts/homelab/basic-auth.age;
|
|
||||||
owner = config.services.nginx.user;
|
|
||||||
inherit (config.services.nginx) group;
|
|
||||||
};
|
|
||||||
mosquitto-zigbee2mqtt.rekeyFile = ../../secrets/hosts/homelab/mosquitto-zigbee2mqtt.age;
|
mosquitto-zigbee2mqtt.rekeyFile = ../../secrets/hosts/homelab/mosquitto-zigbee2mqtt.age;
|
||||||
mosquitto-sas.rekeyFile = ../../secrets/hosts/homelab/mosquitto-sas.age;
|
mosquitto-sas.rekeyFile = ../../secrets/hosts/homelab/mosquitto-sas.age;
|
||||||
mosquitto-ha.rekeyFile = ../../secrets/hosts/homelab/mosquitto-ha.age;
|
mosquitto-ha.rekeyFile = ../../secrets/hosts/homelab/mosquitto-ha.age;
|
||||||
|
|
@ -29,11 +24,17 @@ in {
|
||||||
];
|
];
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
restic.backups.homelab.paths = [
|
restic.backups.homelab = {
|
||||||
config.services.zigbee2mqtt.dataDir
|
paths = [
|
||||||
config.services.home-assistant.configDir
|
config.services.zigbee2mqtt.dataDir
|
||||||
];
|
config.services.home-assistant.configDir
|
||||||
|
];
|
||||||
|
exclude = [
|
||||||
|
"/var/lib/zigbee2mqtt/log/"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
oauth2-proxy.nginx.virtualHosts."zigbee.nickolaj.com".allowed_groups = ["iot-admin"];
|
||||||
nginx.virtualHosts = {
|
nginx.virtualHosts = {
|
||||||
"zigbee.nickolaj.com" = {
|
"zigbee.nickolaj.com" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
|
@ -42,7 +43,6 @@ in {
|
||||||
proxyPass = "http://localhost:${toString zigbee2mqttPort}";
|
proxyPass = "http://localhost:${toString zigbee2mqttPort}";
|
||||||
proxyWebsockets = true;
|
proxyWebsockets = true;
|
||||||
};
|
};
|
||||||
basicAuthFile = "${config.age.secrets.z2m-basic-auth.path}";
|
|
||||||
};
|
};
|
||||||
"ha.nickolaj.com" = {
|
"ha.nickolaj.com" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgsUnstable,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
age.secrets.netdata-claim-token.rekeyFile = ../../secrets/netdata-claim-token.age;
|
|
||||||
|
|
||||||
services.netdata = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgsUnstable.netdataCloud;
|
|
||||||
claimTokenFile = "${config.age.secrets.netdata-claim-token.path}";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -27,6 +27,9 @@
|
||||||
adminpassFile = "${config.age.secrets.nextcloud-admin-pass.path}";
|
adminpassFile = "${config.age.secrets.nextcloud-admin-pass.path}";
|
||||||
dbtype = "pgsql";
|
dbtype = "pgsql";
|
||||||
};
|
};
|
||||||
|
extraApps = {
|
||||||
|
inherit (config.services.nextcloud.package.packages.apps) sociallogin;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,11 @@ _: {
|
||||||
|
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
recommendedTlsSettings = true;
|
||||||
|
recommendedOptimisation = true;
|
||||||
recommendedProxySettings = true;
|
recommendedProxySettings = true;
|
||||||
|
recommendedGzipSettings = true;
|
||||||
|
recommendedBrotliSettings = true;
|
||||||
};
|
};
|
||||||
security.acme = {
|
security.acme = {
|
||||||
acceptTerms = true;
|
acceptTerms = true;
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,4 @@
|
||||||
postgresql.enable = true;
|
postgresql.enable = true;
|
||||||
postgresqlBackup.enable = true;
|
postgresqlBackup.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
52
hosts/homelab/prometheus.nix
Normal file
52
hosts/homelab/prometheus.nix
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
hostname,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
mkScrapeConfig = name: {
|
||||||
|
job_name = name;
|
||||||
|
static_configs = [
|
||||||
|
{
|
||||||
|
labels = {
|
||||||
|
instance = hostname;
|
||||||
|
};
|
||||||
|
|
||||||
|
targets = [
|
||||||
|
"${toString config.services.prometheus.exporters.${name}.listenAddress}:${toString config.services.prometheus.exporters.${name}.port}"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
age.secrets.grafana-cloud-prometheus-api-key = {
|
||||||
|
rekeyFile = ../../secrets/grafana-cloud-prometheus.age;
|
||||||
|
owner = "prometheus";
|
||||||
|
group = "prometheus";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.prometheus = {
|
||||||
|
enable = true;
|
||||||
|
enableAgentMode = true;
|
||||||
|
globalConfig.scrape_interval = "1m";
|
||||||
|
remoteWrite = [
|
||||||
|
{
|
||||||
|
url = "https://prometheus-prod-01-eu-west-0.grafana.net/api/prom/push";
|
||||||
|
basic_auth = {
|
||||||
|
username = "432120";
|
||||||
|
password_file = "${config.age.secrets.grafana-cloud-prometheus-api-key.path}";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
scrapeConfigs = [
|
||||||
|
(mkScrapeConfig "node")
|
||||||
|
];
|
||||||
|
|
||||||
|
exporters.node = {
|
||||||
|
enable = true;
|
||||||
|
extraFlags = [
|
||||||
|
"--web.disable-exporter-metrics"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
105
hosts/homelab/sso.nix
Normal file
105
hosts/homelab/sso.nix
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
{config, pkgsUnstable, ...}: let
|
||||||
|
port = 9190;
|
||||||
|
rootDomain = "nickolaj.com";
|
||||||
|
zitadelDomain = "sso.${rootDomain}";
|
||||||
|
oathproxyDomain = "oauth2-proxy.${rootDomain}";
|
||||||
|
in {
|
||||||
|
age.secrets.zitadel-master = {
|
||||||
|
rekeyFile = ../../secrets/hosts/homelab/zitadel-master.age;
|
||||||
|
owner = config.services.zitadel.user;
|
||||||
|
};
|
||||||
|
age.secrets.oauth2-proxy = {
|
||||||
|
rekeyFile = ../../secrets/hosts/homelab/oauth2-proxy-keyfile.age;
|
||||||
|
owner = "oauth2-proxy";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."${zitadelDomain}" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString port}";
|
||||||
|
extraConfig = ''
|
||||||
|
grpc_pass grpc://127.0.0.1:${toString port};
|
||||||
|
grpc_set_header Host $host:$server_port;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.nginx.virtualHosts."${oathproxyDomain}" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/" = {
|
||||||
|
proxyWebsockets = true;
|
||||||
|
proxyPass = "http://127.0.0.1:4180";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
ensureDatabases = ["zitadel"];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "zitadel";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
ensureClauses.login = true;
|
||||||
|
ensureClauses.superuser = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.zitadel = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgsUnstable.zitadel;
|
||||||
|
masterKeyFile = config.age.secrets.zitadel-master.path;
|
||||||
|
settings = {
|
||||||
|
Port = port;
|
||||||
|
Database.postgres = {
|
||||||
|
Host = "/var/run/postgresql/";
|
||||||
|
Port = 5432;
|
||||||
|
Database = "zitadel";
|
||||||
|
User = {
|
||||||
|
Username = "zitadel";
|
||||||
|
SSL.Mode = "disable";
|
||||||
|
};
|
||||||
|
Admin = {
|
||||||
|
Username = "zitadel";
|
||||||
|
SSL.Mode = "disable";
|
||||||
|
ExistingDatabase = "zitadel";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
ExternalDomain = zitadelDomain;
|
||||||
|
ExternalPort = 443;
|
||||||
|
ExternalSecure = true;
|
||||||
|
};
|
||||||
|
steps.FirstInstance = {
|
||||||
|
InstanceName = "Fireproof Auth";
|
||||||
|
Org = {
|
||||||
|
Name = "Fireproof Auth";
|
||||||
|
Human = {
|
||||||
|
UserName = "nickolaj1177@gmail.com";
|
||||||
|
FirstName = "Nickolaj";
|
||||||
|
LastName = "Jepsen";
|
||||||
|
Email.Verified = true;
|
||||||
|
Password = "Password1!";
|
||||||
|
PasswordChangeRequired = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
LoginPolicy.AllowRegister = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.oauth2-proxy = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgsUnstable.oauth2-proxy;
|
||||||
|
provider = "oidc";
|
||||||
|
reverseProxy = true;
|
||||||
|
redirectURL = "https://${oathproxyDomain}/oauth2/callback";
|
||||||
|
validateURL = "https://${zitadelDomain}/oauth2/";
|
||||||
|
oidcIssuerUrl = "https://${zitadelDomain}:443";
|
||||||
|
keyFile = config.age.secrets.oauth2-proxy.path;
|
||||||
|
nginx.domain = oathproxyDomain;
|
||||||
|
email.domains = ["*"];
|
||||||
|
extraConfig = {
|
||||||
|
whitelist-domain = ".${rootDomain}";
|
||||||
|
cookie-domain = ".${rootDomain}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,13 @@ in {
|
||||||
ROCKET_PORT = 8222;
|
ROCKET_PORT = 8222;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
restic.backups.homelab.paths = ["/var/lib/vaultwarden"];
|
restic.backups.homelab = {
|
||||||
|
paths = ["/var/lib/vaultwarden"];
|
||||||
|
exclude = [
|
||||||
|
"/var/lib/vaultwarden/icon_cache"
|
||||||
|
"/var/lib/vaultwarden/tmp"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
nginx.virtualHosts."${domain}" = {
|
nginx.virtualHosts."${domain}" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
|
|
||||||
BIN
secrets/grafana-cloud-prometheus.age
Normal file
BIN
secrets/grafana-cloud-prometheus.age
Normal file
Binary file not shown.
|
|
@ -1,7 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 uxq+Zw O7Lgl8nCBN+7PkfnDJg1QlJuJsIWHsC0ph5HRvc+U3E
|
|
||||||
bdllRkmn3RDwg1DVPSHLtYWfay/Y+hUeCtdiCYc1rDM
|
|
||||||
-> JC5p)q|.-grease J<5Gb -#' }(d &;SYO
|
|
||||||
9sFJvUrPneffSRN4a5VLMZBMJYluYh7efNGdJHnEnDLS2NJt33px
|
|
||||||
--- Ct3YI+Fb2sCve9NRhIMZfAlDEN0jANs6kJREaSeRxUo
|
|
||||||
IÇ|#+ÎR :Êù
õËO¤FÞY\ìÝΤcË|ÃX‹éÓ²¸Fm˰˜X«¼©/Oâȃ‹IŠ]Q<>¡5<>Ýtë!ö¡v‚SîVRÜM»˜×„<C397>42ocüözMFX »Ý½Ñ’¡+ÿ™€Þ$#»Ii<49>üóaÇ(¾ÚK<C39A><4B>8û™Ï¦¡×̦Ùñi£ ñø2þô2ó}ÐЦO°Ý@
zñqÕPº
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,8 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 uxq+Zw QFvSKN7maaWY8fYzwxBASBvTXg55zUhkZLJZVeQCBSg
|
||||||
|
tNvUOsiH0p1QfaAFbj1XqNmOUijykTaEdmxohFuNqlQ
|
||||||
|
-> tqn,r-grease FV& }tddM
|
||||||
|
vfFh7GoVlDh4YaZkFvROgw
|
||||||
|
--- SCregMmWnU6Ihuzv8E14/jnXY3Kd09235BvQZXePLRI
|
||||||
|
<EFBFBD>d6ÿȤ¤ÎN/,€—na<6E>1ŽÝ儌 RÌì$çÂ4HãU±'Q¯
|
||||||
|
<EFBFBD>xA[s¤—çv·2@Ú
»9{<7B>øÚÜ
”èVl=ÿ)æX~DÝA[¹Ÿuðn…² ѰiÄ‹ÿßûßÚ¶<C39A>ø<EFBFBD>ŒtÜëMXÒmklu]-«)<29>߬¥‰*i˜0Ù”ß ëŸ°Ñ¿´$½<ÁÑcL,¾ªµ-{¬ò»Ø<Í<>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 uxq+Zw g1Pw9Cgly2Wy9jiaKGqzVCJOuDDPfxfxDLe0XIyTtgU
|
||||||
|
vnYYw7sfYFc5hBI8ub5hzEXJaK04vno+uUChpkd1g9s
|
||||||
|
-> q,.q!V-grease 9$zhS U^zTl
|
||||||
|
nJEewmCjlrNA+8UTjveja2AYbl481OTdb6JkaZMr
|
||||||
|
--- rw1uP9RF+ehWosrklvIK9CbcKbwc9founpsG0XEXcgk
|
||||||
|
Z _8x†<EFBFBD>O<EFBFBD>e¯}²êklK¸ÏÑË
l>qžxŠŒÔd;ÐÛÎz&-µœ<>º
—>ÕÓ`÷0å_¬¥¼æ£3
|
||||||
BIN
secrets/hosts/homelab/oauth2-proxy-keyfile.age
Normal file
BIN
secrets/hosts/homelab/oauth2-proxy-keyfile.age
Normal file
Binary file not shown.
10
secrets/hosts/homelab/zitadel-master.age
Normal file
10
secrets/hosts/homelab/zitadel-master.age
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> X25519 8fy15guw0en6anMwXtYtgNORD8Lj5RiymCgYZqMPoHo
|
||||||
|
AQJP0q/gkG/JbwuUCCeILemcGM8sgXVsPzTyZK2Gm14
|
||||||
|
-> piv-p256 q3LNVw A+5W/lITCh0xb5xDxwQQWCjfhKrAEFU1Ix/SwbKjGxSG
|
||||||
|
kSentadMboREK630i0dAp/NWcgta2BDO878p6Rxg1vU
|
||||||
|
-> ?/=3-grease x7td
|
||||||
|
3S2C9b7mavQzhSWlkEzioYuD2+HmjkXdiyKMgkd1KwUw6Jz/FoT6+skE5wXVT0jA
|
||||||
|
q9B0aa66NhAoT7WKxlqvrUJPnjq9QuFeV7UNN3PCG1pstkIk+s4
|
||||||
|
--- 2B0VffwckYQT11chc0laW9oRHaaZSy3wrnjP0xe/Yrc
|
||||||
|
»I>Q}Zz’<7A>'¶z=„`<14>Æ»@ƒŠ„˜ÉÀ]±48¹°Z<C2B0>ÀLz‹pƒk^;×IÛ—áH¸ŽÚr©Ñ–o:Ú
|
||||||
Loading…
Add table
Add a link
Reference in a new issue