SSH отклоняет ключ: где искать причину и как исправить
Когда SSH-клиент пишет Permission denied (publickey), проблема может быть в ключах, правах на файлы, настройках сервера или клиента. Разберёмся, как устроена проверка ключей, где искать подсказки в логах и что делать, если доступ не работает.
Как SSH проверяет ключи: шаг за шагом
SSH-авторизация по ключам работает не так просто, как кажется. Клиент и сервер обмениваются несколькими сообщениями, прежде чем разрешить доступ. Вот что происходит на каждом этапе:
- Клиент подключается к серверу и начинает процесс аутентификации.
- Клиент предлагает открытый ключ (без подписи) из своего списка доступных ключей.
- Сервер проверяет, есть ли этот ключ в файле
authorized_keysпользователя.- Если ключа нет или права на файлы неверные, сервер отвечает
SSH_MSG_USERAUTH_FAILURE, и клиент видитAuthentications that can continue: publickey,.... - Если ключ есть и права корректны, сервер отвечает
SSH_MSG_USERAUTH_PK_OKи просит клиента подписать данные сессии.
- Если ключа нет или права на файлы неверные, сервер отвечает
- Клиент подписывает данные закрытым ключом и отправляет подпись серверу.
- Сервер проверяет подпись открытым ключом из
authorized_keys.- Если подпись верна, доступ разрешается, и клиент видит
Authenticated to host ... using "publickey". - Если подпись неверна, клиент пробует следующий ключ из своего списка.
- Если подпись верна, доступ разрешается, и клиент видит
Кандидаты ключей — ключи из агента и из IdentityFile/-i; без IdentityFile берутся стандартные файлы (~/.ssh/id_rsa, id_ecdsa, id_ecdsa_sk, id_ed25519, id_ed25519_sk). При большом числе ключей сервер может разорвать сессию по MaxAuthTries (по умолчанию 6), и нужный ключ не будет предложен.
Если клиент перебрал все ключи, но ни один не подошёл, сервер возвращает Permission denied (publickey). При этом клиент не знает, почему ключ был отклонён: его нет в authorized_keys, у файла плохие права, или сработали другие ограничения сервера.
Где искать подсказки: подробный вывод клиента
Чтобы понять, почему сервер отклонил ключ, запустите клиент с флагом -vvv (максимальный уровень детализации). Вот что можно увидеть в выводе:
$ ssh -vvv user@host
...
debug1: Offering public key: ~/.ssh/id_ed25519 ED25519 SHA256:abc123 explicit
debug1: Authentications that can continue: publickey,password
...
Что означают ключевые строки
-
Offering public keyКлиент предлагает ключ серверу. Если этой строки нет для конкретного ключа, значит, клиент его не нашёл (например, из-за неверного пути или прав на файл). -
Authentications that can continue: publickey,...Сервер отклонил ключ. Причины могут быть разные:- Ключа нет в
authorized_keys. - У файла
authorized_keysили каталога~/.sshплохие права. - Сервер настроен на запрет определённых ключей или пользователей.
- Ключа нет в
-
Отсутствие
Authenticated to host ... using "publickey"Если ключ предложен и отклонён, клиент не знает почему (нет вauthorized_keys, права/владелец,AuthorizedKeysFile/AllowUsers/Match). Различить можно только по журналу сервера.
Как отличить проблемы клиента от проблем сервера
-
Проблемы клиента:
- Ключ не предлагается (
Offering public keyотсутствует). - Клиент перебирает не те ключи (например, из-за неверной настройки
IdentityFile).
- Ключ не предлагается (
-
Проблемы сервера:
- Ключ предлагается, но сервер его отклоняет (
Authentications that can continue: publickey,...). - Если ключ принят, клиент видит
Server accepts key: ....
- Ключ предлагается, но сервер его отклоняет (
Если проблема на стороне сервера, нужно проверять его журналы. Там можно найти сообщения вроде:
Authentication refused: bad ownership or modes for file ~/.ssh/authorized_keys
или
Failed publickey for user from 192.168.1.1 port 12345 ssh2: ED25519 SHA256:abc123
Права на файлы и каталоги: почему сервер отклоняет ключ
SSH-сервер строго проверяет права на файлы и каталоги. Если что-то не так, он отклоняет ключ, даже если он правильный. Вот что нужно проверить:
1. Права на домашний каталог (~)
- Проблема: Если домашний каталог или любой каталог от него вверх до
~/.sshвключительно доступен на запись группе или остальным, сервер откажется использовать ключи. - Исправление: Снимите право записи для группы и остальных:
chmod go-w ~ - Проверка владельца: Сначала проверьте текущего владельца:
Если владелец неверный, исправьте от root с явным путём:ls -ld ~ ~/.ssh ~/.ssh/authorized_keyssudo chown -R alice: /home/alice/.ssh sudo chown alice: /home/alice
2. Права на каталог ~/.ssh
- Проблема: Каталог должен быть доступен только пользователю (рекомендуется
700). - Исправление:
chmod 700 ~/.ssh
3. Права на файл ~/.ssh/authorized_keys
- Проблема: Файл должен быть доступен только пользователю (рекомендуется
600). - Исправление:
chmod 600 ~/.ssh/authorized_keys
4. SELinux: восстановление контекста безопасности
На системах с SELinux (например, RHEL, CentOS, Fedora) нужно восстановить контекст безопасности:
restorecon -Rv ~/.ssh
Если права нарушены, сервер не будет использовать ключ, даже если он правильный. Проверяйте права внимательно: sshd отказывается, если authorized_keys, ~/.ssh или любой каталог от него вверх до домашнего каталога включительно доступен на запись группе/остальным либо принадлежит не пользователю и не root.
Как явно указать ключ для конкретного хоста
Если у вас несколько ключей, клиент может перебирать их в неверном порядке или предлагать не тот ключ. Чтобы этого избежать, можно явно указать ключ для конкретного хоста в файле ~/.ssh/config:
Host example.com
HostName example.com
User user
IdentityFile ~/.ssh/id_ed25519_example
IdentitiesOnly yes
Что делают эти параметры
IdentityFile: Указывает путь к ключу, который нужно использовать для этого хоста.IdentitiesOnly yes: Запрещает клиенту предлагать ключи из агента, которых нет вIdentityFile. Это полезно, если у вас много ключей, но для конкретного хоста нужен только один.
Как проверить, какой ключ предлагает клиент
Запустите клиент с флагом -v и посмотрите, какие ключи он предлагает:
$ ssh -v user@example.com
...
debug1: Offering public key: ~/.ssh/id_ed25519_example ED25519 SHA256:abc123 explicit
...
Если клиент предлагает не тот ключ, проверьте настройки в ~/.ssh/config или передайте ключ явно с помощью флага -i:
ssh -i ~/.ssh/id_ed25519_example user@example.com
Подключение к git-хостингу: типичные ошибки
При подключении к git-хостингу (например, для клонирования репозитория) часто возникают проблемы с ключами. Вот что нужно проверить:
1. Ключ привязан к аккаунту
- Проблема: Если открытый ключ не добавлен в настройки аккаунта на хостинге, сервер его не примет.
- Исправление: Добавьте открытый ключ в настройки аккаунта на хостинге.
2. Правильный пользователь в адресе
- Проблема: В SSH-адресе репозитория указывается служебный пользователь хостинга (например,
git@git-host), а не имя вашего аккаунта. Аккаунт определяется по ключу. - Исправление: Используйте SSH-адрес репозитория, а не HTTPS:
git clone git@git-host:user/repo.git
3. Репозиторий клонирован по HTTPS
- Проблема: Если репозиторий клонирован по HTTPS, ключи не используются.
- Исправление: Переключитесь на SSH-адрес:
git remote set-url origin git@git-host:user/repo.git
4. Проверка подключения
Убедитесь, что ключ работает, с помощью команды:
ssh -T git@git-host
Она покажет, за какой аккаунт сервер принял ключ. Если ключ не привязан к аккаунту, вы увидите сообщение об ошибке.
Тупик: почему не помогает перегенерация ключей
Часто при проблемах с доступом первым делом генерируют новый ключ и копируют его на сервер. Но если причина в другом, это не поможет. Вот типичные ситуации, когда перегенерация ключей не решает проблему:
1. Неверные права на файлы или каталоги
Если домашний каталог, ~/.ssh или authorized_keys доступны на запись группе или остальным, либо принадлежат не тому пользователю, сервер будет игнорировать все ключи, пока права не исправлены.
2. Клиент предлагает не тот ключ
Если в ~/.ssh/config указан неверный ключ для хоста, клиент будет предлагать его снова и снова, даже если правильный ключ есть в authorized_keys.
3. Ограничения сервера
Сервер может быть настроен на запрет определённых ключей или пользователей (например, через AllowUsers или Match). В этом случае нужно проверять журналы сервера.
Позиция редакции
При отказе в доступе первым делом нужно читать подробный вывод клиента (ssh -vvv). Это позволяет быстро найти проблему: неверные права, отсутствие ключа в authorized_keys или не тот ключ, который предлагает клиент.
Однако эта рекомендация неверна, если доступ закрыт на стороне сервера политикой, которую клиент не видит. Например, если сервер настроен на запрет определённых ключей или пользователей, клиент об этом не узнает. В таком случае нужно проверять журнал сервера. Смотрите журнал юнита: journalctl -u ssh (Debian/Ubuntu) или journalctl -u sshd (RHEL/Fedora). В OpenSSH 9.8+ сообщения о входе пишет процесс sshd-session, поэтому если фильтруете по идентификатору, указывайте оба: journalctl -t sshd -t sshd-session. Чтобы увидеть отказы по конкретным ключам, временно включите LogLevel VERBOSE в sshd_config.
Если проблема не решается, проверьте:
- Права на файлы и каталоги (
~,~/.ssh,authorized_keys). - Настройки клиента (
~/.ssh/config,IdentityFile). - Журналы сервера.