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