nix-config/docs/ssh.md

185 lines
7.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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`)