# SSH-ключи для Git _Безопасность · GitLab Knowledge Base_ **TL;DR:** SSH-ключ - пара файлов: приватный (у тебя) и публичный (на сервере). Аутентификация без пароля при push/clone. По безопасности SSH-key с passphrase + ssh-agent и HTTPS + scoped/expiring PAT в credential helper примерно сопоставимы - оба упираются в защиту локального секрета. SSH чаще выбирают за удобство и отсутствие ротации. ed25519 - современный дефолт, RSA 4096 - legacy-совместимость. Git по умолчанию использует тот же SSH, что и `ssh username@host`. Поэтому всё, что про SSH (ключи в `~/.ssh/`, `~/.ssh/config`, ssh-agent), работает и для Git без отдельной настройки. ## Создание ключа ```bash # Современный дефолт - ed25519 ssh-keygen -t ed25519 -C "you@example.com" # Legacy-совместимость (старые форджи, требующие RSA) ssh-keygen -t rsa -b 4096 -C "you@example.com" ``` При генерации спросит: - Куда сохранять (обычно `~/.ssh/id_ed25519`). - Парольную фразу (рекомендуется ставить, защищает приватный ключ при копировании). Результат - два файла: - `~/.ssh/id_ed25519` - приватный (никому не показывать). - `~/.ssh/id_ed25519.pub` - публичный (загружается на GitHub/GitLab/etc). ## Загрузка на GitHub/GitLab ```bash # Скопировать публичный ключ в буфер cat ~/.ssh/id_ed25519.pub ``` Дальше - Settings → SSH Keys → New SSH Key, вставить публичный ключ. На GitHub различают auth-ключи (для push/pull) и signing-ключи (для подписи коммитов, см. [gpg-signing](/courses/git/kb/gpg-signing.md)). Один и тот же ключ можно зарегистрировать в обеих категориях. ## Проверка ```bash ssh -T git@github.com # Hi ! You've successfully authenticated, but GitHub does not # provide shell access. ``` Если работает - ключ распознан, можно использовать SSH-URL для clone: ```bash git clone git@github.com:foo/bar.git ``` ## ssh-agent: чтобы не вводить парольную фразу каждый раз ```bash eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519 # Введи парольную фразу один раз - дальше agent помнит ``` На macOS лучше через Keychain: ```bash ssh-add --apple-use-keychain ~/.ssh/id_ed25519 ``` На Windows есть OpenSSH-агент в виде службы (`services.msc` → OpenSSH Authentication Agent). ## Несколько ключей для разных аккаунтов Сценарий: один ключ для GitHub-аккаунта работы, другой для личного. `~/.ssh/config` управляет, какой ключ под какой host: ``` Host github.com-work HostName github.com User git IdentityFile ~/.ssh/id_ed25519_work Host github.com-personal HostName github.com User git IdentityFile ~/.ssh/id_ed25519_personal ``` Клонировать с указанным host'ом: ```bash git clone git@github.com-work:company/repo.git ``` Git автоматически возьмёт нужный ключ. ## HTTPS vs SSH HTTPS требует логина при каждом push - либо через credential helper (сохраняет токен), либо через PAT/Personal Access Token, который вводится как пароль. Это работает, но менее удобно, чем SSH с ключом и agent'ом. SSH-key flow: ``` Один раз: сгенерил ключ, загрузил публичный на GitHub. Дальше: clone/pull/push - без логина, без пароля, без токена. ``` HTTPS-flow: ``` Каждый push: либо ввод пароля, либо credential helper подсовывает токен. Токен надо обновлять, если истёк. ``` В корпоративных setups иногда HTTPS принудительно через SSO, и SSH запрещён политикой. В open-source и большинстве команд SSH удобнее. ## Подводные камни - **Приватный ключ - секрет.** Не коммитить в репо. Включи `id_ed25519` в `~/.gitconfig`-уровне gitignore, чтобы случайно не запушить. См. [gitignore](/courses/git/kb/gitignore.md). - **Парольная фраза != пароль аккаунта.** Это локальная защита приватного файла на случай, если ноут украли. - **`Permission denied (publickey)` после ssh-keygen** - забыли загрузить публичный ключ на сервер или ssh-agent не подцепил ключ. Проверь: `ssh-add -l`. - **Истёкший ключ на сервере.** Многие компании ротируют SSH-ключи раз в год. Когда `Permission denied` - иногда ключ просто проэкспирировался, нужно перезагрузить. ## Команды ```bash ssh-keygen -t ed25519 -C 'you@example.com' ``` Сгенерировать современный ed25519-ключ ```bash ssh -T git@github.com ``` Проверить, что ключ распознан ```bash ssh-add ~/.ssh/id_ed25519 ``` Загрузить ключ в ssh-agent ```bash cat ~/.ssh/id_ed25519.pub ``` Показать публичную часть для загрузки на форджу ## См. также - [git clone](/courses/git/kb/clone.md) - [GPG-подпись коммитов](/courses/git/kb/gpg-signing.md)