SSH-ключи: настройка входа на сервер без пароля
Настройка SSH-ключей сводится к трём шагам: создать пару ключей командой ssh-keygen -t ed25519, скопировать публичный ключ на сервер командой ssh-copy-id user@host и проверить вход. После этого в /etc/ssh/sshd_config отключают вход по паролю (PasswordAuthentication no), а частые подключения описывают в ~/.ssh/config.
SSH-ключ — это пара файлов: закрытый ключ остаётся у вас, открытый кладётся на сервер. При подключении сервер проверяет, что у вас есть закрытый ключ, соответствующий одному из разрешённых открытых, и пускает без пароля. Это удобнее и намного надёжнее пароля: подобрать ключ перебором практически невозможно. Ниже — настройка SSH-ключей от генерации до запрета входа по паролю, с разбором ошибок, на которых спотыкаются чаще всего.
Как работает аутентификация по ключу
Ключи асимметричные. Открытый ключ (id_ed25519.pub) можно показывать кому угодно — по нему нельзя восстановить закрытый. Закрытый ключ (id_ed25519) никогда не покидает вашу машину и не передаётся по сети.
При входе клиент сообщает серверу, каким ключом хочет войти. Сервер ищет этот открытый ключ в файле ~/.ssh/authorized_keys пользователя, и если находит — просит клиента подписать данные сессии закрытым ключом. Подпись сверяется с открытым ключом, и вход разрешается. Пароль при этом не передаётся вообще.
Шаг 1. Сгенерировать ключ: ssh-keygen
На своём компьютере (Linux, macOS или Windows 10/11 с встроенным OpenSSH) выполните:
ssh-keygen -t ed25519 -C "alena@laptop"
Флаг -t задаёт алгоритм, -C — комментарий, который попадёт в конец открытого ключа и поможет потом понять, чей это ключ. Ed25519 — современный рекомендуемый алгоритм: ключи короткие, быстрые и надёжные. Если сервер очень старый и не поддерживает Ed25519, используйте RSA длиной не меньше 3072 бит: ssh-keygen -t rsa -b 4096.
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/alena/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/alena/.ssh/id_ed25519
Your public key has been saved in /home/alena/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:Xq3v0m6c1y2pVv8m3N0uYv9yQm0e6dFv5gH2rZt1aBc alena@laptop
Нужна ли парольная фраза
Passphrase шифрует закрытый ключ на диске. Если ноутбук украдут или файл утечёт, без фразы ключ бесполезен. Для личного ключа фразу ставить стоит, а чтобы не вводить её при каждом подключении, используйте ssh-agent: он держит расшифрованный ключ в памяти до конца сессии.
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l # список загруженных ключей
Ключи без парольной фразы оправданы для автоматики — например, для CI или скрипта бэкапа. Такой ключ лучше ограничить на сервере (об этом ниже).
Шаг 2. Скопировать открытый ключ на сервер: ssh-copy-id
Самый простой способ — ssh-copy-id. Он подключится по паролю последний раз, допишет ваш открытый ключ в ~/.ssh/authorized_keys на сервере и выставит правильные права.
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@203.0.113.10
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/alena/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
deploy@203.0.113.10's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'deploy@203.0.113.10'"
and check to make sure that only the key(s) you wanted were added.
Если сервер слушает нестандартный порт, добавьте -p 2222.
Если ssh-copy-id недоступен
В Windows утилиты ssh-copy-id нет. Ключ можно передать вручную одной командой:
cat ~/.ssh/id_ed25519.pub | ssh deploy@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
У облачных провайдеров открытый ключ обычно указывают ещё при создании сервера — он попадает в authorized_keys через cloud-init.
Шаг 3. Проверить вход
ssh deploy@203.0.113.10
Если пароль больше не спрашивают (или спрашивают только passphrase ключа), всё работает. При первом подключении к новому серверу SSH покажет отпечаток ключа хоста и спросит, доверять ли ему. После ответа yes отпечаток сохранится в ~/.ssh/known_hosts, и в дальнейшем SSH будет предупреждать, если ключ сервера изменится.
Чтобы увидеть, какие ключи пробует клиент и почему сервер отказывает, запустите подключение с подробным выводом:
ssh -v deploy@203.0.113.10
Файл ~/.ssh/config: короткие имена для серверов
Когда серверов несколько, набирать каждый раз пользователя, IP, порт и путь к ключу утомительно. Всё это описывают в ~/.ssh/config:
Host prod
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Host bastion
HostName bastion.example.com
User alena
Host db-internal
HostName 10.0.0.15
User admin
ProxyJump bastion
Host *
ServerAliveInterval 60
AddKeysToAgent yes
Теперь достаточно ssh prod, а scp, rsync и Git тоже понимают эти имена: rsync -av ./site/ prod:/var/www/.
IdentitiesOnly yes— использовать только указанный ключ. Без этой строки клиент перебирает все ключи из агента, и сервер может отключить вас по лимиту попыток раньше, чем дойдёт до нужного.ProxyJump— подключиться к внутреннему серверу через промежуточный (бастион) одной командой.ServerAliveInterval— отправлять «пинг» раз в 60 секунд, чтобы соединение не обрывалось при простое.
Права на файл должны быть 600, иначе SSH может отказаться его читать: chmod 600 ~/.ssh/config.
Agent forwarding: когда он нужен и чем опасен
Иногда с сервера нужно подключиться дальше — например, сделать git pull из приватного репозитория. Копировать туда закрытый ключ нельзя. Вместо этого используют ssh -A или ForwardAgent yes: сервер получит доступ к вашему агенту на время сессии. Но любой, у кого есть root на этом сервере, тоже сможет воспользоваться агентом, пока вы подключены. Поэтому включайте проброс только для доверенных хостов, а для перехода через промежуточный сервер предпочитайте ProxyJump: он не открывает агент.
Шаг 4. Отключить вход по паролю
Пока вход по паролю разрешён, сервер остаётся мишенью для перебора. Когда вы убедились, что входите по ключу, отключите пароли. Важно: не закрывайте текущую сессию, пока не проверите вход в новом окне, иначе можно потерять доступ.
Откройте /etc/ssh/sshd_config (или создайте файл в /etc/ssh/sshd_config.d/, если основной конфиг его подключает директивой Include) и задайте:
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
PermitRootLogin no запрещает входить под root вообще: администраторы заходят под своими пользователями и повышают права через sudo. Если без входа под root никак, используйте PermitRootLogin prohibit-password — только по ключу.
Проверьте синтаксис и перезапустите службу:
sudo sshd -t
sudo systemctl reload ssh # в Debian/Ubuntu; в RHEL-подобных — sshd
Команда sshd -t молчит, если конфиг корректен. Теперь в новом терминале убедитесь, что вход по ключу работает, а с паролем сервер отвечает отказом:
$ ssh -o PubkeyAuthentication=no deploy@203.0.113.10
deploy@203.0.113.10: Permission denied (publickey).
Дополнительная защита
Отключение паролей — главная мера. Дальше обычно ограничивают доступ к порту 22 файрволом (ufw allow from 198.51.100.0/24 to any port 22) и ставят fail2ban, который банит IP после серии неудачных попыток. Статус защиты SSH показывает sudo fail2ban-client status sshd.
Ключ для автоматики можно ограничить прямо в authorized_keys опциями перед ключом: например, from="198.51.100.7",no-port-forwarding,no-pty ssh-ed25519 AAAA... backup разрешит вход только с одного адреса и без интерактивной оболочки.
Типичные ошибки и как их исправить
Permission denied (publickey)
Самая частая ошибка. Причины, от частых к редким:
- Неверные права на сервере. sshd игнорирует
authorized_keys, если каталог или файл доступны на запись другим. Исправление:chmod 700 ~/.ssh,chmod 600 ~/.ssh/authorized_keys, и домашний каталог не должен быть доступен на запись группе и остальным. - Неверный владелец. Если вы создавали файлы через
sudo, они принадлежат root. Исправление:sudo chown -R deploy:deploy /home/deploy/.ssh. - Ключ попал не тому пользователю. Вы скопировали ключ для
root, а входите какdeploy, или наоборот. - Клиент предлагает не тот ключ. Посмотрите
ssh -v: в строкахOffering public keyвидно, какие ключи пробуются. Укажите нужный через-iилиIdentityFile. - Ключ испорчен при копировании. Открытый ключ должен быть одной строкой. Перенос строки из буфера обмена ломает его.
Причину отказа на стороне сервера покажет журнал: sudo journalctl -u ssh -n 30 (в RHEL — -u sshd). Там встречаются строки вида Authentication refused: bad ownership or modes for directory /home/deploy/.ssh.
UNPROTECTED PRIVATE KEY FILE
Клиент отказывается использовать закрытый ключ, который читают другие пользователи. Исправление: chmod 600 ~/.ssh/id_ed25519.
REMOTE HOST IDENTIFICATION HAS CHANGED
Ключ хоста не совпадает с сохранённым в known_hosts. Так бывает после переустановки сервера или смены IP, но так же выглядит и атака «человек посередине». Убедитесь, что сервер действительно пересоздавали, и удалите старую запись: ssh-keygen -R 203.0.113.10.
Too many authentication failures
Агент предложил серверу слишком много ключей, и тот закрыл соединение по MaxAuthTries. Решение — IdentitiesOnly yes и явный IdentityFile в ~/.ssh/config.
Итог
Настройка SSH-ключей занимает пять минут: ssh-keygen -t ed25519, ssh-copy-id, проверка входа, затем PasswordAuthentication no и перезагрузка sshd при открытой второй сессии. Файл ~/.ssh/config избавляет от длинных команд, а права 700/600 решают большинство ошибок «Permission denied». SSH, rsync и защита сервера файрволом и fail2ban разобраны на практике в курсе по Linux.
Частые вопросы
Можно ли использовать один SSH-ключ для всех серверов?
Технически да, и многие так делают. Но для разных зон ответственности (работа, личные проекты, CI) лучше завести отдельные ключи: утечка одного не откроет доступ ко всему.
Где хранятся SSH-ключи в Windows?
Встроенный OpenSSH хранит их в C:\Users\имя\.ssh\ — там же id_ed25519, id_ed25519.pub, known_hosts и config. Генерация выполняется той же командой ssh-keygen в PowerShell.
Как сменить парольную фразу у существующего ключа?
Выполните ssh-keygen -p -f ~/.ssh/id_ed25519: команда попросит старую фразу и новую. Сам ключ не меняется, перекладывать его на серверы не нужно.
Как отозвать доступ по ключу?
Удалите строку с этим открытым ключом из ~/.ssh/authorized_keys на сервере. Комментарий в конце ключа помогает найти нужную строку.
Как получить открытый ключ, если остался только закрытый?
Команда ssh-keygen -y -f ~/.ssh/id_ed25519 выводит открытый ключ, вычисленный из закрытого.
Эта тема подробно разобрана с практикой в курсе «Linux: с нуля до уверенного администрирования».
- Удалённый доступ и сетевые хранилища: SSH, rsync, NFS и SMB
- Firewall и защита сервера: ufw, nftables, fail2ban и GPG