M1: standalone Kerberos KDC on mail (realm CLOONAR.COM) + IdP-swap ADR #267
Labels
No labels
bug
enhancement
in-progress
needs-info
needs-triage
p0
ready-for-agent
ready-for-human
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/nixos#267
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of #266 (M1 of M1–M6). Stand up a standalone Kerberos KDC on
mailand write the ADR for the IdP swap.This is the first, fully additive step toward real desktop SSO. Nothing consumes the KDC when this lands — it is verifiable standalone with
kinitand revertible by removing one module.Design decisions already made (do not re-litigate)
These were resolved in a design session on #266. The ADR records them; the implementation follows them.
nb. LDAPuserPasswordstays the authoritative password store for every user and every other service.{SASL}password pass-through. The original proposal in #266 (userPassword: {SASL}user@REALM+ saslauthd) is rejected — see "Why" below. It is a fleet-wide mail outage, not anbchange.CLOONAR.COM.fw;nbreaches the KDC over the existing WireGuard tunnel. A dedicated tunnel comes later.sso.cloonar.com(M3 — not this issue).Scope — what to implement
hosts/mail/modules/kerberos.nix(new), imported fromhosts/mail/configuration.nix.services.kerberos_serverwith a single realmCLOONAR.COM, standalone (its own database — not LDAP-backed).security.krb5client config onmail: realmCLOONAR.COM,kdc = mail.cloonar.com,admin_server = mail.cloonar.com,default_realm = CLOONAR.COM, and a[domain_realm]mapping.cloonar.com→CLOONAR.COM.kadm5.aclgranting full rights to*/admin@CLOONAR.COM.networking.firewallonmail. Do not open 749 (kadmin) or 464 (kpasswd) — kadmin stays local-only viakadmin.local, and remote password change is not wanted yet.kdb5_util create -sis a one-time human step (see below). Creating it from an activation script would risk clobbering a live database on everynixos-rebuild switch, which onmailruns unattended via bento every 5 minutes.utils/modules/borgbackup.nix:59-63backs up/varwholesale with an exclude list. Confirm the state dir the chosen implementation uses (/var/lib/krb5kdcfor MIT,/var/lib/heimdalfor Heimdal) is not caught by an exclude, and add a comment in the module noting the dependency. Losing the KDC database means recreating every principal by hand.Explicitly out of scope — do not touch
hosts/mail/modules/openldap.nix— no ACL changes, no{SASL}, no schema changes.hosts/mail/modules/dovecot.nixandpostfix.nix— no change.auth_bindstaysno.services.saslauthd— not used.hosts/nb/*(that is M2),hosts/web-arm/*(that is M3).utils/modules/ldap-auth.nix— imported byweb-arm; leave it alone.No new SOPS secrets are needed for M1. The KDC master key lives in a stash file generated on the host; it is host state, not a deploy secret.
Why
{SASL}was rejected (record this in the ADR)hosts/mail/modules/dovecot.nix:15,23,28setsauth_bind = no,pass_attrs = mail=user,userPassword=password,default_pass_scheme = CRYPT. Dovecot binds ascn=vmail,ou=system,…, reads the rawuserPasswordvalue, and verifies it itself — it never asks slapd to perform a bind. A{SASL}value only works when slapd does the comparison, so rewritinguserPasswordwould hand Dovecot the literal string{SASL}dominik@CLOONAR.COMto CRYPT-compare. All IMAP and SMTP auth fordc=cloonar,dc=combreaks immediately. Postfix'ssmtpd_sender_login_mapschain has the same shape.Underneath that: Kerberos cannot derive principal keys from an existing crypt hash, so a full cutover would additionally require a coordinated password reset for every mail user in the tenant.
The GSSAPI bonuses in #266 (Dovecot/Thunderbird, fleet SSH) are also additive — they need a keytab and an extra
auth_mechanismsentry, not{SASL}— so nothing is forfeited by scoping.ADR — required deliverable
Write
docs/adr/0022-<slug>.md(0021 is the highest current). It covers the IdP swap as a whole, not just M1. It must record:auth_bind = nodefect above as the reason. This is the most important thing in the ADR.web-armmeasured 10 GB available of 15.5 GB, and Authelia itself uses 32 MB, so Keycloak's ~1 GB is not a constraint. The decision now rests solely on packaging: authentik is flake-only (nixpkgs#375509 still open) and would source-build Node + Go + Python on every version bump, on a host with no substituters that bento rebuilds every 5 minutes. Record what that costs: authentik's proxy provider maps onto the existing nginxauth_requestsetup, so choosing Keycloak buys the entire oauth2-proxy workstream at M5.fw;nbvia WireGuard; dedicated tunnel later). Note the consequence: off-VPN,nbcan still log in from the SSSD credential cache but gets no TGT and therefore no SSO.sso.cloonar.comand SPNEGO is proven end-to-end before any client is cut over.services.keycloakdoes not manage realms, clients, or LDAP federation declaratively. Todayhosts/web-arm/modules/authelia.nixholds all 8 OIDC clients and every policy in Nix, reviewable in a diff. Click-ops would move the auth layer's configuration out of git and into a database backup. Options arekeycloak-config-cli, realm-JSON import, or accepting click-ops. Must be answered before M4; does not block M1–M3.Follow the existing ADR style in
docs/adr/(prose, "Considered options", "Consequences"). UseCONTEXT.mdvocabulary.Verification
scripts/pre-commitdry-buildsmail. Do not runscripts/test-configurationmanually.Human steps after this PR merges and deploys
fw→mail:88(tcp+udp).mail, once:kdb5_util create -s -r CLOONAR.COM(master password → Bitwarden, not sops).kadmin.local -r CLOONAR.COM:addprinc dominik.polakovics— interactive, sets the Kerberos password.addprinc -randkey HTTP/sso.cloonar.comktadd -k /root/keycloak.keytab HTTP/sso.cloonar.com— run once only; a secondktaddrotates the key and silently invalidates the first keytab.base64 -w0 /root/keycloak.keytab→ add askeycloak-keytab-b64inhosts/web-arm/secrets.yaml, thenshred -uthe file. (Needed for M3, not M1.)kinit dominik.polakovics@CLOONAR.COMthenklistshows a TGT.Definition of done
hosts/mail/modules/kerberos.nixexists and is imported;maildry-builds clean.docs/adr/0022-*.mdwritten.openldap.nix,dovecot.nix,postfix.nix,ldap-auth.nix, or any host other thanmail(plus the ADR).Closes #<this issue>.