From e26ee3b98cab9e1311fcc3803deff33dc3afc658 Mon Sep 17 00:00:00 2001 From: Joe Mou Date: Wed, 9 Oct 2024 13:47:31 -0400 Subject: Use Zitadel to replace Kanidm Kanidm development is kind of slow and conservative. Their frontend is lacking. The hope was Zitadel would solve some issues logging in to the Home Assistant app behind oauth2-proxy, but it doesn't really help. In particular, KeePassium is unable to password complete (login page reloads to username entry?). In any case, we probably prefer Zitadel so let's at least record it for now. Pocket ID is an interesting minimal alternative, but the Home Assistant app doesn't support passkeys. $ sudo rm -r /var/lib/kanidm/ --- hostnix/elmo/oidc.nix | 85 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 32 deletions(-) (limited to 'hostnix/elmo/oidc.nix') diff --git a/hostnix/elmo/oidc.nix b/hostnix/elmo/oidc.nix index b24b070..00d2fcf 100644 --- a/hostnix/elmo/oidc.nix +++ b/hostnix/elmo/oidc.nix @@ -1,38 +1,61 @@ -{ config, ... }: +{ lib, pkgs, ... }: { - services.kanidm = { - enableClient = true; - enableServer = true; - clientSettings = { - uri = "https://ki.mou.fo"; - }; - serverSettings = { - origin = "https://ki.mou.fo"; - domain = "ki.mou.fo"; - bindaddress = "[::1]:7368"; - trust_x_forward_for = true; - # Kanidm requires TLS even behind a reverse proxy. - tls_chain = "/run/credentials/kanidm.service/fullchain.pem"; - tls_key = "/run/credentials/kanidm.service/key.pem"; + services.postgresql = { + ensureDatabases = [ "zitadel" ]; + ensureUsers = [{ + name = "zitadel"; + ensureDBOwnership = true; + }]; + }; + + # CVE-2024-41952 as of 24.05. Leaks existence of usernames. + nixpkgs.config.permittedInsecurePackages = [ + "zitadel" + ]; + + services.zitadel = { + enable = true; + settings = { + # We seem to be unable to bind Zitadel to only the loopback interface. + Port = 9068; + ExternalPort = 443; + ExternalDomain = "zd.mou.fo"; + Database.postgres = { + Host = "127.0.0.1"; + Port = 5432; + Database = "zitadel"; + User.Username = "zitadel"; + User.SSL.Mode = "disable"; + }; }; + masterKeyFile = "/run/credentials/zitadel.service/master.key"; + # Zitadel only connects to Postgres over the network, so we need to + # configure passwords here and manually for the zitadel Postgres user. + extraSettingsPaths = [ "/run/credentials/zitadel.service/secrets.yaml" ]; }; - systemd.services.kanidm = { - # Kanidm runs as an unprivileged user that needs access to certificates. - serviceConfig.LoadCredential = let - certDir = config.security.acme.certs."ki.mou.fo".directory; - in - [ - "fullchain.pem:${certDir}/fullchain.pem" - "key.pem:${certDir}/key.pem" + systemd.services.zitadel = { + # Shim into PATH to avoid start-from-init which requires Postgres admin + # credentials. See https://github.com/zitadel/zitadel/issues/4304 + path = let + wrapper = pkgs.writeShellScriptBin "zitadel" + '' + shift + exec ${pkgs.zitadel}/bin/zitadel start-from-setup "$@" + ''; + in lib.mkBefore [ wrapper ]; + # Allow unprivileged zitadel user selective access to secrets. + serviceConfig.LoadCredential = [ + "master.key:/var/secrets/zitadel.key" + "secrets.yaml:/var/secrets/zitadel.yaml" ]; }; - services.nginx.virtualHosts."ki.mou.fo" = { + services.nginx.virtualHosts."zd.mou.fo" = { enableACME = true; forceSSL = true; - locations."/".proxyPass = "https://[::1]:7368"; + locations."/".proxyPass = "http://127.0.0.1:9068"; }; # The oauth2-proxy module has a magic nginx.virtualHosts option that rewrites @@ -46,20 +69,18 @@ nginx.domain = "op.mou.fo"; setXauthrequest = true; # let oauth2-proxy nginx module pass X-User/X-Email reverseProxy = true; - # Example nestled in https://kanidm.github.io/kanidm/stable/examples/kubernetes_ingress.html provider = "oidc"; - clientID = "oauth2-proxy"; - oidcIssuerUrl = "https://ki.mou.fo/oauth2/openid/oauth2-proxy"; + clientID = "288565372746006652@mou.fo"; + oidcIssuerUrl = "https://zd.mou.fo"; # Sets OAUTH2_PROXY_COOKIE_SECRET and OAUTH2_PROXY_CLIENT_SECRET. keyFile = "/var/secrets/oauth2-proxy.env"; # Ignore e-mail address. - scope = "openid profile"; email.domains = [ "*" ]; extraConfig = { - "code-challenge-method" = "S256"; - "whitelist-domain" = ".mou.fo"; # allowed redirects after authentication + code-challenge-method = "S256"; + whitelist-domain = ".mou.fo"; # allowed redirects after authentication # https://github.com/oauth2-proxy/oauth2-proxy/issues/1612#issuecomment-1099217761 - "oidc-email-claim" = "sub"; + oidc-email-claim = "sub"; }; }; -- cgit v1.3.1