Как исправить ошибку SSH «Permission denied (publickey)»
Вход по SSH обрывается с Permission denied (publickey)? Семь причин, от прав на файлы и AllowUsers до SELinux, каждая с точной строкой из журнала и подходящим средством устранения.
Попытка соединения обрывается через секунду, запроса пароля нет, только одна-единственная строка: Permission denied (publickey). Это сообщение неприятно именно тем, что оно намеренно ничего не выдаёт. SSH-сервер не подскажет потенциальному злоумышленнику, существует ли такой пользователь, был ли ключ неверным или файл оказался нечитаемым. Но ровно та же скрытность достаётся и вам, когда вы стоите под дверью на законных основаниях.
Хорошая новость: список причин конечен, их можно перебрать в жёстко заданном порядке, и в большинстве случаев дело просто в правах на файлы. Эта статья разбирает причины по частоте их появления, приводит к каждой точную формулировку из журнала и объясняет, как с помощью ssh -vvv за тридцать секунд понять, где именно проблема: на вашей машине или на сервере.
Что именно означает это сообщение
Скобка в конце строки не украшение, а самая важная её часть. В ней перечислены способы аутентификации, которые сервер всё ещё предлагает после неудачной попытки:
Permission denied (publickey).
Permission denied (publickey,password).
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
Если там указан только publickey, вход по паролю на сервере отключён. Если в списке есть password, вход по паролю в принципе был возможен, просто его не пробовали или он тоже не прошёл. Вариант с gssapi характерен для AlmaLinux, Rocky Linux и RHEL: там поддержка Kerberos вкомпилирована в пакет.
Важно отличать эту строку от сообщений, которые выглядят похоже, но описывают совершенно другую проблему:
Permission denied, please try again.без скобки означает неверный пароль, а не проблему с ключом.Host key verification failed.относится к ключу сервера в вашем файлеknown_hosts, а не к вашему собственному ключу.Received disconnect from 203.0.113.7 port 22:2: Too many authentication failuresозначает, что ваш агент предложил подряд слишком много ключей и сервер оборвал соединение по достиженииMaxAuthTries.Connection refusedили таймаут относятся к сети или к файрволу. Если незадолго до этого вы правили файрвол UFW или Fail2ban, начинайте оттуда.
Развилка: как правильно читать ssh -vvv
Прежде чем что-то менять, посмотрите на сам ход аутентификации. Три v здесь не случайность: с одним v решающих строк в выводе не будет:
ssh -vvv deploy@203.0.113.7
Вывод длинный, но интересуют всего четыре места. Первое: имя пользователя, с которым соединение действительно устанавливается:
debug1: Authenticating to 203.0.113.7:22 as 'deploy'
Второе: какие ключи клиент вообще рассматривает. Третье: какой из них он в самом деле отправляет:
debug1: Will attempt key: /home/tom/.ssh/id_ed25519 ED25519 SHA256:8Qk... agent
debug1: Offering public key: /home/tom/.ssh/id_ed25519 ED25519 SHA256:8Qk... agent
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
И четвёртое: сообщение об успехе, которого при ошибке как раз и нет:
debug1: Server accepts key: /home/tom/.ssh/id_ed25519 ED25519 SHA256:8Qk...
debug1: Authenticated to 203.0.113.7 ([203.0.113.7]:22) using "publickey".
Отсюда и получается развилка, которая экономит половину времени на поиск причины:
- Строки
Offering public keyс вашим ключом нет. Значит, проблема на вашей машине, ключ вообще не был отправлен. Переходите к причине 3. - Строка
Offering public keyесть, но следом снова идётAuthentications that can continue. Значит, сервер увидел ваш ключ и отклонил его. Это причины 1, 2, 4, 5 и 6, все на стороне сервера. - Появляется
send_pubkey_test: no mutual signature algorithm. Значит, дело в типе ключа, переходите к причине 7.
Ещё две строки отладочного вывода заслуживают внимания. debug3: no such identity: /home/tom/.ssh/id_rsa: No such file or directory безобидна: клиент просто перебирает все стандартные имена. А вот Permissions 0644 for '/home/tom/.ssh/id_ed25519' are too open. — это уже настоящее попадание, ваш закрытый ключ в таком случае игнорируется.
Сторона сервера: sshd -T и журналы
ssh -vvv показывает исключительно точку зрения клиента. Причина отказа записана только в журнале сервера. Если у вас ещё осталась открытая сессия или вы можете зайти через консоль в личном кабинете, смотрите в первую очередь туда.
В Debian и Ubuntu служба называется ssh, в AlmaLinux, Rocky Linux и RHEL — sshd. Это классическая ловушка при копировании команд:
journalctl -u ssh -n 50 --no-pager # Debian, Ubuntu
journalctl -u sshd -n 50 --no-pager # AlmaLinux, Rocky, RHEL
Классический текстовый журнал есть уже не везде. Ubuntu 22.04 и 24.04 в серверной установке по-прежнему ведут /var/log/auth.log, потому что rsyslog там входит в комплект. Debian 12 и Debian 13 в минимальной установке rsyslog больше не ставят, поэтому файла там просто нет и всё попадает в журнал systemd. В семействе Red Hat файл называется /var/log/secure. Если текстовый файл на Debian нужен обратно, rsyslog доустанавливается отдельно: в Debian и Ubuntu командой apt-get install -y rsyslog, в семействе Red Hat командой dnf install -y rsyslog.
Вторая серверная команда ещё важнее, потому что она выводит реально действующую конфигурацию и раскрывает при этом все подключённые файлы:
sshd -T | grep -Ei 'pubkeyauth|authorizedkeysfile|strictmodes|permitrootlogin'
Если вместо конфигурации команда отвечает только Missing privilege separation directory: /run/sshd и не выводит ни одной строки, значит, не хватает каталога времени выполнения. Так бывает на Debian 11, Debian 12, Ubuntu 22.04 и Ubuntu 24.04 сразу после установки пакета, пока служба ни разу не запускалась, а также в контейнерах. При обычной работе systemd-юнит создаёт этот каталог сам через RuntimeDirectory=sshd. Если сообщение появилось, помогает предварительный mkdir -p /run/sshd, после чего sshd -T нормально выдаёт permitrootlogin, pubkeyauthentication yes, strictmodes yes и authorizedkeysfile. Debian 13 с OpenSSH 10 и всё семейство Red Hat этого ограничения уже не знают. Учтите, что в конвейере сообщение теряется: sshd -T | grep ... покажет тогда просто пустой вывод, а сам код возврата 255 растворится в grep.
А если хочется по-настоящему увидеть, что думает сервер, не трогая работающую службу, запустите второй экземпляр в режиме отладки на свободном порту. После одного соединения он завершится сам и заблокировать вам доступ не может.
/usr/sbin/sshd -ddd -p 2222
Затем со своей машины выполните ssh -p 2222 deploy@203.0.113.7, и в терминале сервера причина отказа будет видна открытым текстом. Порт для этого, разумеется, должен быть открыт в файрволе.
Причина 1: права и владелец, самый частый случай с большим отрывом
В OpenSSH по умолчанию включена опция StrictModes yes. Сервер отказывается читать ключ из файла, в который может писать кто-то кроме самого пользователя. Это не придирка: так исключается ситуация, когда другой пользователь просто дописывает собственный ключ в ваш authorized_keys.
Целевое состояние задано жёстко:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 750 ~
chown -R "$(id -un):$(id -gn)" ~/.ssh
Проверить это можно одной строкой:
stat -c "%a %U %G %n" ~ ~/.ssh ~/.ssh/authorized_keys
Ожидаются 750 или 700 для домашнего каталога, 700 для .ssh и 600 для authorized_keys, и во всех трёх строках должно стоять ваше собственное имя пользователя. Решающее условие: домашний каталог не должен быть доступен на запись группе и остальным, так что 770 или 777 уже достаточно для отказа.
Одно число при этом нельзя принимать за ошибку: в AlmaLinux, Rocky Linux и Oracle Linux у каталога /root права 550, а не 700, как в Debian и Ubuntu. stat -c показывает это верно, и так и должно быть. Для StrictModes важно лишь то, что у группы и остальных нет права записи, а 550 этому условию как раз соответствует. Тот, кто дополнительно выполнит здесь chmod 700 /root, вход не починит, а только глубже спрячет настоящую причину.
В журнале сервера это написано вполне однозначно:
Authentication refused: bad ownership or modes for directory /home/deploy/.ssh
Authentication refused: bad ownership or modes for file /home/deploy/.ssh/authorized_keys
error: Could not open authorized keys '/home/deploy/.ssh/authorized_keys': Permission denied
Две детали, которые другие руководства охотно опускают. Первая — владелец: если файл создан командой sudo nano ~/.ssh/authorized_keys, он принадлежит root, а не пользователю, и вход не проходит даже при идеальных правах 600. Вторая: sshd проверяет весь путь вверх по дереву. Если домашний каталог лежит не в /home, а, скажем, в /srv/clients/deploy, то и /srv, и /srv/clients должны принадлежать root или пользователю и не быть доступными на запись группе и остальным.
Причина 2: неверное имя пользователя
Несуществующий пользователь порождает ровно то же сообщение, что и неверный ключ, ведь сервер намеренно не раскрывает, какой из двух случаев перед вами. В журнале разница видна сразу:
Invalid user deply from 203.0.113.7 port 51234
Чаще всего причина в том, что ключ лежит в /root/.ssh/authorized_keys, а вы входите под обычным пользователем, или наоборот. В готовых облачных образах вход под root часто закрыт, вместо него есть заранее подготовленный пользователь: в зависимости от дистрибутива debian, ubuntu, almalinux или rocky. А вот в стандартных образах на root-сервере KernelHost вы входите напрямую как root.
Проверьте также, не подставляет ли вам другой логин файл ~/.ssh/config. Следующая команда не устанавливает соединение, а лишь показывает, какие настройки реально действуют для этой цели:
ssh -G deploy@203.0.113.7
В выводе интересны user, hostname, port и список записей identityfile.
Причина 3: ключ вообще не предлагается
Если в выводе ssh -vvv нет строки Offering public key с вашим ключом, у сервера просто не было шанса. Для этого есть четыре типичные причины.
У ключа нестандартное имя
Автоматически OpenSSH перебирает только стандартные имена id_ed25519, id_ecdsa и id_rsa. Ключ с именем id_production будет использован, только если вы укажете его явно:
ssh -i ~/.ssh/id_production -o IdentitiesOnly=yes deploy@203.0.113.7
IdentitiesOnly=yes здесь не украшение. Без этой опции ssh дополнительно предложит все ключи из агента, и при слишком большом числе попыток сервер оборвёт соединение с Too many authentication failures ещё до того, как очередь дойдёт до нужного ключа.
В агенте нет ключа
ssh-add -l
Если команда отвечает The agent has no identities. или Could not open a connection to your authentication agent., догрузите ключ командой ssh-add ~/.ssh/id_ed25519.
Права на закрытом ключе
У закрытого ключа должны быть права 600, иначе клиент откажется работать. В Windows chmod не действует, там всё решается через ACL:
icacls %USERPROFILE%\.ssh\id_ed25519 /inheritance:r /grant:r "%USERNAME%":R
Файл authorized_keys повреждён
Открытый ключ занимает ровно одну строку. При копировании через редакторы, тикет-системы или окна чата в середине блока Base64 легко появляется перенос, и после этого не сходится уже ничего. Пересчитайте:
grep -c '^ssh-' ~/.ssh/authorized_keys
awk '{print NR": "NF" полей, тип "$1}' ~/.ssh/authorized_keys
Каждая строка должна начинаться с ssh-ed25519, ssh-rsa или ecdsa-sha2- и состоять из двух-трёх полей. Число строк должно совпадать с числом ключей. Вторая классическая ошибка: вместо открытого ключа по недосмотру вписан закрытый, это узнаётся по BEGIN OPENSSH PRIVATE KEY. А ключ в формате PuTTY (.ppk) в таком виде не работает, его сначала нужно экспортировать в формат OpenSSH.
Соответствуют ли друг другу закрытый и открытый ключ, покажет сравнение отпечатков:
ssh-keygen -lf ~/.ssh/id_ed25519.pub
ssh-keygen -lf ~/.ssh/authorized_keys
Одно и то же значение SHA256 должно встретиться в обоих выводах. Как всё это выглядит при аккуратной первоначальной настройке, описано в нашей статье про защиту SSH и настройку входа по ключу.
Причина 4: PubkeyAuthentication выключен
Встречается реже, зато не оставляет сомнений. Проверяйте не файл конфигурации, а результат:
sshd -T | grep -i pubkeyauthentication
Здесь прячется ловушка, которая стоит многих часов. В Debian начиная с 12 и в Ubuntu начиная с 22.04 в самом начале /etc/ssh/sshd_config стоит строка Include /etc/ssh/sshd_config.d/*.conf. В sshd действует правило: для каждого ключевого слова учитывается первое найденное значение. Поскольку подключение файлов стоит в начале, любая мелочь из sshd_config.d побеждает основной файл, что бы ни было написано в нём ниже. Если ваша правка не даёт эффекта, смотрите туда:
grep -rniE 'pubkeyauthentication|authorizedkeysfile|allowusers|allowgroups' /etc/ssh/
Второй пункт этой же категории — AuthorizedKeysFile. По умолчанию это .ssh/authorized_keys и .ssh/authorized_keys2. Некоторые скрипты усиления безопасности переставляют путь на что-нибудь вроде /etc/ssh/authorized_keys/%u. После этого ваш файл в домашнем каталоге игнорируется полностью, без единого сообщения об ошибке. Это тоже видно в выводе sshd -T.
Причина 5: срабатывают AllowUsers, AllowGroups и Match
Эти директивы отсекают целые группы пользователей, причём ещё до того, как ключ вообще будет проверен. Формулировки в журнале:
User root from 203.0.113.7 not allowed because not listed in AllowUsers
User deploy from 203.0.113.7 not allowed because none of user's groups are listed in AllowGroups
User root from 203.0.113.7 not allowed because "PermitRootLogin no"
Запомните порядок старшинства: DenyUsers сильнее AllowUsers, и как только AllowUsers вообще задан, все неперечисленные пользователи оказываются отрезаны. Для AllowGroups должно совпадать членство в группе, это проверяется командой id deploy.
Для PermitRootLogin важно различать значения: prohibit-password разрешает вход под root по ключу. Полностью закрывает root только no. Но в выводе sshd -T слова prohibit-password не ждите: там стоит более старое, равнозначное имя without-password. И значение по умолчанию отнюдь не везде одинаково, что при сравнении двух серверов регулярно сбивает с толку:
| Система | Значение из sshd -T |
|---|---|
| Debian 11, 12, 13 | without-password |
| Rocky Linux 9, Oracle Linux 9 | without-password |
| AlmaLinux 9, AlmaLinux 10 | yes |
То есть в AlmaLinux root может войти и по паролю, а в остальных перечисленных системах нет. Тот, кто переносит службу с AlmaLinux на Debian и до сих пор входил под root по паролю, после переезда получает ровно Permission denied (publickey).
Если правило спрятано в блоке Match, поможет опция, которая вычисляет конфигурацию для конкретного случая:
sshd -T -C user=deploy,host=client.example.com,addr=203.0.113.7 | grep -Ei 'pubkeyauth|allowusers|permitrootlogin'
Это самый надёжный способ увидеть, что действует именно для этого пользователя и именно с этого IP-адреса.
Причина 6: SELinux в AlmaLinux, Rocky и RHEL
В семействе Red Hat SELinux по умолчанию работает в режиме Enforcing, в Debian и Ubuntu он роли не играет. Процесс sshd может прочитать authorized_keys, только если у файла контекст ssh_home_t. Так и происходит, если файл был создан обычным образом в домашнем каталоге. И не происходит, если вы перенесли его командой mv из /tmp или создали домашний каталог вручную, ведь mv тащит за собой старый контекст.
getenforce
ls -Z ~/.ssh
Правильная запись оканчивается на ssh_home_t. Если там user_tmp_t или user_home_t, причина найдена. Исправление:
restorecon -R -v ~/.ssh
Этот шаг относится исключительно к семейству Red Hat. В Debian и Ubuntu штатной установки SELinux нет, там оболочка ответит restorecon: command not found, и это не ошибка, а просто неприменимый случай. Но и в AlmaLinux с Rocky Linux при облегчённой установке команды может не оказаться, потому что нужный пакет не поставлен. Тогда сначала доустановите его:
dnf install -y policycoreutils
Подтверждение находится в журнале аудита, там отказ записан открытым текстом:
ausearch -m avc -ts recent
Если домашние каталоги лежат в необычном месте, одного restorecon мало: SELinux вообще не считает такой путь домашним каталогом. Тогда нужно один раз объявить соответствие и после этого восстановить контексты:
semanage fcontext -a -e /home /srv/clients
restorecon -R -v /srv/clients
semanage лежит в пакете policycoreutils-python-utils. Не отключайте SELinux ради того, чтобы заработал вход: так задача на две команды решается ценой потери безопасности всей системы.
Причина 7: старый сервер, неподходящий тип ключа
Начиная с OpenSSH 8.8 клиент отвергает RSA-подписи с SHA-1. Это касается уже Ubuntu 22.04, а Debian 13 тем временем поставляет OpenSSH 10. Если с такой актуальной системы вы идёте на очень старый сервер, который знает только устаревший ssh-rsa, в отладочном выводе появится:
debug1: send_pubkey_test: no mutual signature algorithm
Это не проблема прав, с вашим ключом всё в порядке. Для разового доступа помогает:
ssh -o PubkeyAcceptedAlgorithms=+ssh-rsa -o HostKeyAlgorithms=+ssh-rsa deploy@203.0.113.7
На постоянной основе этому место в ~/.ssh/config под записью Host, чтобы настройка касалась только этого одного сервера. На очень старых клиентах опция ещё называется PubkeyAcceptedKeyTypes. Настоящее решение — обновить старый сервер, ведь начиная с OpenSSH 7.2 он тоже умеет варианты с SHA-2, и ваш существующий RSA-ключ продолжит работать без изменений. Меняется только способ подписи.
Обратный случай тоже бывает. Ключу ed25519 нужен как минимум OpenSSH 6.5 с обеих сторон, аппаратным токенам типа ed25519-sk как минимум 8.2. А DSA остался в прошлом: начиная с OpenSSH 10.0 ssh-dss удалён полностью, и такие старые ключи против Debian 13 уже не работают вовсе. Какие типы знает ваш клиент, покажет:
ssh -Q key
Если на свежеустановленной AlmaLinux, Rocky Linux или RHEL команды ssh нет вообще, дело в ловушке с именами пакетов: dnf install openssh-server ставит только службу, без клиентских утилит. Без них нет ни ssh, ни ssh-add, а значит, нет и ssh -Q с ssh -G. Доустанавливается пакет с «s» на конце, в отличие от пакета Debian openssh-client:
dnf install -y openssh-clients
В AlmaLinux, Rocky и RHEL 9 добавляется второй уровень. Там на то, что разрешено, влияют общесистемные криптографические политики, независимо от конфигурации sshd:
update-crypto-policies --show
Этот инструмент тоже существует только на стороне Red Hat, в Debian и Ubuntu его нет. И даже в Oracle Linux 9 при минимальной установке он отсутствует, там его доустанавливает dnf install -y crypto-policies-scripts, после чего, как и ожидается, выводится DEFAULT. Если там стоит DEFAULT, подписи SHA-1 уже заблокированы на уровне всей системы. update-crypto-policies --set LEGACY это снимает, но ослабляет всю машину и годится разве что как временное решение на период миграции.
Если вы заблокировали себе доступ
Опасен не сам сбой, а ремонт sshd_config. Три правила, которые делают потерю доступа практически невозможной:
- Держите открытой вторую сессию. Перезапуск sshd не разрывает уже установленные соединения. Пока открыт хотя бы один терминал, любую правку можно откатить.
- Перед каждым перезапуском проверяйте синтаксис.
sshd -tпри ошибке выводит номер строки и молчит, если всё в порядке. Иначе опечатка в конфигурации не даст службе запуститься, и внутрь уже никто не попадёт. Если вместо этого появляетсяMissing privilege separation directory: /run/sshd, с конфигурацией всё хорошо и не хватает только каталога времени выполнения, смотрите выше. - Проверяйте вход из второй сессии, прежде чем закрывать первую.
С перезапуском системы различаются. В Debian и Ubuntu юнит называется ssh, в семействе Red Hat — sshd. Начиная с Ubuntu 22.10 и в Debian 13 SSH дополнительно запускается через активацию по сокету: конфигурация из sshd_config действует по-прежнему, но изменённое значение Port вступает в силу только после перезапуска ssh.socket.
sshd -t
systemctl restart ssh # Debian, Ubuntu
systemctl restart ssh.socket # дополнительно, если изменён порт
systemctl restart sshd # AlmaLinux, Rocky, RHEL
Если это всё же случилось, нужен путь в обход SSH. На root-сервере KernelHost вы открываете в личном кабинете VNC-консоль и входите там по паролю root, вообще без сетевой службы. Если и это не приводит к цели, например потому что sshd больше не запускается, поможет rescue-система: вы загружаетесь в аварийное окружение, монтируете системный раздел и правите authorized_keys и права прямо на накопителе. Не забудьте после монтирования проверить владельцев файлов, ведь в rescue-системе вы работаете как root и иначе создадите файлы с неверным владельцем.
Как убедиться, что вход действительно работает
Успешный вход ещё не означает, что он прошёл по ключу. Пока вход по паролю включён, сервер может молча откатить вас на него. Честная проверка исключает любой другой способ:
ssh -o BatchMode=yes -o PreferredAuthentications=publickey deploy@203.0.113.7 'id -un; hostname'
BatchMode=yes подавляет любые интерактивные запросы. Если в ответ приходят ваше имя пользователя и имя хоста, а echo $? затем выдаёт 0, значит, сработал исключительно ключ.
Второе подтверждение находится в журнале сервера и содержит даже отпечаток использованного ключа:
Accepted publickey for deploy from 203.0.113.7 port 51234 ssh2: ED25519 SHA256:8Qk...
Сравните это значение SHA256 с выводом ssh-keygen -lf ~/.ssh/id_ed25519.pub. Если они совпадают, вы знаете не только то, что вход работает, но и то, каким именно ключом. Это важно, когда в деле несколько ключей и один из них требуется отозвать.
Порядок действий
Если на теорию нет времени, пройдите этот список сверху вниз. Он отсортирован по частоте случаев, а не по изяществу.
- Запустить
ssh -vvvи определить, появляется лиOffering public key. Это делит задачу на клиентскую и серверную половины. - Проверить права:
700на~/.ssh,600наauthorized_keys, домашний каталог без права записи для группы, всё во владении пользователя. - Проверить имя пользователя, в сомнительном случае спросить
ssh -Gи поискать в журналеInvalid user. - Сравнить отпечатки закрытого ключа и
authorized_keys, проконтролировать число строк в файле. - Разобрать вывод
sshd -T:pubkeyauthentication,authorizedkeysfile,strictmodes,permitrootlogin. - Проверить
AllowUsers,AllowGroups,DenyUsersи блокиMatch, вместе с каталогомsshd_config.d. - В семействе Red Hat выполнить
ls -Z ~/.sshи при необходимостиrestorecon -R -v ~/.ssh. - Только для очень старых удалённых систем: расширить набор алгоритмов подписи через
PubkeyAcceptedAlgorithms=+ssh-rsa.
Самое позднее на этом шаге причина находится. Если после этого вы хотите заново и аккуратно настроить доступ, подходящими продолжениями будут введение в подключение по SSH и чек-лист для нового root-сервера.
Частые вопросы
Что означает скобка в «Permission denied (publickey,password)»?
Какие права должны быть у ~/.ssh и authorized_keys?
Как по выводу ssh -vvv понять, где проблема: у клиента или на сервере?
Почему вход по ключу не работает на AlmaLinux, хотя права верные?
Что означает «no mutual signature algorithm»?
Моя правка в /etc/ssh/sshd_config не действует. В чём причина?
Как вернуться на сервер, если я заблокировал себе доступ?
2026 KernelHost GmbH. Все права защищены. Эта инструкция охраняется авторским правом. Публикация на других сайтах, в том числе частично или в изменённом виде, без нашего письменного согласия не разрешается. Цитирование с указанием источника и активной ссылкой мы приветствуем.

