feat(nb): SSSD LDAP identity + Kerberos login alongside local dominik #270
No reviewers
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!270
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/269"
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?
M2 of #266 / ADR-0022. Adds
hosts/nb/modules/ldap-login.nixand imports it fromhosts/nb/configuration.nix.id_provider = ldapagainstldap.cloonar.com,auth_provider = krb5against the KDC onmail,services.sssd.kcm = true,cache_credentials = true, plussecurity.krb5client config,pam_mkhomedirfor the first graphical login, and system-level SPNEGO policy for Firefox and Chromium.Diff is 2 files: the new module, and
hosts/nb/configuration.nix(+1 import, +2 persistence entries). Nothing outsidehosts/nb/.⚠️ Not dry-built — please run the gate before this lands
The agent sandbox has no Nix at all (
nix-instantiate: command not found), soscripts/test-configuration nbcould not run and the commit used--no-verify.nbdeploys unattended every 5 minutes, so please dry-build before merging:To compensate, every option name was verified verbatim against
release-26.05source rather than from memory:nixos/modules/services/misc/sssd.nix,security/pam.nix,security/krb5/{default,krb5-conf-format}.nix,services/display-managers/sddm.nix,programs/firefox.nix, and SSSD 2.13's ownsrc/config/cfg_rules.ini. That verification caught three defects in the issue's spec (below).Coexistence / lockout safety
users.users.dominikis untouched — uid,/home/dominik, itshashedPassword,hosts/nb/users/dominik.nix, and all foursops.secrets.*.owner = \"dominik\"declarations. Nousers.users/users.groupsentry is added for the LDAP account; it resolves through NSS. Nowheel/sudo for it.utils/modules/ldap-auth.nixis not edited, soweb-armis out of the blast radius.pam_sssis required nowhere. Fromnixos/modules/security/pam.nix:pam_unix.so(sufficient,try_first_pass likeauth) is listed beforepam_sss.so(sufficient);autoOrderRulesassigns order by list position, sopam_unixruns first and short-circuits for a local user.pam_sss.sosufficientfirst,pam_unix.sorequiredlast (upstream's own comment explains why).sufficientdiscards failures, so all three of sssd-healthy (USER_UNKNOWN), sssd-dead (AUTHINFO_UNAVAIL) and network-down are ignored andpam_unixsucceeds from/etc/passwd.sssdStrictAccessis left unset, so the strict[default=bad …]control is not used./etc/nsswitch.confisfiles sss …(mkBefore [ \"files\" ]), so a hung sssd cannot block localgetpwnam.Three deliberate divergences from the issue
Each has an in-file comment explaining why, so the reasoning is not lost.
krb5_store_password_if_offline, notkrb5_store_password_if_no_ccache. The spelling in the issue is not an SSSD option — it is absent from sssd 2.13'scfg_rules.ini, andsss_ini_call_validators()'s return is discarded inmonitor.c, so the daemon would have started, loggedAttribute ... is not allowed, and silently ignored the line. Worth correcting in the issue so the next agent doesn't reintroduce it.security.pam.services.login.makeHomeDir, not.sddm.sddm.nixsetsuseDefaultRules = falseand supplies its own rules, whilemakeHomeDironly injectspam_mkhomedir.sointo the default session rule list (rules = lib.optionalAttrs cfg.useDefaultRules) — sosddm.makeHomeDirrenders nothing. SDDM's session stack isinclude login, sologin.makeHomeDiris what actually creates the home directory.enumerateis not set. It cannot do what it was asked for on NixOS:system.nssModulesonly reaches nsncd's ownLD_LIBRARY_PATH, and the nscd wire protocol has no enumeration request, sogetpwent()— which is how SDDM builds its user list — never sees SSSD. Enumeration would still walk the directory every few minutes, a repeating failing LDAP round trip off-VPN. Typing the username at the SDDM prompt is the fallback the issue pre-approved. Single lookups are unaffected.Two additions beyond the issue's scope
Both are
hosts/nb-only and additive; flagging them explicitly since the issue didn't ask for either./var/lib/sss/{db,secrets}.nb's root is tmpfs and the sssd unit'sStateDirectory=covers only/var/lib/sssd(the rendered config);/var/lib/sss/*is a plainmkdir -pinpreStart. Without this the offline cache is wiped on every reboot, so a reboot off-VPN would leavedominik.polakovicsunable to log in at all — defeatingcache_credentials = true. Only those two subdirs are persisted;pubconf/,mc/,pipes/,gpo_cache/are runtime-only. Recovery note for a channel rollback (newer sysdb sssd refuses to open) is in the comment.Requires=/After=network-online.target. Upstream sets both andBefore=systemd-user-sessions.service, which chains display-manager → systemd-user-sessions → sssd → network-online, backed bynm-online -swithNM_ONLINE_TIMEOUT=60. Every link-down boot would sit in front of the greeter for up to a minute. Not a lockout (wait-online is onlyWantedBy=the target), but a real regression on a laptop that boots off-network constantly. Safe to drop because going offline is SSSD's normal mode and the point ofcache_credentials;beforeis left as upstream set it so sssd is still up before logins are allowed.ADR
No amendment needed — this matches ADR-0022's M2 description (
id_provider = ldap+auth_provider = krb5withkcmand offline caching, coexistence per the decision). The divergences above are spelling/mechanism corrections, not changes of intent.Verification (yours — the agent cannot reach the fleet)
getent passwd dominik.polakovics→ uid 5001, home/home/dominik.polakovics.getent group 5001resolves.id dominik.polakovics— note whether supplementary LDAP groups appear. This is the unresolvedrfc2307/memberUidvsgroupOfNames/memberquestion flagged in a comment; primary gid is what login needs.dominikstill logs in with its own password before logging out.dominik.polakovicswith the Kerberos password from #267 — type the username, it will not be in the picker (divergence 3).klistshowskrbtgt/CLOONAR.COM@CLOONAR.COM;echo \$KRB5CCNAMEshows a KCM cache.Heads-up on 5:
pam_mkhomedirruns with nixpkgs' defaultsskel=/var/empty umask=0077, so/home/dominik.polakoviceswill be mode 0700 with no dotfiles — no.bashrc, no.profile. The shell will look bare. That is expected for a deliberately home-manager-less test session, not a failure.Closes #269
Add hosts/nb/modules/ldap-login.nix: id_provider = ldap against ldap.cloonar.com with auth_provider = krb5 against the KDC on mail, so an SDDM login also yields a TGT in a KCM cache. M2 of ADR-0022. Purely additive. users.users.dominik, its uid, home, hashedPassword and home-manager config are untouched, and nothing makes pam_sss required: nixpkgs orders pam_unix (sufficient) ahead of pam_sss (sufficient) in the auth stack, so a stopped sssd.service, a wrong bind password or a dead network all fall through to local auth. sssdStrictAccess is left unset. utils/modules/ldap-auth.nix is deliberately not reused or edited, keeping web-arm out of the blast radius. Also persists /var/lib/sss/{db,secrets} so the offline credential cache and KCM ticket store survive a reboot under impermanence, and drops sssd's Requires=/After=network-online.target so the greeter is not gated on NetworkManager-wait-online on a link-down boot. Three deliberate divergences from issue #269, each with an in-file comment: - krb5_store_password_if_offline, not krb5_store_password_if_no_ccache. The latter is not an SSSD option (absent from sssd 2.13 cfg_rules.ini) and would have been silently ignored. - security.pam.services.login.makeHomeDir, not .sddm. SDDM sets useDefaultRules = false, so makeHomeDir on sddm renders no pam_mkhomedir rule; SDDM's session stack includes login, which does. - enumerate is not set. On NixOS, NSS modules load only inside nsncd and the nscd protocol has no enumeration request, so getpwent() (what SDDM's user picker uses) cannot see SSSD regardless. Closes #269Typo correction to the last line of the description: the path is
/home/dominik.polakovics(notpolakovices). The committed files use the correct spelling throughout — verified, 6/6 occurrences canonical.Comment density reduced at the maintainer's request before merge —
ce2d2f3.hosts/nb/modules/ldap-login.nixgoes 267 → 140 lines, 170 → 45 comment lines.hosts/nb/configuration.nix's persistence block goes from a 15-line comment to 5. Comment-only: stripping comment lines from the before and after trees gives byte-identical output, for the Nix code and for the renderedsssd.confdirectives alike, so the maintainer's localscripts/test-configuration -v nbon the previous commit still stands.What was cut: nixpkgs
file:linecitations, quoted upstream source, and the multi-paragraph justifications — all of which are already in this PR's description and ADR-0022. What stays: one or two lines per non-obvious decision, concentrated where a future reader would otherwise "fix" a deliberate choice back (enumerateleft unset,login.makeHomeDirnotsddm,default_ccache_nameomitted becauseservices.sssd.kcmsets it, the droppednetwork-online.targetordering).The rule is anchored in
CLAUDE.md's Conventions section in the same commit so it does not recur: comments explain non-obvious decisions in one or two lines, and long-form reasoning belongs in the PR description or the ADR rather than the module.[autoland] verdict: pass
PASS.
Signal relied on: the maintainer ran
scripts/test-configuration -v nblocally againstb1e53d9and reported it clean. Forgejo Actions reports no check rows for this PR (labctl pr checks 270→state: none), and this agent's sandbox has no Nix (no/nix/store), so the maintainer's local dry-build is the only evaluation gate that has run — and it is the same gatescripts/pre-commitinvokes. The follow-up commitce2d2f3is provably comment-only (comment-stripped trees are byte-identical, Nix code and renderedsssd.confdirectives alike), so that result carries forward.Conventions: Conventional Commits title with host scope; body carries
Closes #269; diff confined tohosts/nb/plus theCLAUDE.mdconvention added at the maintainer's request while landing.Conflicts: none — merge base equals
origin/main(53118e5), fast-forward.Reviewed by inspection against nixpkgs
release-26.05rather than taking the description's word for it:services.sssdreally declaresconfig/settings/kcm/environmentFilewith the two config forms mutually exclusive by assertion; itskcmblock really setssecurity.krb5.settings.libdefaults.default_ccache_name, so omitting that key here is correct; the sssd unit really carriesafter/requires = network-online.targettogether withbefore = systemd-user-sessions.service, so themkForcetargets a real greeter-blocking chain;security.krb5declaresenable/package/settingsas used. The Firefox reasoning also holds — nixpkgs'wrapFirefoxemits no default policies absentusesNixExtensions/smartcardSupport, and home-manager 25.11 synthesises policies only forlanguagePacksand profile bookmarks, neither of whichdominik.nixuses, so the/etcpolicy file shadows nothing. Eval-conflict sweep onnbfound no competing definer ofmakeHomeDir,security.krb5,systemd.tmpfiles.rules, the twoenvironment.etcpaths, orservices.sssd;sops.secrets.sssd-environmentresolves against an existing key inhosts/nb/secrets.yaml.Lockout safety is sound as described:
pam_unixis ordered beforepam_ssson auth,pam_sssissufficienton account withpam_unixrequired last,sssdStrictAccessis unset, andnsswitchisfiles sss.users.users.dominikandutils/modules/ldap-auth.nixare untouched.No blocking concerns. Runtime behaviour (supplementary-group resolution under the unresolved
rfc2307vsgroupOfNamesquestion, and the offline-login path) remains for the maintainer's post-deploy checklist in the PR description.