doc: SSH key management and secrets 📝
- 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.
This commit is contained in:
parent
1fdce52239
commit
cd7658f452
5 changed files with 108 additions and 114 deletions
|
|
@ -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.
|
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)
|
## Learnings (NixOS server)
|
||||||
|
|
||||||
- Minimal ISO: use Ethernet or the graphical installer (Wi‑Fi on minimal is fiddly).
|
- Minimal ISO: use Ethernet or the graphical installer (Wi‑Fi on minimal is fiddly).
|
||||||
|
|
|
||||||
86
README.md
86
README.md
|
|
@ -1,86 +1,48 @@
|
||||||
# dotfiles
|
# 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:
|
## 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)
|
|
||||||
|
|
||||||
|
- [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
|
## Windows
|
||||||
|
|
||||||
* disable system sounds: `start menu search: "change system sounds" -> set profile to None`
|
- System sounds: None. Language/keyboard: en_US.
|
||||||
* change language / keyboard layout to `en_US`
|
- [Powertoys](https://docs.microsoft.com/en-us/windows/powertoys/install) — remap CAPS to L-CTRL.
|
||||||
* [install powertoys](https://docs.microsoft.com/en-us/windows/powertoys/install#install-with-windows-executable-file-via-github)
|
- [Alacritty](https://alacritty.org/) — config: `%AppData%/alacritty/alacritty.yml`.
|
||||||
* remap CAPS LOCK to L-CTRL
|
|
||||||
* install [alacritty](https://alacritty.org/) (use the installer, not portable)
|
|
||||||
* add alacritty config: `/mnt/c/Users/<winuser>/AppData/Roaming/alacritty/alacritty.yml`
|
|
||||||
|
|
||||||
### WSL
|
### WSL
|
||||||
|
|
||||||
Install via [nix-community/NixOS-WSL Quickstart](https://github.com/nix-community/NixOS-WSL?tab=readme-ov-file#quick-start) :white_check_mark:
|
[Quickstart](https://github.com/nix-community/NixOS-WSL?tab=readme-ov-file#quick-start):
|
||||||
Setup dotfiles / config via github:
|
|
||||||
```bash
|
```bash
|
||||||
# git and github CLI tool in a temp shell
|
|
||||||
nix-shell -p gh git
|
nix-shell -p gh git
|
||||||
# authenticate
|
|
||||||
gh auth login
|
gh auth login
|
||||||
# clone dotfiles
|
gh repo clone dannydannydanny/dotfiles && cd dotfiles
|
||||||
gh repo clone dannydannydanny/dotfiles
|
# git checkout <branch> # if needed
|
||||||
# checkout the appropriate branch
|
|
||||||
git checkout feat/wsl-neovim-update
|
|
||||||
# rebuild WSL nixos using
|
|
||||||
sudo nixos-rebuild switch --flake ~/dotfiles/nixos#wsl
|
sudo nixos-rebuild switch --flake ~/dotfiles/nixos#wsl
|
||||||
# rebuild macbook nixos using
|
|
||||||
# sudo nixos-rebuild switch --flake ~/dotfiles/nixos#macbook
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Clone repo SSH method
|
### Clone via SSH
|
||||||
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 <<<y >/dev/null 2>&1
|
|
||||||
|
|
||||||
# echo 'older machines might not support ed25519, then use RSA with 4096 bit key'
|
One key per purpose; see [AGENTS.md](AGENTS.md) and [docs/ssh-and-secrets.md](docs/ssh-and-secrets.md). Otherwise clone with HTTPS.
|
||||||
# echo 'ssh-keygen -q -t rsa -b 4096 -N '' -f ~/.ssh/id_rsa_github <<<y >/dev/null 2>&1'
|
|
||||||
|
|
||||||
# add the output to https://github.com/settings/ssh/new
|
```bash
|
||||||
cat ~/.ssh/id_*_github.pub
|
ssh-keygen -q -t ed25519 -N '' -f ~/.ssh/id_ed25519_github <<<y
|
||||||
# add to https://github.com/settings/ssh/new
|
cat ~/.ssh/id_ed25519_github.pub # add at https://github.com/settings/ssh/new
|
||||||
```
|
eval $(ssh-agent -s) # fish: eval (ssh-agent -c)
|
||||||
|
ssh-add ~/.ssh/id_ed25519_github
|
||||||
#### activate ssh
|
git clone git@github.com:DannyDannyDanny/dotfiles.git && cd dotfiles
|
||||||
```
|
|
||||||
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
|
|
||||||
git config user.name "DannyDannyDanny"
|
git config user.name "DannyDannyDanny"
|
||||||
git config user.email "dth@taiga.ai"
|
git config user.email "dth@taiga.ai"
|
||||||
git config pull.rebase false
|
|
||||||
git config push.autoSetupRemote true
|
|
||||||
# more git config: https://blog.gitbutler.com/how-git-core-devs-configure-git/
|
|
||||||
|
|
||||||
# install dotfiles
|
|
||||||
bash install.sh
|
bash install.sh
|
||||||
|
|
||||||
# hop back out
|
|
||||||
cd ..
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Good Reads / Philosophy
|
## Good reads
|
||||||
* sometimes [`TODO`s arent for doing](https://sophiebits.com/2025/07/21/todos-arent-for-doing)
|
|
||||||
|
- [TODOs aren't for doing](https://sophiebits.com/2025/07/21/todos-arent-for-doing)
|
||||||
|
|
|
||||||
38
TODO.md
38
TODO.md
|
|
@ -1,26 +1,24 @@
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
1. **Secrets** (started)
|
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.
|
||||||
- SSH public keys removed from `nixos/hosts/nixos-server.nix` and `nixos/server-install-configuration.nix`. Keys are not managed by NixOS there; use scp (see comments in those files and server-quickstart.md).
|
- **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.
|
||||||
- Optional: audit repo for other IDs (emails, UUIDs) if desired.
|
- **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).
|
||||||
- Check out friend's setup: public repo w config + setup; private repo w IDs, keys and secrets.
|
- **Forgejo:** When needed: create `id_ed25519_forgejo`, add to forge, add Host in `~/.ssh/config`.
|
||||||
- **SSH keys (one key per purpose).** Strategy: AGENTS.md. Actions:
|
|
||||||
- **GitHub:** In use: `id_ed25519_github`. Add `~/.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:** No `~/.ssh/authorized_keys` on server → currently password auth. To switch to key auth: 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 that only for server (then 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**
|
3. Rename nixos-server to <something-cooler>
|
||||||
- Continue configuring the server (add more services to `hosts/nixos-server.nix` as needed).
|
- Shortlist hostnames; then do flake + hostname + docs in one pass.
|
||||||
- Make sure SSH is only possible via LAN, using ssh keys and no password
|
- **Monte Cristo–themed candidates (two-word, non-human):**
|
||||||
- Make sudo not require a password
|
- 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**
|
4. Give <something-cooler> wifi access instead of ethernet.
|
||||||
- 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).
|
|
||||||
|
|
||||||
5. Rename nixos-server to <something-cooler>
|
5. Host telegram bot once again (for what purpose?)
|
||||||
|
|
||||||
6. Give <something-cooler> wifi access in stead of using ethernet.
|
|
||||||
|
|
||||||
7. Host telegram bot once again (for what purpose?)
|
|
||||||
|
|
|
||||||
47
docs/ssh-and-secrets.md
Normal file
47
docs/ssh-and-secrets.md
Normal file
|
|
@ -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.<name>.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.<name>.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.
|
||||||
|
|
@ -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
|
sudo nixos-rebuild switch --flake ~/dotfiles/nixos#macbookair
|
||||||
# or
|
# or #wsl
|
||||||
sudo nixos-rebuild switch --flake ~/dotfiles/nixos#wsl
|
# macOS: cd ~/dotfiles/nixos && darwin-rebuild switch --flake .
|
||||||
# or (macOS)
|
|
||||||
sudo -H nix run github:lnl7/nix-darwin -- switch --flake ~/dotfiles/nixos#Daniel-Macbook-Air
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Server (nixos-server)
|
## 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
|
```bash
|
||||||
nix run --extra-experimental-features "nix-command flakes" nixpkgs#git -- clone https://github.com/DannyDannyDanny/dotfiles.git /tmp/dotfiles
|
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
|
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
|
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:
|
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).
|
||||||
```bash
|
|
||||||
scp nixos/server-configuration-with-flakes.nix danny@<server>:/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
|
|
||||||
```
|
|
||||||
|
|
||||||
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`.
|
No git in PATH: `sudo nix run nixpkgs#git -- -C /etc/dotfiles pull origin main`.
|
||||||
|
|
||||||
**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.
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue