SSH-ключи глубоко
Зачем это нужно
В главе «Файлы, пакеты, SSH» мы подключались к серверу по паролю и один раз сгенерировали ключ, чтобы пароль больше не вводить. Этого хватает, чтобы «работало». Но очень быстро наступает момент, когда «работает» мало: ключей становится два — для чемпионатного сервера и для GitHub; терминал начинает при каждом подключении спрашивать парольную фразу; команда подключения разрастается до ssh -i ~/.ssh/work_key -p 2222 student@192.168.1.10, которую невозможно запомнить. На этой странице разберём механизм ключей до конца: как пара ключей на самом деле доказывает серверу, кто ты, что лежит в каждом файле внутри ~/.ssh, зачем нужен агент и как файл config превращает длинные заклинания в короткое ssh champ.
Эта страница — углубление: сначала пройди главу «Файлы, пакеты, SSH», где ssh и ssh-keygen появляются впервые.
- Зачем это нужно
- Как пара ключей доказывает, кто ты
- Что лежит в ~/.ssh
- Ed25519 или RSA: почему выбор всё ещё встречается
- Ключ не обязан пускать в полноценный shell
- ssh-agent: ввести парольную фразу один раз
- ~/.ssh/config: короткие имена вместо заклинаний
- Несколько ключей на одной машине
- Когда ничего не помогает: ssh -v
- known_hosts: сервер переустановили или подменили
- SSH-туннели: пробрось порт через сервер
- rsync и git: когда SSH везёт не терминал, а данные
- Практика: собери свой ~/.ssh
- Шпаргалка
- Что должен уметь
- Куда дальше: проверенные ресурсы
Как пара ключей доказывает, кто ты
Ключ SSH — это всегда пара из двух файлов, которые генерируются одновременно и математически связаны:
- Приватный ключ (private key) — твой секрет. Никогда не покидает твою машину, никому не отправляется, ни в чат, ни в репозиторий.
- Публичный ключ (public key) — открытая половина. Её можно показывать кому угодно: она кладётся на каждый сервер, куда ты хочешь входить.
Механика подключения — по сути «вызов-ответ»:
твоя машина сервер
┌───────────────────┐ ┌────────────────────────┐
│ приватный ключ │ │ authorized_keys: │
│ id_ed25519 │ │ ...твой публичный... │
└────────┬──────────┘ └───────────┬────────────┘
│ 1. «хочу войти как student» │
│ ────────────────────────────────────► │
│ 2. случайный вызов (challenge) │
│ ◄──────────────────────────────────── │
│ 3. подпись вызова приватным ключом │
│ ────────────────────────────────────► │
│ 4. проверка подписи публичным ключом │
│ ◄──────────────── вход разрешён ───── │
Сервер присылает случайные данные, твоя машина подписывает их приватным ключом, сервер проверяет подпись публичным. Подпись, созданную приватным ключом, может проверить только парный публичный — и наоборот, по публичному ключу восстановить приватный практически невозможно. Поэтому перехват публичного ключа злоумышленнику ничего не даёт, а приватный ключ даже не передаётся по сети — сервер его никогда не видит.
Откуда вообще берётся эта асимметрия — почему по одной половине пары легко посчитать вторую, а в обратную сторону нет. В основе лежит математическая односторонняя функция: операция, которую в одну сторону выполнить дёшево, а обратить — практически невозможно при разумных затратах времени. У Ed25519 это точка на эллиптической кривой: из приватного числа публичная точка считается за микросекунды, а чтобы по точке восстановить число, потребовалось бы больше вычислений, чем есть у человечества компьютеров на ближайшие десятилетия. Ключ не «зашифрован» в обычном смысле — это не сейф, который можно взломать перебором пароля; это разница в вычислительной сложности прямого и обратного пути. Отсюда и практический вывод: сервер, у которого лежит только публичная точка, физически не может по ней вычислить твой приватный ключ — не потому что не пытался, а потому что задача не решается за разумное время в принципе.
Сгенерировать пару мы уже умеем, теперь прочитаем команду целиком:
При генерации команда задаст два вопроса: куда сохранить (по умолчанию ~/.ssh/id_ed25519 — соглашайся) и парольную фразу (passphrase). Парольная фраза шифрует приватный ключ на диске: если ноутбук украдут, файл ключа без неё бесполезен. Это не тот пароль, что у сервера, — сервер о ней вообще не знает.
Что лежит в ~/.ssh
После пары подключений каталог ~/.ssh выглядит так:
| Файл | Что это | Права |
|---|---|---|
id_ed25519 | приватный ключ — секрет | 600 (только владелец, только чтение-запись) |
id_ed25519.pub | публичный ключ — одна строка текста | 644 |
config | твои настройки подключений (разберём ниже) | 600 |
known_hosts | отпечатки серверов, куда ты уже ходил | ведёт сам ssh |
authorized_keys | на сервере: список публичных ключей, кому можно входить | 600 |
Права — не формальность: ssh отказывается использовать приватный ключ, доступный на чтение кому-то кроме владельца, с ошибкой WARNING: UNPROTECTED PRIVATE KEY FILE!. Починка — chmod 600 ~/.ssh/id_ed25519 (вот где пригодилась глава про права).
Доставить публичный ключ на сервер проще всего командой ssh-copy-id student@192.168.1.10: она сама допишет твой .pub в ~/.ssh/authorized_keys на сервере с правильными правами. Руками это то же самое, что дописать одну строку в тот файл.
authorized_keys — это список строк, каждая строка — отдельный ключ, отдельное разрешение на вход. Дописать туда чужой публичный ключ по ошибке (например, скопировал не тот .pub файл или вставил ключ из чужого письма-инструкции) значит буквально выдать этому человеку доступ к аккаунту на сервере — без пароля, без предупреждения, молча. Перед тем как редактировать authorized_keys руками, проверь, чей это ключ: в конце строки — комментарий вида user@host, тот самый, что задаётся флагом -C при генерации. Лишнюю строку так же просто удалить — доступ этого ключа исчезнет мгновенно.
Ключ у тебя уже есть, но ssh island@server почему-то не пускает. Разберись, что отвечает сервер, и почини причину — как в реальной жизни. Нужны всего две вещи из этой главы: правильные права на приватный ключ и публичный ключ на сервере.
А known_hosts решает обратную задачу — проверяет сервер: при первом подключении ssh показывает отпечаток (fingerprint) ключа сервера и спрашивает Are you sure you want to continue connecting?. После твоего yes отпечаток запоминается, и если однажды сервер ответит другим ключом, ssh поднимет тревогу REMOTE HOST IDENTIFICATION HAS CHANGED! — либо сервер переустановили, либо кто-то притворяется им.
Ed25519 или RSA: почему выбор всё ещё встречается
В старых руководствах и на старых серверах до сих пор попадается ssh-keygen -t rsa -b 4096. RSA не сломан и не устарел до дыр — это по-прежнему рабочий алгоритм, которому 45 лет. Но у него есть накопленный исторический багаж, из-за которого новые ключи сейчас почти никто не генерирует на RSA:
- Длина решает всё. У RSA стойкость впрямую зависит от длины ключа: 1024 бита уже считаются слабыми, 2048 — минимум, 4096 — разумный запас. У Ed25519 длина фиксирована и уже соответствует по стойкости примерно RSA-3072, но публичный ключ при этом умещается в 68 символов против сотен у RSA-4096.
- История слабых генераторов. В 2008 году в Debian и Ubuntu был баг в генераторе случайных чисел OpenSSL: несколько лет системы создавали предсказуемые RSA- и DSA-ключи, и весь диапазон возможных ключей оказался переборным за разумное время. Ed25519 тогда ещё не существовал, но сама история — почему важно, чтобы алгоритм был спроектирован без острых углов вроде «параметр длины на усмотрение пользователя, ошибиться легко».
- Скорость. Подпись и проверка Ed25519 быстрее RSA той же стойкости — на слабом железе (одноплатных серверах, старых ноутбуках) это заметно при частых подключениях.
Практический вывод простой: новый ключ — ssh-keygen -t ed25519, без раздумий. RSA остаётся ровно для одного случая — древний сервер или встраиваемое устройство, которое буквально не понимает Ed25519 (такое иногда попадается в промышленном оборудовании); тогда -t rsa -b 4096, никогда не меньше.
Забыл парольную фразу — это не «попробуй ещё раз». Passphrase не хранится нигде в системе в открытом виде и не восстанавливается: она нужна только чтобы расшифровать конкретный файл ключа на диске. Единственный выход — генерировать новую пару и заново раскладывать публичный ключ по всем серверам через ssh-copy-id. Именно поэтому разумно вести короткую и запоминающуюся, но не пустую passphrase — записывать её в менеджер паролей, а не понадеяться на память.
Управлять ключами в агенте можно точнее, чем просто «добавил и всё»:
ssh-add -t 3600 ~/.ssh/id_ed25519 # ключ живёт в агенте только час
ssh-add -D # выгрузить из агента все ключи разом
Ключ не обязан пускать в полноценный shell
authorized_keys — не просто список «кому можно», у каждой строки есть необязательные опции перед самим ключом, которые ограничивают, что этот конкретный ключ умеет:
command="/usr/local/bin/backup.sh",no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAA...restofkey... backup@ci
command="..." заставляет сервер выполнить именно эту команду при входе по данному ключу — независимо от того, что попросила подключающаяся сторона (даже интерактивный ssh без аргументов запустит только backup.sh и сразу же отключится). Остальные опции гасят возможности, которые для служебного ключа не нужны: проброс портов, agent forwarding, X11. В сумме — ключ, скомпрометированный на CI-сервере или в деплой-скрипте, физически не даёт открыть интерактивную сессию, только выполняет одну заранее известную операцию.
Тот же принцип работает и со стороны самого сервера, в файле /etc/ssh/sshd_config — уже не про конкретный ключ, а про сервер целиком: PasswordAuthentication no полностью выключает вход по паролю (имеет смысл только когда вход по ключу для всех нужных аккаунтов проверенно работает), PermitRootLogin no запрещает подключаться напрямую пользователем root.
Классическая ошибка при правке sshd_config — сразу отключиться и перезапустить sshd. Если в файле опечатка или вход по ключу ещё не проверен, второй раз зайти будет уже не по чему: сервис не запустится или не пустит никого, а физического доступа к серверу может не быть. Правило простое: держи текущую сессию открытой, проверь новую конфигурацию во второй вкладке терминала — и только убедившись, что вход работает, закрывай первую.
ssh-agent: ввести парольную фразу один раз
Парольная фраза защищает ключ, но вводить её при каждом git push — мучение. Для этого есть агент — программа ssh-agent, которая один раз расшифровывает приватный ключ и держит его в памяти до конца сеанса; все следующие подключения обращаются к агенту и проходят без вопросов.
eval "$(ssh-agent -s)" # запустить агента (обычно уже запущен системой)
ssh-add ~/.ssh/id_ed25519 # добавить ключ — парольную фразу спросит один раз
ssh-add -l # список ключей, которые агент уже держит
Странная на вид первая строка объясняется просто: ssh-agent -s печатает команды настройки переменных окружения, а eval их выполняет в текущей оболочке — так остальные команды узнают, где искать агента. В Ubuntu с графическим входом агент, как правило, уже запущен, и остаётся только ssh-add.
Флаг ssh -A (agent forwarding) пробрасывает твой локальный агент дальше — с промежуточного сервера можно ходить твоим же ключом ещё дальше по цепочке, не копируя приватный ключ на этот сервер. Звучит удобно, но пока сессия открыта, любой с правами root на промежуточном сервере технически может воспользоваться твоим агентом, как будто это его собственный терминал — подписать что угодно твоим ключом, пока ты не отключился. Официальная документация OpenSSH прямо советует включать -A только для машин, которым доверяешь так же, как своей. Для связки «через один сервер попасть на другой» почти всегда правильнее ProxyJump (ниже), а не проброс агента.
~/.ssh/config: короткие имена вместо заклинаний
Команда ssh -i ~/.ssh/work_key -p 2222 student@192.168.1.10 — это четыре вещи, которые нужно помнить: ключ, порт, пользователь, адрес. Файл ~/.ssh/config позволяет записать их один раз:
Host champ
HostName 192.168.1.10
User student
Port 2222
IdentityFile ~/.ssh/work_key
После этого всё то же самое делает команда ssh champ — а заодно scp file.txt champ:~/ и любой инструмент поверх ssh, включая git. Разберём поля:
Блоков Host в файле может быть сколько угодно — по одному на каждый сервер. Отступы внутри блока — просто читаемость: ssh их не требует, но все так пишут.
Несколько ключей на одной машине
Типичная ситуация: один ключ для чемпионатного сервера, второй — для GitHub. Ключи не обязаны называться id_ed25519: при генерации задай своё имя файла, например ~/.ssh/github_key. Дальше всё решает config — каждому серверу свой IdentityFile:
Host champ
HostName 192.168.1.10
User student
IdentityFile ~/.ssh/champ_key
Host github.com
User git
IdentityFile ~/.ssh/github_key
Для GitHub псевдоним совпадает с настоящим адресом — так git, который ходит на github.com, автоматически подхватит нужный ключ. Обрати внимание на User git: на GitHub все подключаются пользователем git, а кто именно ты — сервер понимает по предъявленному ключу. Именно поэтому команда проверки выглядит так:
ssh -T git@github.com
и отвечает Hi <твой-логин>! You've successfully authenticated... — ключ и есть твоё имя.
Грабля, о которую спотыкаются почти все, у кого ключей больше одного. Сервер по умолчанию не ждёт, пока ты предъявишь единственно верный ключ, — ssh перебирает все ключи, которые держит агент, один за другим, пока не найдёт подходящий. Если в агенте их накопилось много (личный, рабочий, чемпионатный, ещё пара забытых), а у сервера настроен лимит попыток, можно словить Too many authentication failures — сервер обрывает соединение раньше, чем очередь дойдёт до правильного ключа. Лечится строкой IdentitiesOnly yes в нужном блоке Host: она запрещает ssh перебирать всё подряд и заставляет сразу использовать только IdentityFile, указанный в этом блоке.
Host github.com
User git
IdentityFile ~/.ssh/github_key
IdentitiesOnly yes
Когда ничего не помогает: ssh -v
Permission denied (publickey) без единой подсказки — самое частое сообщение, из-за которого новичок начинает переустанавливать всё подряд. Прежде чем что-то менять, стоит спросить сам ssh, что он на самом деле пробовал, — флагом -v (verbose):
ssh -v champ
Вывод покажет по шагам: какие ключи ssh нашёл и предложил, какой ключ сервер отклонил и почему, дошло ли дело до пароля вообще. Один -v даёт короткую сводку, -vv и -vvv — всё более подробную (вплоть до содержимого пакетов протокола) для действительно упрямых случаев. Типичная находка в выводе -v — ssh вообще не пробует нужный ключ, потому что тот не добавлен в агент (ssh-add -l пуст) или явно не указан в config; тогда правка тривиальна, просто без -v её не видно.
known_hosts: сервер переустановили или подменили
Выше уже прозвучало: если отпечаток сервера вдруг не совпал с записанным, ssh кричит REMOTE HOST IDENTIFICATION HAS CHANGED! и отказывается соединяться. На практике за этим предупреждением стоят две совершенно разные ситуации, и реагировать на них нужно по-разному:
- Сервер легитимно переустановили или пересоздали. Новая установка Ubuntu генерирует новый ключ хоста — старый отпечаток в
known_hostsустарел. Частый случай на учебных стендах и в облаке: пересоздал виртуалку с тем же IP — получил новый ключ. - Кто-то встаёт посередине (MITM) и представляется сервером. Реже, но именно для этого случая предупреждение и существует: сеть (например, публичный Wi-Fi без доверенного маршрута) отдаёт тебе не тот сервер, к которому ты привык ходить.
Отличить одно от другого через сам ssh нельзя — само предупреждение одинаковое в обоих случаях. Различает только внешняя проверка:
- Спроси администратора сервера (в другом канале — не в этом же подключении) отпечаток по факту:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubна самом сервере печатает тот жеSHA256:..., что видит клиент. - Если отпечаток подтверждён легитимной переустановкой — старую запись убирает
ssh-keygen -R champ(по алиасу изconfig) илиssh-keygen -R 192.168.1.10(по адресу); дальше обычное подключение внесёт новую запись как первое доверие. - Если подтвердить не удалось или связаться с администратором нельзя — не подключайся с этой сети; попробуй с другой (например, из дома вместо кафе) и сравни результат.
В автоматизации (CI, скрипт разворачивания нового сервера) вопрос Are you sure? вообще некому задать — терминала с человеком за клавиатурой нет. Для этого случая есть ssh-keyscan: он забирает отпечаток сервера напрямую и печатает его в формате known_hosts, без интерактивного подтверждения — ssh-keyscan champ >> ~/.ssh/known_hosts. Это не обходит проверку подмены, а переносит момент доверия на более раннюю точку: ты сам решаешь, когда именно занести сервер в доверенные (например, сразу после того, как только что его создал), а не полагаешься на диалоговое окно посреди скрипта.
Привычка не глядя жать yes на вопрос Are you sure you want to continue connecting? при первом подключении — не страшна: сравнивать пока не с чем. А вот yes на предупреждение о смене ключа уже знакомого сервера — это ровно тот момент, где MITM и рассчитывает на автоматизм. Секундная пауза и один вопрос себе «я точно знаю, почему ключ сменился» стоят дороже, чем кажется.
SSH-туннели: пробрось порт через сервер
SSH умеет не только открывать терминал — тем же зашифрованным каналом можно провести чужой трафик, не открывая на сервере ни одного дополнительного порта наружу. Это называется проброс портов (port forwarding), и у него два основных направления.
Локальный проброс (-L) — сервис живёт на удалённой машине или в её локальной сети, а тебе нужно достучаться до него со своего ноутбука:
ssh -L 8080:localhost:80 champ
После такой команды открытая вкладка http://localhost:8080 на твоём компьютере на самом деле показывает то, что сервер champ видит на своём localhost:80 — веб-панель, базу данных, что угодно, что администратор намеренно не выставил в интернет напрямую. Трафик всё это время идёт зашифрованным внутри ssh-сессии.
Удалённый проброс (-R) — обратная задача: дать серверу доступ к сервису, который крутится у тебя локально. Используется реже (в основном для демонстрации локально запущенного сайта или для отладки вебхуков), синтаксис зеркальный: ssh -R 9000:localhost:3000 champ открывает на сервере champ порт 9000, который ведёт на твой локальный 3000.
Флаги -N (не открывать shell, только туннель) и -f (уйти в фон) обычно ставят вместе: ssh -N -f -L 8080:localhost:80 champ держит туннель в фоне без занятого терминала. А если нужно попасть на сервер, у которого нет прямого доступа из интернета, а только через второй, «прыжковый» сервер — для этого есть ProxyJump прямо в config, без ручных туннелей:
Host internal
HostName 10.0.0.5
User student
ProxyJump champ
Ещё одна деталь для тех, кто подключается к одному и тому же серверу за день десятки раз (например, во время подготовки к чемпионату): каждое новое ssh champ — это заново рукопожатие, заново проверка ключа. ControlMaster/ControlPersist в config держат уже открытое соединение и переиспользуют его для следующих подключений — второе и все последующие ssh champ подключаются почти мгновенно:
Host champ
HostName 192.168.1.10
User student
IdentityFile ~/.ssh/champ_key
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 10m
rsync и git: когда SSH везёт не терминал, а данные
scp из главы «Файлы, пакеты, SSH» копирует файл целиком каждый раз — просто и предсказуемо, но для больших каталогов и повторной синхронизации есть инструмент точнее.
rsync ходит по тому же ssh-каналу (-e ssh, обычно уже настроено по умолчанию), но сравнивает файлы на обеих сторонах и передаёт только разницу:
rsync -avz --delete -e ssh ./dist/ champ:~/www/
-a — режим архива (сохраняет права, время, символьные ссылки), -v — подробный вывод, -z — сжатие на лету, --delete — удалить на сервере файлы, которых больше нет локально (синхронизация в одну сторону, а не просто докидывание). При повторном запуске rsync перекачает только изменённые файлы — для деплоя сайта или синхронизации папки с сотнями файлов это на порядок быстрее, чем гонять scp заново целиком, и вдобавок прерванную передачу можно продолжить, а не начинать с нуля.
git remote: SSH или HTTPS. У любого репозитория на GitHub/GitLab есть два адреса — git@github.com:user/repo.git (SSH) и https://github.com/user/repo.git (HTTPS). Оба варианта одинаково безопасны, разница — в повседневном удобстве:
| SSH | HTTPS | |
|---|---|---|
Вход при push/pull | без пароля, если ключ в агенте | нужен personal access token (пароли для git отключены) |
| Проброс через корпоративный firewall | порт 22 иногда закрыт наружу | порт 443 открыт почти всегда |
| Несколько аккаунтов на машине | решает config с разными IdentityFile (см. выше) | нужно переключать токены вручную |
| Deploy-ключи для CI/сервера | штатный механизм GitHub/GitLab | отдельные токены с ограниченным сроком |
Для повседневной работы с ноутбука, где 22-й порт не заблокирован, SSH обычно удобнее — один раз настроенный config снимает вопрос авторизации насовсем. В офисных сетях с жёстким firewall или в одноразовых CI-контейнерах чаще выбирают HTTPS с токеном. Проверить, каким протоколом настроен уже склонированный репозиторий, можно командой git remote -v; поменять — git remote set-url origin git@github.com:user/repo.git.
Практика: собери свой ~/.ssh
Учебный терминал не умеет запускать настоящий ssh-keygen, но раскладку файлов — самое частое место ошибок — отрепетировать можно. Собери каталог ~/.ssh руками: создай его, положи внутрь «ключи» и запиши в config блок для сервера champ (используй echo 'текст' >> .ssh/config, чтобы дописывать строки).
- ○ .ssh/champ_key
- ○ .ssh/champ_key.pub
- ○ .ssh/config
Как это устроено под капотом
И набери команды этой страницы руками — на настоящей машине они должны отлетать без подглядывания:
Цель: точность ≥ 90%
ssh-keygen -t ed25519 -C 'oleg@laptop'
Шпаргалка
| Команда / файл | Что делает |
|---|---|
ssh-keygen -t ed25519 -C 'метка' | сгенерировать пару ключей Ed25519 |
ssh-copy-id user@host | доставить публичный ключ в authorized_keys сервера |
chmod 600 ~/.ssh/id_ed25519 | починить права приватного ключа |
eval "$(ssh-agent -s)" | запустить агента в текущей оболочке |
ssh-add ~/.ssh/id_ed25519 | добавить ключ агенту (passphrase — один раз) |
ssh-add -l | какие ключи агент уже держит |
~/.ssh/config | блоки Host: адрес, пользователь, порт, ключ — под коротким именем |
ssh -T git@github.com | проверить ключ для GitHub |
id_ed25519 / id_ed25519.pub | приватный (секрет!) / публичный (можно делиться) |
known_hosts | отпечатки серверов, которым ты уже доверился |
ssh-keygen -R champ | стереть устаревшую запись сервера из known_hosts после легитимной переустановки |
ssh -L 8080:localhost:80 champ | локальный проброс порта: удалённый сервис доступен на твоём localhost |
rsync -avz -e ssh ./dist/ champ:~/www/ | синхронизировать каталог, передавая только изменения |
git remote set-url origin git@github.com:user/repo.git | переключить репозиторий с HTTPS на SSH (или наоборот) |
Углубиться
Отпечаток ключа. Команда ssh-keygen -lf ~/.ssh/id_ed25519.pub печатает fingerprint — короткую сводку ключа вида SHA256:.... По ней удобно сверять ключи, не сравнивая длинные строки целиком: тот же отпечаток GitHub показывает в настройках рядом с каждым добавленным ключом. ssh-keygen -lf работает и для чужого известного ключа сервера — тем же способом можно самостоятельно посчитать fingerprint из файла /etc/ssh/ssh_host_ed25519_key.pub, если администратор прислал его тебе, вместо того чтобы диктовать длинную строку по телефону.
Один ключ — не навсегда. Ключи отзываются просто: удалил строку из authorized_keys (или из настроек GitHub) — ключ больше не пускает. Поэтому потерянный ноутбук — не катастрофа, а повод за минуту удалить его ключ со всех серверов. Держать по отдельному ключу на каждую машину — как раз для этого: скомпрометирован один ноутбук — отзывается один ключ, остальные машины и остальные ключи этого не касаются.
GitHub умеет требовать подтверждение подписи коммитов. Ed25519-ключ можно использовать не только для входа по SSH, но и чтобы подписывать git-коммиты (git config user.signingkey, gpg.format ssh, commit.gpgsign true) — тогда рядом с коммитом в интерфейсе GitHub появляется пометка Verified, а значит коммит действительно сделан владельцем приватного ключа, а не кем-то, кто просто прописал твоё имя и почту в git config. Для командной работы, где важно доверять авторству, это уже не экзотика, а стандартная практика.
Что если приватный ключ всё-таки утёк. Отозвать доступ (удалить из authorized_keys и из настроек GitHub) — только первый шаг. Раз приватный ключ мог оказаться у кого-то ещё, доверять паре в принципе больше нельзя: правильная реакция — сгенерировать новую пару целиком, а не пытаться «спасти» скомпрометированный ключ новой passphrase. Passphrase защищает файл на диске до утечки; если файл уже кто-то скопировал, дальнейшая судьба passphrase уже не в твоих руках.
Дальше по теме:
- OpenSSH Manual Pages — официальные man-страницы ssh, ssh-keygen, ssh-agent, ssh_config — первоисточник всей этой страницы
- GitHub Docs — Подключение к GitHub с помощью SSH — генерация ключа, добавление в аккаунт и проверка, по-русски
Сводная проверка по всей главе: 13 вопросов, 5:00 на всё, без подсказок по ходу. Вопросы показываются по одному, ответ изменить нельзя. Если время выйдет — экзамен завершится с тем, что успел ответить. Пересдавать можно сколько угодно раз.
Что должен уметь
- Объяснять на пальцах, как пара ключей доказывает серверу личность и почему приватный ключ не передаётся по сети.
- Называть роль каждого файла в
~/.ssh: ключи, config, known_hosts — и authorized_keys на сервере. - Чинить ошибку
UNPROTECTED PRIVATE KEY FILEи понимать, зачем приватному ключу права 600. - Доставлять публичный ключ на сервер через
ssh-copy-idи объяснять, что она меняет на сервере. - Пользоваться ssh-agent: добавить ключ, посмотреть список, объяснить, зачем нужна конструкция с eval.
- Писать блоки Host в
~/.ssh/config— включая отдельные ключи для разных серверов и для GitHub. - Обосновывать выбор Ed25519 вместо RSA для нового ключа и понимать, что теряется при утере passphrase.
- Отличать легитимную смену ключа сервера от подозрительной и знать, что проверить перед тем как жать
yes. - Пробрасывать порт через
ssh -L, объяснять разницу с-Rи когда вместо туннеля нуженProxyJump. - Выбирать между
rsyncиscp, между SSH- и HTTPS-адресом git-репозитория — и объяснять, чем один вариант выгоднее другого в конкретной ситуации.
Куда дальше: проверенные ресурсы
-
OpenSSH Manual Pages — man-страницы всего семейства OpenSSH: ssh, ssh-keygen, ssh-agent, ssh-add, ssh_config, sshd.
-
GitHub Docs — Сведения об SSH — зачем GitHub ключи и как ими управлять в аккаунте, по-русски.
-
man ssh_config (Ubuntu) — полный список директив файла config: Host, HostName, IdentityFile, ProxyJump и десятки других.
-
cloud.ru — пошаговая настройка SSH-ключей — тот же путь с ssh-keygen и переносом ключа, разобранный со скриншотами.
-
Видео и материалы сообщества — ниже — ролики по теме и ссылки от студентов и преподавателей смотри в самом низу страницы.
SSH создал в 1995 году финский исследователь Тату Улёнен — после того, как в сети его университета завёлся сниффер паролей. Программа, написанная в ответ на один инцидент, за пару месяцев набрала двадцать тысяч пользователей.
Комментарии
Обсуждение живёт в GitHub Discussions и грузится с чужого домена — поэтому только по нажатию.