From 0d704fb3e30bb144b5b071a3d1356febfebd77e8 Mon Sep 17 00:00:00 2001 From: Alexandru Macocian Date: Mon, 22 Jun 2026 15:31:50 +0200 Subject: [PATCH] Shared homes documentation --- docs/roadmap.md | 3 ++ docs/shared-homes.md | 77 ++++++++++++++++++++++++++++++++++++++++++++ docs/toc.md | 1 + 3 files changed, 81 insertions(+) create mode 100644 docs/shared-homes.md diff --git a/docs/roadmap.md b/docs/roadmap.md index 3e241ef..c55d924 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -23,5 +23,8 @@ context. | Dashboards as code | `Charlie/victoriametrics` | | Cert issuer hardening | `Charlie/cert-issuer` | | Bootstrap tooling | Host onboarding | +| [Shared home directories][shared-homes] | Host onboarding | + +[shared-homes]: shared-homes.md Done work stays in Git history, not this doc. diff --git a/docs/shared-homes.md b/docs/shared-homes.md new file mode 100644 index 0000000..479e349 --- /dev/null +++ b/docs/shared-homes.md @@ -0,0 +1,77 @@ +# Shared home directories + +Status: **planned**. Tracking doc for moving host home directories onto the NAS +via LDAP-backed autofs, so per-user config (shells, `nvim`, etc.) follows the +user across every host. This is the first slice of host auto-provisioning; see +[roadmap → Bootstrap tooling](roadmap.md). Fold the implemented parts into +[identity](identity.md) and [onboarding](onboarding.md) once shipped. + +## Goal + +Login on any host lands in the same NFS-backed `/Users/`, mounted on +demand from Miquella. The `/Users` path stays (macOS-compatible; Malenia is +macOS), and the map is managed centrally in LDAP. + +## Current state + +| Aspect | Today | +| --------------- | --------------------------------------------------------------- | +| `homeDirectory` | LDAP serves `/Users/` (rfc2307 `posixAccount`). | +| Home creation | `pam_mkhomedir` makes `/Users/` **locally, per host**. | +| Sharing | None; each host has its own copy. Config does not follow. | +| `/Users` parent | `drwx------ sys-gitea-runner:charlie-deploy` — traversal bug. | +| autofs | `nsswitch automount: sss` set, but autofs not installed/enabled.| +| LDAP automount | No automount schema loaded; no map objects. | +| NAS | `miquella.lan:/volume1/ubuntu` at `/mnt/nas`; no root_squash. | +| `users/` share | `/mnt/nas/users` does not exist yet. | + +## Target design + +```mermaid +flowchart LR + Login[Login on host] --> Autofs[autofs /Users indirect map] + Autofs -->|map from| SSSD[SSSD autofs provider] + SSSD -->|LDAP| Maps[ou=automount] + Autofs -->|mount on demand| NAS[miquella:/volume1/ubuntu/users/&] +``` + +| Layer | Change | +| ----- | ------ | +| NAS | `/volume1/ubuntu/users/` root, per-user `users/` owned by the user, `0700`, seeded from skel. | +| LDAP | Load automount schema; add `ou=automount` with `auto.master` and `auto.Users` maps. | +| SSSD | Add `autofs` service and `autofs_provider = ldap` with map attribute mapping. | +| Host | Install + enable `autofs`; `/etc/auto.master` reads `+auto.master` from SSS; clean local `/Users/` first. | +| PAM | Drop `pam_mkhomedir` for human users (homes pre-provisioned on NAS). | + +## LDAP automount map + +| DN | Key | Value | +| -- | --- | ----- | +| `ou=automount,dc=alexandru,dc=macocian,dc=me` | — | container | +| `automountMapName=auto.master,ou=automount,…` | `/Users` | `auto.Users --timeout=600` | +| `automountMapName=auto.Users,ou=automount,…` | `*` | `-fstype=nfs4,rw,soft miquella.lan:/volume1/ubuntu/users/&` | + +SSSD map attribute mapping (rfc2307): `automountMap` / `automountMapName` / +`automount` / `automountKey` / `automountInformation`. + +## Migration / cutover + +1. **Interim fix:** set `/Users` to `root:root 0755` on every host so current + logins traverse into their home (independent of the rest of this plan). +2. Create `/volume1/ubuntu/users/` on Miquella; provision existing users' + homes there (owned by user, `0700`, seeded from skel). +3. Load automount schema into OpenLDAP; add the `ou=automount` map objects. +4. Enable autofs in SSSD (`services` + `autofs_provider`); restart SSSD. +5. On one host: install autofs, clean local `/Users/`, enable autofs, + verify on-demand mount and login. Then roll to the fleet. +6. Remove `pam_mkhomedir` for human users once NAS homes are authoritative. + +## Risks & open questions + +| Item | Note | +| ---- | ---- | +| Blast radius | NAS or LDAP down ⇒ no homes ⇒ degraded logins. Keep a local break-glass sudoer with a local home; use `--timeout`/soft mounts. | +| Service accounts | `sys-*` (e.g. `sys-gitea-runner`) should **not** be NFS homes. Move their `homeDirectory` off `/Users` so the indirect map owns `/Users` for humans only. | +| macOS (Malenia) | `/Users` is the native local home root; an indirect autofs map there is not a drop-in. Decide whether Malenia uses a different mechanism or is excluded initially. | +| NFS sockets/locks | ssh-agent/gpg sockets belong in `XDG_RUNTIME_DIR` (`/run`); `nvim` swap/undo and lockfiles need NFS-safe paths or local dirs. | +| Provisioning owner | Per-user home creation belongs in the future provisioning tool (or DirectoryAdmin) at account creation; no_root_squash lets a root-run provisioner set correct ownership. | diff --git a/docs/toc.md b/docs/toc.md index e43e441..890f1c8 100644 --- a/docs/toc.md +++ b/docs/toc.md @@ -12,6 +12,7 @@ Repository: [Charlie/project-charlie](https://gitea.alexandru.macocian.me/Charli | inventory | [Inventory](inventory.md) | Stack ownership, hosts, source/image repos, operator tooling. | | onboarding | [Host onboarding](onboarding.md) | Required host state and deploy-target prerequisites. | | identity | [Identity & access](identity.md) | Authentik, LDAP, step-ca, Gssh, Sherlock, service identities. | +| shared-homes | [Shared home directories](shared-homes.md) | Planned LDAP/autofs NFS-backed `/Users` homes. | | secrets | [Secrets](secrets.md) | SOPS, age keys, PAT identities, secret placement. | | cert-issuer | [Cert issuer](cert-issuer.md) | step-ca, cert-syncer, cert-watch, trust boundaries. | | automation | [Automation](automation.md) | Reusable workflows/actions, deploy path, build path, Gitea constraints. |