diff --git a/README.md b/README.md index ff9b71c..6f42dec 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,12 @@ another way in. `https://auth.mgaction.town` with `authentik_bootstrap_password` from sops. The username is hardcoded upstream and the bootstrap runs once — later changes to the env vars are ignored. + To use your own admin instead: create a user, add it to the **`authentik + Admins`** group (superuser is a *group* flag in Authentik, there is no + per-user one), verify it works in a private window, then **deactivate** + `akadmin` — do not rename or delete it. The bootstrap blueprint keys on + `username: akadmin` with `state: created`, so if no user by that name + exists it simply makes a new one on the next reconcile. 3. **Bootstrap the tailnet** (headscale starts with an empty database): ``` sudo headscale users create darman @@ -159,10 +165,23 @@ another way in. application with slug **`headplane`** — the slug is what makes the issuer `.../application/o/headplane/` in `services/vpn/headplane.nix`. Client ID goes in that file, client secret into sops. -6. **Pin jupiter's tailnet address.** `networking.hosts` in - `hosts/neptun/configuration.nix` carries jupiter's IP, because neptun runs - `--accept-dns=false` and cannot use MagicDNS. Until it matches - `headscale nodes list`, the `abs.` and `git.` vhosts fail to proxy. +6. **Headscale OIDC** (optional — pre-auth keys work without it). A *second* + Authentik provider/application, slug **`headscale`**, redirect + `https://vpn.mgaction.town/oidc/callback` (headscale's own, not headplane's + under `/admin`). Client ID in `services/vpn/headscale.nix`, secret into sops + as `headscale_oidc_client_secret`. + ⚠️ headscale runs OIDC discovery **at startup and a failure is fatal** — + an issuer pointing at an application that doesn't exist yet means the + control server won't boot, taking the whole tailnet's control plane with + it. Always verify first: + ``` + curl -s https://auth.mgaction.town/application/o/headscale/.well-known/openid-configuration + ``` + Users created by OIDC login are distinct from `headscale users create` + ones: headplane matches the OIDC `sub` claim against the user's + `providerId`, CLI-made users have none, and 0.28 dropped both + `map_legacy_users` and node reassignment — so moving an existing node to + an OIDC user means re-enrolling it. ### jupiter @@ -190,9 +209,23 @@ another way in. ``` sudo nix-store --verify --check-contents # add --repair to fix ``` - A card that has corrupted one path will corrupt more. Replace it and reflash; - only pihole's runtime state (query history, dynamic leases) is lost — the - static leases are declarative. + A card that has corrupted one path will corrupt more. Replace it and reflash. +- **A reflash wipes `/var/lib/pihole`**, which is NOT declarative. The + `FTLCONF_*` env vars rebuild the DNS/DHCP config, but the gravity database + goes with it — so adlists and blocking are gone and resolution silently + keeps working with nothing blocked (`Blocked DNS queries: 0` in the logs is + the tell). Re-add the adlists, then: + ``` + sudo podman exec pihole pihole -g + ``` +- mercury's own `resolv.conf` is deliberately public resolvers, not its own + pihole (`resolveLocalQueries = false`, see `CLAUDE.md`) — so `.sol` names do + not resolve *on mercury itself*. That is expected, not a fault. +- LAN `.sol` names resolve on tailnet members only because headscale sets + `override_local_dns = false`. With upstream's default of `true`, every node's + `resolv.conf` is replaced with MagicDNS and `.sol` returns NXDOMAIN + everywhere — along with losing ad blocking, since queries stop reaching + pihole at all. ## Adding a service