From cd7658f452071845611c6060e1f6c67a6c96fe9a Mon Sep 17 00:00:00 2001 From: DannyDannyDanny Date: Sun, 1 Mar 2026 11:55:44 +0100 Subject: [PATCH] doc: SSH key management and secrets :memo: - Updated AGENTS.md to specify one key per purpose for SSH access, including naming conventions and configuration tips. - Revised README.md to streamline the roadmap and link to SSH and secrets documentation. - Created docs/ssh-and-secrets.md to outline the strategy for managing SSH keys and secrets in a public repo. - Refined TODO.md to reflect the new approach for secrets and server configuration tasks. --- AGENTS.md | 8 ++++ README.md | 86 ++++++++++++----------------------------- TODO.md | 38 +++++++++--------- docs/ssh-and-secrets.md | 47 ++++++++++++++++++++++ nixos/readme.md | 43 ++++++--------------- 5 files changed, 108 insertions(+), 114 deletions(-) create mode 100644 docs/ssh-and-secrets.md diff --git a/AGENTS.md b/AGENTS.md index f4770a2..b850222 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,6 +16,14 @@ Do not automatically run rebuild commands - ask the user first. No keys, tokens, or identifying secrets in the repo. Prefer `scp` or config outside the repo. +## SSH keys (one key per purpose) + +We use **one key per purpose**, not one per machine: separate keys for server access, GitHub, Forgejo (and other forges if needed). Benefits: limit blast radius if a key is compromised; clear revocation; clear which key is for what. + +- **Key names:** e.g. `id_ed25519_github`, `id_ed25519_forgejo`, `id_ed25519_servers` (Ed25519 preferred). +- **Config:** Use `~/.ssh/config` with `IdentityFile` and `IdentitiesOnly yes` per host so the right key is used. Keys and sensitive config stay outside the repo. +- **Server / NixOS:** Use actual key names on the machine (e.g. `id_ed25519_github`), not a generic `id_ed25519` (see Learnings below). + ## Learnings (NixOS server) - Minimal ISO: use Ethernet or the graphical installer (Wi‑Fi on minimal is fiddly). diff --git a/README.md b/README.md index 1bf2034..79c967d 100644 --- a/README.md +++ b/README.md @@ -1,86 +1,48 @@ # dotfiles -[`nixos`](https://nixos.org/) + [`tmux`](https://github.com/tmux/tmux/?tab=readme-ov-file#welcome-to-tmux) + [`fish`](https://fishshell.com/) + [`neovim`](https://neovim.io/) +[nixos](https://nixos.org/) + [tmux](https://github.com/tmux/tmux) + [fish](https://fishshell.com/) + [neovim](https://neovim.io/) -This repo is an extension of [dannydannydanny/methodology](https://github.com/DannyDannyDanny/methodology/) +Extension of [dannydannydanny/methodology](https://github.com/DannyDannyDanny/methodology). -## Roadmap: - -* configure [firefox-scrolling](firefox-scrolling.md) via terminal -* server cluster roadmap: [server](server.md); NixOS server flake and bootstrap: [nixos/readme.md](nixos/readme.md) (nixos-server). -* :art: check for `nvim checkhealth` status -* make tmux nice: https://www.youtube.com/watch?v=DzNmUNvnB04 -* [fonts](https://www.programmingfonts.org/) - how does this relate to nerdfonts? -* [HN: What's on your home server](https://news.ycombinator.com/item?id=34271167) -* Jetson Nano Developer Kit SD Card Image [link](https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit) -* Raspberry Pi OS Lite (32-bit) [link](https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-32-bit) +## Roadmap +- [firefox-scrolling](firefox-scrolling.md) via terminal +- Server: [server](server.md); NixOS flake and bootstrap [nixos/readme.md](nixos/readme.md). SSH and secrets: [docs/ssh-and-secrets.md](docs/ssh-and-secrets.md). +- nvim checkhealth; tmux setup; [fonts](https://www.programmingfonts.org/) / nerdfonts; [HN: home server](https://news.ycombinator.com/item?id=34271167) ## Windows -* disable system sounds: `start menu search: "change system sounds" -> set profile to None` -* change language / keyboard layout to `en_US` -* [install powertoys](https://docs.microsoft.com/en-us/windows/powertoys/install#install-with-windows-executable-file-via-github) - * remap CAPS LOCK to L-CTRL -* install [alacritty](https://alacritty.org/) (use the installer, not portable) - * add alacritty config: `/mnt/c/Users//AppData/Roaming/alacritty/alacritty.yml` +- System sounds: None. Language/keyboard: en_US. +- [Powertoys](https://docs.microsoft.com/en-us/windows/powertoys/install) — remap CAPS to L-CTRL. +- [Alacritty](https://alacritty.org/) — config: `%AppData%/alacritty/alacritty.yml`. ### WSL -Install via [nix-community/NixOS-WSL Quickstart](https://github.com/nix-community/NixOS-WSL?tab=readme-ov-file#quick-start) :white_check_mark: -Setup dotfiles / config via github: +[Quickstart](https://github.com/nix-community/NixOS-WSL?tab=readme-ov-file#quick-start): + ```bash -# git and github CLI tool in a temp shell nix-shell -p gh git -# authenticate gh auth login -# clone dotfiles -gh repo clone dannydannydanny/dotfiles -# checkout the appropriate branch -git checkout feat/wsl-neovim-update -# rebuild WSL nixos using +gh repo clone dannydannydanny/dotfiles && cd dotfiles +# git checkout # if needed sudo nixos-rebuild switch --flake ~/dotfiles/nixos#wsl -# rebuild macbook nixos using -# sudo nixos-rebuild switch --flake ~/dotfiles/nixos#macbook ``` -### Clone repo SSH method -Skip this if you don't plan on getting SSH access to github repos and clone with HTTP instead -#### generate ssh -``` -ssh-keygen -q -t ed25519 -N '' -f ~/.ssh/id_ed25519_github <</dev/null 2>&1 +### Clone via SSH -# echo 'older machines might not support ed25519, then use RSA with 4096 bit key' -# echo 'ssh-keygen -q -t rsa -b 4096 -N '' -f ~/.ssh/id_rsa_github <</dev/null 2>&1' +One key per purpose; see [AGENTS.md](AGENTS.md) and [docs/ssh-and-secrets.md](docs/ssh-and-secrets.md). Otherwise clone with HTTPS. -# add the output to https://github.com/settings/ssh/new -cat ~/.ssh/id_*_github.pub -# add to https://github.com/settings/ssh/new -``` - -#### activate ssh -``` -echo 'adding key to ssh-agent' -eval `ssh-agent -s` # if using fish shell run: eval "$(ssh-agent -c)" -ssh-add ~/.ssh/id_*_github - -# download dotfiles repo -git clone git@github.com:DannyDannyDanny/dotfiles.git - -# config git -cd dotfiles +```bash +ssh-keygen -q -t ed25519 -N '' -f ~/.ssh/id_ed25519_github <<> ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys`. Optional: create `id_ed25519_servers` and use that only for server (then add Host in config). - - **Forgejo:** When needed: create `id_ed25519_forgejo`, add to forge, add Host in `~/.ssh/config`. +1. **Secrets** — Approach A (see [docs/ssh-and-secrets.md](docs/ssh-and-secrets.md)): public repo only, one key per purpose (AGENTS.md), server keys via scp. Optional later: private repo + sops-nix. + - **GitHub:** Use `id_ed25519_github`; in `~/.ssh/config`: `Host github.com` with `IdentityFile ~/.ssh/id_ed25519_github` and `IdentitiesOnly yes`. Remove `id_rsa_github` from GitHub and locally once confirmed unused. + - **nixos-server:** Switch to key auth if still on password: on server `mkdir -p ~/.ssh; chmod 700 ~/.ssh`; from Mac `scp ~/.ssh/id_ed25519_github.pub danny@SERVER:/tmp/`; on server `cat /tmp/id_ed25519_github.pub >> ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys`. Optional: create `id_ed25519_servers` and use only for servers (add Host in config). + - **Forgejo:** When needed: create `id_ed25519_forgejo`, add to forge, add Host in `~/.ssh/config`. -2. ~~**Server hardware before testing**~~ Done. Fetched via `ssh danny@server 'sudo cat /etc/nixos/hardware-configuration.nix'`, replaced stub; added boot.loader and system.stateVersion; flake check passes. +2. **Server** + - Only I use the machine. Access: SSH keys only (no password auth). + - Continue configuring (add services in `hosts/nixos-server.nix` as needed). + - SSH: key-only auth; disable password auth. Optionally restrict SSH to LAN. + - Passwordless sudo for wheel. -3. **Server** - - Continue configuring the server (add more services to `hosts/nixos-server.nix` as needed). - - Make sure SSH is only possible via LAN, using ssh keys and no password - - Make sudo not require a password +3. Rename nixos-server to + - Shortlist hostnames; then do flake + hostname + docs in one pass. + - **Monte Cristo–themed candidates (two-word, non-human):** + - Ships / sea: sunken-ship, phantom-ship, rusty-anchor, salty-wind, stormy-wave, calm-harbor, distant-shore, foreign-port, wooden-hull, anchor-chain + - Prison / stone: prison-rock, cold-stone, iron-chain, damp-cell, guard-tower, midnight-bell, stony-corridor, broken-chain + - Secrets / treasure: buried-treasure, secret-cave, forgotten-tunnel, hidden-key, rusty-sword, faded-parchment, ancient-map, broken-seal, buried-chest + - Atmosphere: strange-companion, masked-ball, poison-vial -4. **Verify** - - After 2–4: confirm server hardware in repo, flake builds, auto-rebuild works. On server, `systemctl is-active dotfiles-rebuild.timer` should be `active` once the flake config is live (see nixos/readme.md). +4. Give wifi access instead of ethernet. -5. Rename nixos-server to - -6. Give wifi access in stead of using ethernet. - -7. Host telegram bot once again (for what purpose?) +5. Host telegram bot once again (for what purpose?) diff --git a/docs/ssh-and-secrets.md b/docs/ssh-and-secrets.md new file mode 100644 index 0000000..3029fe5 --- /dev/null +++ b/docs/ssh-and-secrets.md @@ -0,0 +1,47 @@ +# SSH and secrets + +Strategy for SSH key management and secrets with a public NixOS/dotfiles repo and a handful of servers. + +## Chosen approach: A (current) + +- **Repo:** Public only. No keys or tokens in the repo ([AGENTS.md](../AGENTS.md)). +- **SSH keys:** One key per purpose (e.g. `id_ed25519_github`, `id_ed25519_servers`, `id_ed25519_forgejo`). Configure `~/.ssh/config` with `IdentityFile` and `IdentitiesOnly yes` per host. Keys live outside the repo. +- **Server authorized_keys:** Not managed by Nix. Push public keys via `scp` and append to `~/.ssh/authorized_keys` on each server. See [server-quickstart.md](../server-quickstart.md) and comments in [nixos/hosts/nixos-server.nix](../nixos/hosts/nixos-server.nix). + +Benefits: no private repo, simple, works with public dotfiles. Trade-off: one-time (or scripted) scp step per server; authorized_keys are not declarative in Nix. + +## Optional future: private secrets repo + sops-nix + +If you later want declarative secrets (passwords, tokens) or authorized_keys in Nix, a common pattern is: + +- **Public repo:** Config only (like this one). +- **Private repo:** Encrypted secret files (e.g. `secrets.yaml`), added as a flake input via `git+ssh://...`. +- **sops-nix:** Decrypts at activation using age (e.g. host SSH key). Secrets end up in `/run/secrets/`; you can reference them in config (e.g. `hashedPasswordFile`, or `openssh.authorizedKeys.keyFiles` for authorized_keys). + +```mermaid +flowchart LR + subgraph public [Public repo] + config[NixOS config] + end + subgraph private [Private repo] + secrets[Encrypted secrets] + end + subgraph build [Build] + flake[Flake input git+ssh] + sops[sops-nix] + end + config --> flake + private --> flake + flake --> sops + sops --> secrets +``` + +References: [sops-nix](https://github.com/Mic92/sops-nix), NixOS options `users.users..openssh.authorizedKeys.keyFiles` and `sops.secrets`. + +## Long-term plan + +1. **Now:** Use approach A. Document and follow one key per purpose and scp-based server keys; see AGENTS.md and server-quickstart.md. +2. **Optional later:** If you add a private secrets repo, add it as a flake input, enable sops-nix with a small module (defaultSopsFile from that input, age with host SSH key). Use for hashedPassword and service secrets first. +3. **Optional later:** To make authorized_keys declarative, add an encrypted file (one key per line) in the private repo and set `users.users..openssh.authorizedKeys.keyFiles = [ config.sops.secrets.authorized_keys.path ];` in the server host module. + +AGENTS.md remains the source of truth for key naming and one-key-per-purpose. diff --git a/nixos/readme.md b/nixos/readme.md index 7193e99..3d325cf 100644 --- a/nixos/readme.md +++ b/nixos/readme.md @@ -1,48 +1,27 @@ -Rebuild nixos and points to dotfiles dir: +# NixOS flake -``` +Rebuild from dotfiles dir: + +```bash sudo nixos-rebuild switch --flake ~/dotfiles/nixos#macbookair -# or -sudo nixos-rebuild switch --flake ~/dotfiles/nixos#wsl -# or (macOS) -sudo -H nix run github:lnl7/nix-darwin -- switch --flake ~/dotfiles/nixos#Daniel-Macbook-Air +# or #wsl +# macOS: cd ~/dotfiles/nixos && darwin-rebuild switch --flake . ``` ## Server (nixos-server) -One-time on the server (git is not installed until after the first rebuild, so use nix run to get git): +One-time bootstrap (no git until first rebuild): ```bash nix run --extra-experimental-features "nix-command flakes" nixpkgs#git -- clone https://github.com/DannyDannyDanny/dotfiles.git /tmp/dotfiles sudo mv /tmp/dotfiles /etc/dotfiles -# Enable flakes for this run (needed if the current system config does not) sudo nixos-rebuild switch --flake /etc/dotfiles/nixos#nixos-server --option accept-flake-config true ``` -If that fails with "does not provide attribute ... nixos-rebuild", enable flakes for the Nix daemon via the current config (on NixOS, `/etc/nix/nix.conf` is often read-only), then build and switch manually. -**From your Mac:** push a config that enables flakes, then on the server copy it and rebuild: -```bash -scp nixos/server-configuration-with-flakes.nix danny@:/tmp/configuration.nix -``` -**On the server:** -```bash -sudo cp /tmp/configuration.nix /etc/nixos/configuration.nix -sudo nixos-rebuild switch -``` -Then build and switch to the flake: -```bash -sudo nix build /etc/dotfiles/nixos#nixosConfigurations.nixos-server.config.system.build.toplevel -o /tmp/nixos-result -sudo /tmp/nixos-result/bin/switch-to-configuration switch -``` +If the daemon doesn’t have flakes: copy [server-configuration-with-flakes.nix](server-configuration-with-flakes.nix) to `/etc/nixos/configuration.nix`, run `sudo nixos-rebuild switch`, then build and switch to the flake (see [server-quickstart.md](../server-quickstart.md) for SSH keys). -Use `git@github.com:DannyDannyDanny/dotfiles.git` if the repo is private (clone as danny then `sudo mv` and `sudo chown -R root:root /etc/dotfiles`). +SSH keys (not in repo): `scp ~/.ssh/*.pub danny@server:/tmp/`, then on server `mkdir -p ~/.ssh; cat /tmp/*.pub >> ~/.ssh/authorized_keys`. See [docs/ssh-and-secrets.md](../docs/ssh-and-secrets.md). -SSH keys for danny (not in repo): from your machine `scp ~/.ssh/*.pub danny@server:/tmp/`, then on server `mkdir -p ~/.ssh; cat /tmp/*.pub >> ~/.ssh/authorized_keys`. +Timer: every 15 min the server pulls and rebuilds when `main` changes. Config: `hosts/nixos-server.nix`, `hosts/nixos-server-hardware.nix`. -After that, a timer pulls and rebuilds every 15 min when `main` changes. Config lives in `hosts/nixos-server.nix` and `hosts/nixos-server-hardware.nix`. - -**Pull when git is not in PATH** (e.g. before first rebuild or when `sudo git` says "command not found"): -```bash -sudo nix run nixpkgs#git -- -C /etc/dotfiles pull origin main -``` -Then run `sudo nixos-rebuild switch --flake /etc/dotfiles/nixos#nixos-server` as usual. After that, git is in the system profile; for manual pulls you can use `sudo /run/current-system/sw/bin/git -C /etc/dotfiles pull origin main` if `sudo git` still isn’t in PATH. +No git in PATH: `sudo nix run nixpkgs#git -- -C /etc/dotfiles pull origin main`.