From 754024d915eb3452b8d91d556fafc6e9a1091207 Mon Sep 17 00:00:00 2001 From: mikl Date: Thu, 2 Jul 2026 02:02:05 +0300 Subject: [PATCH] docs: add ssh.md (keys, FIDO2, recovery) --- docs/ssh.md | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++ garden.md | 93 ++++++++++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 docs/ssh.md diff --git a/docs/ssh.md b/docs/ssh.md new file mode 100644 index 0000000..1536522 --- /dev/null +++ b/docs/ssh.md @@ -0,0 +1,185 @@ +# ssh + +SSH keys, agent configuration, and remote access for poppy. + +## как работает ssh-agent + +на macOS ssh-agent запускается через launchd (`com.openssh.ssh-agent`). +- сокет: `/private/tmp/com.apple.launchd.*/Listeners` (берётся из `launchctl getenv SSH_AUTH_SOCK`) +- `ssh-add ~/.ssh/` — добавляет ключ в agent +- `ssh-add -l` — список загруженных ключей +- `ssh-add -d ` — удалить ключ +- `ssh-add -D` — удалить все + +переменная `SSH_AUTH_SOCK` должна указывать на launchd socket, не на +`/Users/michaotic/.gnupg/S.gpg-agent.ssh` (это от gpg-agent — для pass, не для SSH). + +если что-то сломалось: +```bash +unset SSH_AUTH_SOCK +launchctl start com.openssh.ssh-agent +ssh-add -l +``` + +## ключи на poppy + +| файл | comment | для чего | алгоритм | +|------|---------|----------|----------| +| `~/.ssh/id_ed25519` | poppy-legacy | github (isogonalconjugate) | ed25519 | +| `~/.ssh/id_ed25519_forgejo` | forgejo-iscg | git.iscg.dev (port 2222) | ed25519 | +| `~/.ssh/poppy` | — | git.sol.moe (user: mikl) | ed25519 | +| `~/.ssh/id_ed25519_sk_ledger` | ledger@iscg.dev | **TODO**: FIDO2 (Ledger) | ed25519-sk | + +## конфигурация + +управляется в `home/ssh.nix` через `programs.ssh.matchBlocks`: + +```nix +"git.iscg.dev" = { + identityFile = "~/.ssh/id_ed25519_forgejo"; + port = 2222; + identitiesOnly = true; + addKeysToAgent = "yes"; +}; +"github.com" = { + identityFile = "~/.ssh/id_ed25519"; + identitiesOnly = true; + addKeysToAgent = "yes"; +}; +"git.sol.moe" = { + identityFile = "~/.ssh/poppy"; + user = "mikl"; + identitiesOnly = true; + addKeysToAgent = "yes"; +}; +``` + +**`identitiesOnly = true`** — критично: ssh-agent предлагает серверу **только** указанный +ключ, не пробует все подряд. + +**`addKeysToAgent = "yes"`** — при первом использовании ключ автоматически добавляется в ssh-agent. + +генерируется в `~/.ssh/config` (можно посмотреть: `cat ~/.ssh/config`). + +## создание нового ключа + +```bash +# обычный ed25519 +ssh-keygen -t ed25519 -C "comment" -f ~/.ssh/ + +# с passphrase ОБЯЗАТЕЛЬНО для безопасности +# ssh-agent кэширует passphrase на defaultCacheTtl (1 час) +``` + +после создания: +1. загрузить **публичный** ключ (`.pub`) на forge через web UI: + - github: https://github.com/settings/keys + - forgejo: https://git.iscg.dev/user/settings/keys + - gitea/sol.moe: аналогично +2. добавить в `home/ssh.nix` matchBlocks если новый хост +3. `darwin-rebuild switch` +4. `ssh-add ~/.ssh/` чтобы добавить в agent + +## подключение + +```bash +# тест подключения (ничего не делает, только проверка auth) +ssh -T git@github.com +ssh -T git@git.iscg.dev -p 2222 +ssh -T git@git.sol.moe + +# клонирование +git clone git@github.com:user/repo.git +git clone ssh://git@git.iscg.dev:2222/user/repo.git +git clone git@git.sol.moe:user/repo.git +``` + +## macOS Keychain (опционально) + +чтобы не вводить passphrase каждый раз: +```bash +ssh-add --apple-use-keychain ~/.ssh/ +``` + +или в `~/.ssh/config`: +``` +Host * + UseKeychain yes + AddKeysToAgent yes +``` + +ключи хранятся в **Keychain** (зашифровано, привязано к логину). + +## FIDO2 (Ledger Security Key) + +**Ledger поддерживает FIDO2 через `app-security-key` (открытый исходник — `LedgerHQ/app-security-key`).** + +### создание +```bash +# через nix shell (нужен libfido2) +nix shell nixpkgs#libfido2 nixpkgs#openssh --command \ + ssh-keygen -t ed25519-sk -C "ledger@iscg.dev" -f ~/.ssh/id_ed25519_sk_ledger +``` + +опции: +- `-O resident` — приватный ключ хранится на токене (переносимый) +- `-O verify-required` — требует PIN при подписании +- по умолчанию `touch required` — Ledger требует физическое нажатие + +### использование +```bash +# добавить в agent (нажать кнопку при load) +nix shell nixpkgs#libfido2 nixpkgs#openssh --command \ + ssh-add ~/.ssh/id_ed25519_sk_ledger + +# подписать challenge (нажать кнопку на Ledger) +nix shell nixpkgs#libfido2 nixpkgs#openssh --command \ + ssh-keygen -Y sign -f ~/.ssh/id_ed25519_sk_ledger -n ssh + +# проверить подпись +nix shell nixpkgs#libfido2 nixpkgs#openssh --command \ + ssh-keygen -Y verify -f -n ssh -I -s +``` + +### ограничения + +- **нативный `/usr/bin/ssh-keygen` не умеет FIDO2** — только nix openssh +- **macOS ssh-agent** хранит FIDO2 ключи, но подпись через нативный ssh-keygen не работает +- нужен **nix openssh** для `ssh-keygen -Y sign` и других sign-операций + +## factory reset recovery + +перед reset: +- скопировать `~/.ssh/` (или хотя бы файлы `id_ed25519*`, `poppy`, `id_ed25519_sk_ledger`) на USB/cloud +- записать какие ключи на каких forge (чтобы не забыть) + +после reset: +1. восстановить `~/.ssh/` +2. `chmod 600 ~/.ssh/*` (без этого ssh откажется работать) +3. `chmod 644 ~/.ssh/*.pub` +4. `ssh-add ~/.ssh/` (ввести passphrase) +5. `ssh -T git@` для проверки + +для FIDO2 ключа: см. секцию выше, нужен `nix shell nixpkgs#libfido2 nixpkgs#openssh`. + +## tasks (TODO) + +- [ ] **FIDO2 в nix-config** — добавить `libfido2` и `openssh` в `home/cli.nix` + - сейчас нужно каждый раз `nix shell nixpkgs#libfido2 nixpkgs#openssh --command ...` + - хочется чтобы работало нативно +- [ ] **nix ssh-agent** — заменить macOS ssh-agent на nix версию + - macOS ssh-agent не поддерживает FIDO2 sign через нативный ssh-keygen + - нужно `nix shell nixpkgs#libfido2 nixpkgs#openssh --command ssh-agent` +- [ ] **FIDO2 ключ с `resident`** — пересоздать `id_ed25519_sk_ledger` с `-O resident` + - сейчас без resident — файл обязателен для восстановления + - с resident — можно восстановить через `ssh-keygen -K` после factory reset +- [ ] **FIDO2 ключ на github/forgejo** — добавить `id_ed25519_sk_ledger.pub` на github + - для тестирования и использования + - сейчас не добавлен +- [ ] **backups ключей** — сохранить `id_ed25519_backup.pub` (отдельный, обычный) + - страховка если Ledger сломается + - сейчас нет запасного ключа +- [ ] **`SSH_AUTH_SOCK` fix** — добавить `unset SSH_AUTH_SOCK` в shell init + - если gpg-agent когда-то снова его перехватит + - не критично сейчас +- [ ] **pass-store origins** — настроить remotes для `~/.password-store` (отдельная задача в `garden.md`) diff --git a/garden.md b/garden.md index e69de29..fe3c455 100644 --- a/garden.md +++ b/garden.md @@ -0,0 +1,93 @@ +# garden + +Hosts in this repo are named after plants and flowers. + +## hosts + +### poppy *(active)* +- **role:** MacBook Air M1, personal/work machine +- **system:** nix-darwin, aarch64-darwin +- **location:** daily driver + +### muscari *(planned migration)* +- **role:** linux server, k3s cluster +- **system:** NixOS, x86_64-linux +- **location:** iscg infra + +### rosemary *(planned)* +- **role:** backup VM +- **system:** NixOS, x86_64-linux + +## structure + +- `flake.nix` — entry point, dispatches `mkNixos` and `mkDarwin` per host +- `hosts//default.nix` — per-host config +- `hosts/common/default.nix` — shared NixOS config +- `hosts/common-darwin/default.nix` — shared darwin config +- `home/default.nix` — shared home-manager config for user `michaotic` (plan to migrate to `mikl` later) +- `secrets/` — sops-encrypted secrets per host + +## documentation + +notes are split by topic under `docs/`: + +- `docs/structure.md` — high-level overview, where things go +- `docs/poppy.md` — MacBook specific (homebrew, system defaults) +- `docs/muscari.md` — server + k3s specifics +- `docs/shell.md` — zsh, pure prompt, plugins +- `docs/terminal.md` — kitty + catppuccin theme +- `docs/cheatsheet.md` — quick commands reference + +when adding a new host: copy `docs/structure.md` template, document hostname, role, packages unique to it. + +## migrations + +- `nix-config-legacy/` — previous muscari-only config (preserved for reference) + +## future plans + +### username migration + +currently using `michaotic` as username (historical). plan to migrate to `mikl` across all hosts for consistency. + +**why not now:** +- macOS: changing username requires careful handling of home folder, keychain, permissions +- linux: easier, but better to do in one coordinated change + +**when:** after setting up proper backups and testing migration procedure + +### rosemary setup + +currently `flake.nix` has `rosemary` commented out. need to: +- add disk config (likely similar to muscari) +- add users.users.michaotic.openssh.authorizedKeys +- test `nix flake check` + +### documentation improvements + +- [ ] create `docs/bootstrap.md` — manual setup guide for fresh device without nix (emergency fallback) + - list all CLI tools and how to install via brew/pnpm + - list all system defaults that need manual configuration + - explain which tools are nix-managed vs brew-managed +- [ ] create `docs/adding-host.md` — checklist for adding a new host +- [ ] create `docs/secrets.md` — sops-nix setup when we get there +- [ ] add migration notes to `docs/structure.md` as we learn patterns +- [ ] screenshots/notes for things that aren't obvious (e.g. dock layout) + +### tech debt + +- [ ] **git config** — разобраться с конфликтом `~/.gitconfig` (локальный) vs `~/.config/git/config` (home-manager) + - перенести osxkeychain credential helper, lfs в home-manager + - унифицировать user.name/email (michaotic vs mikl) + - добавить `core.pager = delta` явно + +- [ ] **git origins / remotes** — разобраться как декларативно описывать несколько git origins для произвольного репозитория + - использовать для pass-store (github + git.sol.moe + forgejo) + - сейчас делаем руками + - возможно через `home.file` + `.git/config` в Nix + - решить когда будет актуально + +- [ ] **pass-store sync** — настроить `~/.password-store` с remotes (forgejo primary, github/git.sol.moe backup) + - сначала создать репы на всех 3 хостах + - потом настроить через `pass git remote add` + - алиасы в zsh для каждого origin