feat: sops decrypts via pre-generated SSH host key (works on boot #1)
- pre-generate jupiter SSH host key off-repo (~/.config/homelab/jupiter) - derive age recipient via ssh-to-age, add to .sops.yaml, re-encrypt secret - secrets.nix: sops.age.sshKeyPaths = host key (drop separate keyFile) - gitignore private-key patterns - README: ship host key via nixos-anywhere --extra-files; secret decrypts boot #1 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -37,17 +37,32 @@ an installer, partitions via disko, installs.
|
||||
|
||||
1. Set the real OS disk id in `jupiter/disk-config.nix`
|
||||
(`ls -l /dev/disk/by-id`), and the data-disk mount in `configuration.nix`.
|
||||
2. Add your SSH pubkey to `users.users.darman.openssh.authorizedKeys.keys`.
|
||||
3. Wire the samba secret (see Notes) — real password, not the VM's plaintext.
|
||||
4. Run from your laptop:
|
||||
2. Add your login SSH pubkey to `users.users.darman.openssh.authorizedKeys.keys`.
|
||||
3. Set the real samba password:
|
||||
```
|
||||
export SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt
|
||||
nix shell nixpkgs#sops -c sops secrets/jupiter.yaml # edit, commit
|
||||
```
|
||||
4. Stage the pre-generated host key so sops can decrypt on boot #1
|
||||
(private key lives off-repo in `~/.config/homelab/jupiter/`):
|
||||
```
|
||||
install -Dm600 ~/.config/homelab/jupiter/ssh_host_ed25519_key \
|
||||
/tmp/extra/etc/ssh/ssh_host_ed25519_key
|
||||
install -Dm644 ~/.config/homelab/jupiter/ssh_host_ed25519_key.pub \
|
||||
/tmp/extra/etc/ssh/ssh_host_ed25519_key.pub
|
||||
```
|
||||
5. Run from your laptop:
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- \
|
||||
--flake .#jupiter \
|
||||
--extra-files /tmp/extra \
|
||||
--generate-hardware-config nixos-generate-config ./jupiter/hardware-configuration.nix \
|
||||
--target-host root@<zimablade-ip>
|
||||
```
|
||||
`--generate-hardware-config` pulls the target's real kernel modules into the
|
||||
placeholder for you. Commit the result. Reboot into NixOS.
|
||||
`--extra-files` plants the host key before first boot (its age identity is
|
||||
already a recipient in `.sops.yaml`, so `/run/secrets/samba_password`
|
||||
decrypts on boot #1). `--generate-hardware-config` pulls the target's real
|
||||
kernel modules into the placeholder. Commit the result. Reboot into NixOS.
|
||||
|
||||
Manual alternative (USB ISO): boot installer, `disko` the disk, then
|
||||
`nixos-install --flake .#jupiter`.
|
||||
@@ -72,8 +87,14 @@ prefer `services.<app>` over a container when available. Add a `caddy`
|
||||
|
||||
- Backend is Podman with `dockerCompat` — `docker` CLI works, no daemon.
|
||||
- Samba keeps its own password DB. `services.samba` never sets it; a systemd
|
||||
oneshot (`samba-smbpasswd`) provisions it from `/etc/samba/smb-password`.
|
||||
Real host: supply that file via **sops-nix / agenix**, never commit plaintext.
|
||||
oneshot (`samba-smbpasswd`) provisions it. Host reads the password from
|
||||
`/run/secrets/samba_password` (**sops-nix**); the VM falls back to plaintext
|
||||
`/etc/samba/smb-password`.
|
||||
- Secrets: `secrets/jupiter.yaml` is age-encrypted (safe to commit) to two
|
||||
recipients in `.sops.yaml` — the **admin** key (edit on laptop,
|
||||
`~/.config/sops/age/keys.txt`) and the **jupiter host** key (derived from its
|
||||
SSH host key via `ssh-to-age`, decrypts at runtime). Private keys live
|
||||
off-repo and are gitignored. Rotate/add recipients with `sops updatekeys`.
|
||||
- Data disk: plain `fileSystems."/mnt/data"` in configuration.nix — kept out of
|
||||
disko so it is never formatted. Reference by `by-id` / `by-uuid`.
|
||||
- `system.stateVersion` = `26.05`, install-time schema. Do NOT bump on upgrades.
|
||||
|
||||
Reference in New Issue
Block a user