docs: add ssh.md (keys, FIDO2, recovery)

This commit is contained in:
mikl 2026-07-02 02:02:05 +03:00
commit 754024d915
2 changed files with 278 additions and 0 deletions

185
docs/ssh.md Normal file
View file

@ -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/<key>` — добавляет ключ в agent
- `ssh-add -l` — список загруженных ключей
- `ssh-add -d <key>` — удалить ключ
- `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/<name>
# с 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/<name>` чтобы добавить в 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/<key>
```
или в `~/.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 <file>
# проверить подпись
nix shell nixpkgs#libfido2 nixpkgs#openssh --command \
ssh-keygen -Y verify -f <file.pub> -n ssh -I <identity> -s <file.sig>
```
### ограничения
- **нативный `/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/<key>` (ввести passphrase)
5. `ssh -T git@<forge>` для проверки
для 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`)