diff options
Diffstat (limited to 'hostnix/elmo')
| -rw-r--r-- | hostnix/elmo/oidc.nix | 86 |
1 files changed, 53 insertions, 33 deletions
diff --git a/hostnix/elmo/oidc.nix b/hostnix/elmo/oidc.nix index 0ed170e..b24b070 100644 --- a/hostnix/elmo/oidc.nix +++ b/hostnix/elmo/oidc.nix @@ -1,60 +1,80 @@ -{ ... }: +{ config, ... }: { - services.keycloak = { - enable = true; - database.passwordFile = "/var/secrets/keycloak.dbpass"; - settings = { - hostname = "kc.mou.fo"; - http-host = "127.0.0.1"; - http-port = 7567; - proxy = "edge"; + 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.nginx.virtualHosts."kc.mou.fo" = { + 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" + ]; + }; + + services.nginx.virtualHosts."ki.mou.fo" = { enableACME = true; forceSSL = true; - locations."/".proxyPass = "http://127.0.0.1:7567"; - # We can handle oauth2-proxy callbacks on any subdomain, but the Keycloak - # subdomain is the least arbitrary. - locations."/oauth2/".proxyPass = "http://127.0.0.1:4180"; + locations."/".proxyPass = "https://[::1]:7368"; }; - # Work around "upstream sent too big header" because of large tokens. - services.nginx.appendHttpConfig = '' - proxy_buffers 8 16k; - proxy_buffer_size 16k; - ''; - # The oauth2-proxy module has a magic nginx.virtualHosts option that rewrites - # nginx configs. It's mostly unhelpful, but we use it for brevity. In + # nginx configs. It can be heavy handed, but we use it for brevity. In # particular, it configures Traefik-like ForwardAuth authentication with # auth_request. Note if this resource is missing for whatever reason, the # module magic will fail open (auth_request unset). services.oauth2-proxy = { enable = true; cookie.domain = "mou.fo"; - nginx.domain = "kc.mou.fo"; - setXauthrequest = true; # include claims - email.domains = [ "*" ]; # allow any authenticated user - # https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/keycloak_oidc - provider = "keycloak-oidc"; + 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"; # Sets OAUTH2_PROXY_COOKIE_SECRET and OAUTH2_PROXY_CLIENT_SECRET. keyFile = "/var/secrets/oauth2-proxy.env"; - redirectURL = "https://kc.mou.fo/oauth2/callback"; + # Ignore e-mail address. + scope = "openid profile"; + email.domains = [ "*" ]; extraConfig = { - "oidc-issuer-url" = "https://kc.mou.fo/realms/prod"; - "whitelist-domain" = ".mou.fo"; + "code-challenge-method" = "S256"; + "whitelist-domain" = ".mou.fo"; # allowed redirects after authentication # https://github.com/oauth2-proxy/oauth2-proxy/issues/1612#issuecomment-1099217761 - "insecure-oidc-allow-unverified-email" = true; "oidc-email-claim" = "sub"; }; }; - # Kludge to bring up after KeyCloak (otherwise OIDC discovery fails). A simple - # ordering dependency isn't enough because keycloak.service is active before - # KeyCloak responds to requests. + # Kludge to bring up after Kanidm (otherwise OIDC discovery fails). A simple + # ordering dependency isn't enough because kandim.service is active before + # Kanidm responds to requests. Kanidm starts up quickly enough that boot up + # may work without this. systemd.services.oauth2-proxy.serviceConfig.RestartSec = 5; + + # It's somewhat overkill to assign oauth2-proxy its own domain. We can't use + # Kanidm's though, because it uses the /oauth2 path which the oauth2-proxy + # nginx module is hardcoded for (proxyPrefix is ignored); this module magic is + # also why we do not need to explicitly specify proxyPass. + services.nginx.virtualHosts."op.mou.fo" = { + enableACME = true; + forceSSL = true; + }; } |
