93 lines
3.1 KiB
Markdown
93 lines
3.1 KiB
Markdown
# Secrets (agenix)
|
|
|
|
Encrypted secrets for the fleet, managed with [agenix](https://github.com/ryantm/agenix).
|
|
|
|
Each secret is an age-encrypted file (`*.age`) encrypted to a set of recipient
|
|
public keys declared in [`secrets.nix`](./secrets.nix). A host decrypts its
|
|
secrets at activation using its SSH **host** key
|
|
(`/etc/ssh/ssh_host_ed25519_key`), so every host that must read a secret has to
|
|
be listed as a recipient for it.
|
|
|
|
`secrets.nix` is read only by the `agenix` CLI. It is never imported into the
|
|
NixOS evaluation.
|
|
|
|
## Secrets in this repo
|
|
|
|
| File | Purpose | Recipients |
|
|
| --------------- | ----------------------------------------------------------------------- | ----------------------------------- |
|
|
| `ldap-bind.age` | SSSD → Authentik LDAP bind credential, as an `sssd.conf` drop-in snippet | all SSSD-enabled hosts (not EDaaS) |
|
|
|
|
Consumed by [`modules/sssd.nix`](../modules/sssd.nix) via
|
|
`age.secrets.ldap-bind.path`, which places the decrypted snippet at
|
|
`/etc/sssd/conf.d/01-ldap-authtok.conf`.
|
|
|
|
> **`ldap-bind.age` is not committed yet.** Only `ldap-bind.age.PLACEHOLDER`
|
|
> ships in this change (real host recipient keys and the real password were not
|
|
> available when it was written). Follow the steps below to create the real
|
|
> secret, then delete the `.PLACEHOLDER`.
|
|
|
|
## Owner setup checklist
|
|
|
|
Run these once (per new host or when the bind password rotates):
|
|
|
|
### 1. Collect host recipient keys
|
|
|
|
On each SSSD-enabled host (all Linux hosts **except** EDaaS):
|
|
|
|
```sh
|
|
cat /etc/ssh/ssh_host_ed25519_key.pub
|
|
```
|
|
|
|
Paste each value into the matching placeholder in `secrets.nix`, replacing the
|
|
`AAAA_PLACEHOLDER_REPLACE_ME_*` strings. (Optionally uncomment and set `admin`
|
|
to an operator user key so the secret can be edited off-host.)
|
|
|
|
### 2. Encrypt the bind password
|
|
|
|
The plaintext must be a **full sssd.conf drop-in snippet**, because SSSD cannot
|
|
read `ldap_default_authtok` from a separate file — it only merges `conf.d/*.conf`.
|
|
The content is exactly:
|
|
|
|
```ini
|
|
[domain/default]
|
|
ldap_default_authtok = <the sssd-bind service-account password>
|
|
```
|
|
|
|
Use the password of the `sssd-bind` (Terraform: `sssd-bind`) Authentik LDAP
|
|
service account. Then, from the repo root:
|
|
|
|
```sh
|
|
# Requires the agenix CLI: `nix run github:ryantm/agenix -- -e secrets/ldap-bind.age`
|
|
cd secrets
|
|
agenix -e ldap-bind.age
|
|
```
|
|
|
|
An `$EDITOR` opens; paste the two-line snippet above, save, quit. agenix writes
|
|
the encrypted `ldap-bind.age`. Commit it and delete `ldap-bind.age.PLACEHOLDER`.
|
|
|
|
### 3. Rekey after changing recipients
|
|
|
|
If you add/remove hosts in `secrets.nix`, re-encrypt every secret to the new
|
|
recipient set:
|
|
|
|
```sh
|
|
cd secrets
|
|
agenix -r
|
|
```
|
|
|
|
### 4. DNS
|
|
|
|
`ldap.lyrapup.pet` must resolve to the Authentik LDAP outpost and serve LDAPS on
|
|
port 636 with a certificate the hosts trust (`ldap_tls_reqcert = demand`). If the
|
|
cert is not from a system-trusted CA, add it to the hosts' trust store
|
|
(`security.pki.certificateFiles`) or relax `ldap_tls_reqcert` in
|
|
`modules/sssd.nix`.
|
|
|
|
### 5. Rebuild
|
|
|
|
```sh
|
|
sudo nixos-rebuild switch --flake .#<host>
|
|
```
|
|
|
|
Verify with `getent passwd <ldap-user>` and `id <ldap-user>`.
|