Ошибка SSH Too many authentication failures: как исправить
Ошибка Too many authentication failures возникает из-за перебора ключей в ssh-agent. Узнайте, как ограничить список ключей через IdentitiesOnly и исправить подключение к серверу.
Что означает ошибка "Too many authentication failures"
Ошибка "Too many authentication failures" означает, что ваш SSH-клиент предложил серверу больше ключей, чем тот готов проверить, и сервер закрыл соединение до того, как был использован нужный ключ. Это почти всегда проблема на стороне клиента. Ключ находится на вашем диске, сервер содержит его в authorized_keys, но это не помогает, так как соединение разрывается слишком рано.
Цепочка событий выглядит так. ssh-agent хранит все закрытые ключи, которые вы в него загрузили. Клиент предлагает эти ключи серверу по очереди, так как он не знает, какой из них подходит для данной учетной записи. Сервер отклоняет каждый ключ, которого нет в authorized_keys, и засчитывает каждый отказ как неудачную попытку аутентификации. Параметр MaxAuthTries в sshd_config ограничивает количество допустимых сбоев для одного соединения. По умолчанию это значение равно 6. Если в вашем агенте десять ключей, а нужный стоит восьмым в очереди, сервер разорвет соединение раньше, чем дойдет до него.
Решение заключается в том, чтобы заставить клиент предлагать только один ключ: нужный.
Что учитывает сервер и зачем нужен MaxAuthTries
Аутентификация по открытому ключу начинается как игра в угадывание. Клиент отправляет открытый ключ и запрашивает, примет ли сервер подпись, созданную с его помощью. Сервер отвечает «да» или «нет». Ответ «нет» считается неудачной попыткой, точно так же, как и неверный пароль.
Страница руководства sshd_config(5) описывает это ограничение: «Указывает максимальное количество попыток аутентификации, разрешенных для одного соединения. Как только количество неудач достигает половины этого значения, последующие ошибки записываются в журнал. Значение по умолчанию — 6».
Шести попыток достаточно для человека, вводящего пароль. Но этого мало для агента, хранящего десять ключей. Как только счетчик неудач превышает лимит, sshd разрывает соединение и записывает в системный журнал строку следующего вида:
error: maximum authentication attempts exceeded for deploy from 203.0.113.10 port 51292 ssh2Ваш клиент выводит вторую часть того же события:
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures
Disconnected from 203.0.113.10 port 22Это ошибка иного типа, чем ошибка SSH permission denied (publickey). В том случае сервер проверил все предложенные вами ключи и не принял ни одного. Здесь же сервер просто прекратил проверку. Если перепутать эти две ситуации, можно потратить целый день на повторное копирование ключа, который изначально был верным.
Почему один и тот же ключ работает с ноутбука коллеги
В ключе и на сервере нет никаких различий. В их агенте хранятся два ключа, а в вашем — двенадцать. Предложение, которое для них приходит первым, для вас оказывается девятым, и к этому моменту соединение уже завершено.
Количество ключей растет незаметно. AddKeysToAgent yes в ~/.ssh/config добавляет каждый используемый вами ключ в агент и оставляет его там. Агенты связок ключей в графической оболочке, такие как GNOME Keyring в Linux или login keychain в macOS, загружают ключи при входе в систему без запроса. Добавьте ключ клиента, ключ хоста git и ключ лабораторного сервера в течение года, и однажды сервер, который всегда работал, начнет вам отказывать. На сервере ничего не изменилось. Ваш агент просто стал переполнен.
Как просмотреть предлагаемые ключи с помощью ssh -v
Запустите проблемное соединение с флагом -v и изучите трассировку.
ssh -v deploy@203.0.113.10Важны два типа строк. Will attempt key: перечисляет идентификаторы, которые собрал клиент, в порядке их использования. Offering public key: появляется один раз для каждого ключа, фактически отправленного на сервер.
debug1: Will attempt key: /home/you/.ssh/id_ed25519 ED25519 SHA256:AAAA... agent
debug1: Will attempt key: /home/you/.ssh/id_rsa RSA SHA256:BBBB... agent
debug1: Offering public key: /home/you/.ssh/id_ed25519 ED25519 SHA256:AAAA... agent
debug1: Authentications that can continue: publickey,password
debug1: Offering public key: /home/you/.ssh/id_rsa RSA SHA256:BBBB... agentВаши пути, типы ключей и отпечатки будут отличаться. Вам нужно посчитать количество строк Offering public key: до момента разрыва соединения. Если список предложений проходит, а сессия завершается без появления нужного вам ключа, диагноз ясен. Слово agent в конце строки означает, что идентификатор был получен из ssh-agent. Слово explicit означает, что он был получен из строки IdentityFile или из -i в командной строке.
Затем проверьте, какие ключи хранятся в агенте:
ssh-add -lКаждая строка вывода соответствует одному загруженному ключу. Если выводится The agent has no identities., значит, проблема не в агенте, и вам следует изучить строки IdentityFile в ~/.ssh/config. Если выводится Could not open a connection to your authentication agent., значит, агент не запущен, а предлагаемые ключи берутся из файлов ключей по умолчанию.
Исправление 1: IdentitiesOnly с одним ключом на хост
IdentitiesOnly yes указывает ssh предлагать только те идентификаторы, которые вы настроили, и игнорировать остальные, предлагаемые агентом. Используйте это вместе со строкой IdentityFile, чтобы клиент отправлял только одно предложение.
Host vps
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519_vps
IdentitiesOnly yesСохраните это в ~/.ssh/config, затем выполните chmod 600 ~/.ssh/config. Если файл доступен для записи группе или всем пользователям, ssh откажется работать и выдаст Bad owner or permissions on /home/you/.ssh/config. Теперь ssh vps предлагает один ключ, а ssh -v vps должен показать ровно одну строку Offering public key:.
Два нюанса часто вызывают удивление.
IdentitiesOnly yesсам по себе не означает «один ключ». Файлы идентификации по умолчанию считаются настроенными идентификаторами, поэтому ssh всё равно пытается использовать~/.ssh/id_ed25519,~/.ssh/id_rsaи другие стандартные ключи, которые находит. Вам также необходима строкаIdentityFile.- Агент по-прежнему выполняет подпись.
IdentitiesOnlyуправляет тем, какие ключи предлагаются, а не тем, кто их подписывает. Если закрытый ключ, указанный вIdentityFile, загружен в агент, агент создаст подпись, и парольная фраза не потребуется. Вы можете даже указатьIdentityFileна соответствующий файл.pub; так делают, когда закрытый ключ хранится только в агенте или на аппаратном токене.
Одна ловушка в ~/.ssh/config может незаметно отменить это исправление. Большинство параметров принимают первое найденное значение, поэтому специфические блоки Host должны располагаться выше Host *. IdentityFile не следует этому правилу. В руководстве сказано: «В конфигурационных файлах можно указать несколько файлов идентификации; все эти идентификаторы будут перебираться последовательно». IdentityFile в разделе Host * добавляется к вашему значению для конкретного хоста, а не заменяет его, поэтому забытая глобальная строка возвращает лишнее предложение в каждое соединение.
Если вам нужна глобальная страховка, установите только этот флаг в конце файла:
Host *
IdentitiesOnly yesТогда для каждого хоста потребуется свой IdentityFile, что и является желаемым результатом. Назначение одного ключа на сервер позволяет в будущем отозвать доступ к одной машине, не перевыпуская всё остальное. Эту привычку стоит выработать как можно раньше: см. как управлять SSH-ключами для каждой машины.
Исправление 2: очистка или перезапуск агента
Если вы пока не можете отредактировать конфигурацию, очистите агент и загрузите только необходимые данные.
ssh-add -l # list what is loaded
ssh-add -d ~/.ssh/id_rsa # remove one key
ssh-add -D # remove every key
ssh-add ~/.ssh/id_ed25519_vps # load the one you needЕсли соединение заработало сразу после ssh-add -D, значит, проблема была в агенте. Рассматривайте это как тест, а не как исправление. Агент связки ключей (keyring agent) рабочего стола перезагружает ключи при следующем входе в систему, поэтому завтра проблема вернется. Строка IdentitiesOnly в ~/.ssh/config сохраняется после перезагрузки. Пустой агент — нет.
Вы также можете задать время жизни ключа, чтобы агент удалял его автоматически:
ssh-add -t 1800 ~/.ssh/id_ed25519_vpsКлюч будет удален через 1800 секунд после добавления. Перезапуск агента также помогает; способ зависит от того, как он был запущен. Процесс ssh-agent, который вы запустили вручную, останавливается командой ssh-agent -k. Если вы используете собственный пользовательский юнит systemd, перезапустите его с помощью systemctl --user restart <unit>. Агент связки ключей перезапускается вместе с сеансом рабочего стола.
Способ 3: разовая команда для сервера, к которому вы обращаетесь один раз
Для хоста, который вы не будете добавлять в свою конфигурацию, укажите те же параметры в командной строке:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10Использование -i само по себе — самая частая ошибка. Команда -i добавляет ключ в список идентификаторов. Она не удаляет ключи агента из этого списка, поэтому все остальные ключи по-прежнему предлагаются первыми, и соединение разрывается при достижении лимита. Запустите ssh -v -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10 без IdentitiesOnly, и вы увидите, что ключи агента предлагаются первыми. Для -i требуется -o IdentitiesOnly=yes рядом.
Чтобы полностью исключить агента из процесса для одного соединения:
ssh -o IdentityAgent=none -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10В этом случае ssh считывает закрытый ключ с диска и запрашивает парольную фразу, если она установлена.
Инструменты, построенные на базе ssh, принимают ту же опцию:
scp -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps report.tar.gz deploy@203.0.113.10:/tmp/
rsync -av -e "ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps" ./site/ deploy@203.0.113.10:/srv/site/
GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps" git clone git@example.com:team/repo.gitПочему ошибка возникает на втором этапе подключения
При использовании ForwardAgent yes сокет агента становится доступен на сервере, к которому вы подключаетесь. Команда ssh, запущенная на этом сервере, использует ваш локальный агент со всеми вашими ключами через перенаправленный сокет. Именно поэтому ошибка может возникнуть при переходе с jump host на целевой сервер, хотя первый этап прошел успешно. Выполните echo $SSH_AUTH_SOCK на промежуточной машине: наличие пути к сокету означает, что перенаправленный агент доступен, пустой вывод означает его отсутствие.
Перенаправление агента несет дополнительные риски. Любой пользователь с правами root на промежуточной машине может использовать ваш агент для аутентификации от вашего имени, пока ваша сессия открыта. ProxyJump позволяет избежать обеих проблем:
ssh -J deploy@jump.example.com deploy@10.0.0.5ProxyJump открывает соединение через jump host и выполняет аутентификацию на конечном сервере с вашей локальной машины, поэтому ваш локальный ~/.ssh/config применяется на каждом этапе, включая IdentitiesOnly. Отключение ForwardAgent — стандартный шаг при укреплении безопасности SSH на VPS.
Стоит ли увеличивать MaxAuthTries на сервере?
Обычно нет. Сначала проверьте текущее значение:
sudo sshd -T | grep -i maxauthtriessshd -T выводит эффективную конфигурацию, включая значения по умолчанию, поэтому команда показывает реальный параметр, даже если в sshd_config ничего не указано. Добавьте -C user=deploy,host=example.com,addr=203.0.113.10, если вы используете блоки Match, так как они вычисляются для каждого соединения и в противном случае пропускаются.
Увеличение лимита действительно работает в узком смысле: большее число попыток дает некорректно работающему клиенту больше возможностей:
MaxAuthTries 20Проверьте файл конфигурации и перезагрузите сервис. Во время выполнения этих действий держите открытой вторую сессию:
sudo sshd -t
sudo systemctl reload ssh # Debian and Ubuntu
sudo systemctl reload sshd # RHEL familyЕсли systemctl is-enabled ssh.socket сообщает enabled в Ubuntu 24.04, значит, sshd активируется через сокет: для каждого соединения запускается новый процесс, который заново считывает sshd_config, поэтому новые соединения подхватывают изменения автоматически.
Теперь оцените последствия этого изменения. Клиент предлагает ключи, которые сервер никогда не примет. Увеличение лимита заставляет сервер обрабатывать двадцать отклоненных предложений за соединение вместо шести — для каждого подключающегося клиента и для каждого переборщика паролей в интернете. Каждое предложение требует от сервера поиска в authorized_keys. Ваш собственный вход в систему останется медленным, так как нужный ключ по-прежнему будет последним в очереди. Добавьте тринадцатый ключ в свой агент, и вы вернетесь к исходной точке, снова нуждаясь в увеличении лимита.
Увеличивайте это значение только в том случае, если легитимному клиенту действительно необходимо предъявить несколько идентификаторов. Во всех остальных случаях исправляйте настройки клиента. Уменьшение этого параметра является разумным методом укрепления безопасности, как только каждый пользователь начинает входить в систему с настроенным ключом, поскольку меньшее число попыток дает злоумышленнику меньше шансов на подбор за одно соединение.
Почему fail2ban может заблокировать вас по этой причине
При стандартном уровне логирования sshd записывает каждый отклоненный открытый ключ:
Failed publickey for deploy from 203.0.113.10 port 51292 ssh2: ED25519 SHA256:AAAA...Одно подключение с использованием полного агента создает несколько таких строк для одного адреса в течение секунды или двух. Jail sshd в fail2ban подсчитывает строки с ошибками аутентификации sshd и блокирует исходный адрес, как только достигается значение maxretry в течение findtime. Эти временные интервалы по умолчанию малы, поэтому двух попыток подключения с неисправным агентом может быть достаточно, чтобы заблокировать ваш собственный адрес.
Симптомы при этом меняются, и именно это сбивает пользователей с толку. Вы перестаете видеть сообщение "Too many authentication failures" и не видите вообще ничего: соединение зависает и в конечном итоге прерывается по таймауту, так как межсетевой экран теперь отбрасывает ваши пакеты, а не отвечает на них. Таймаут там, где раньше приходило сообщение об ошибке, — это главный признак; разница между этими состояниями описана в отличие отказа в соединении SSH от таймаута соединения.
Через консоль вашего провайдера или с другого адреса проверьте состояние jail и снимите блокировку:
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.10Добавьте свой адрес в ignoreip в файле jail.local на время отладки клиента, а затем удалите его, когда закончите. Сам jail настраивается согласно руководству по fail2ban для Ubuntu 24.04.
Что сделать один раз, чтобы проблема не повторялась
Назначьте каждому серверу собственный блок Host в файле ~/.ssh/config, указав HostName, User, IdentityFile и IdentitiesOnly yes. После этого команда ssh vps станет короткой, она будет предлагать ровно один ключ и не вызовет срабатывание MaxAuthTries, независимо от того, насколько переполнен ваш агент. Это также позволит сохранить вывод ssh -v достаточно кратким, чтобы его можно было прочитать в день, когда произойдет какой-либо другой сбой.
FAQ
Как немедленно исправить ошибку "Too many authentication failures"?
Предлагайте только один ключ вместо всех имеющихся. Для немедленного подключения выполните ssh -o IdentitiesOnly=yes -i ~/.ssh/your_key user@host. Для постоянного решения добавьте блок в ~/.ssh/config с параметрами HostName, User, IdentityFile, указывающими на этот ключ, а также IdentitiesOnly yes и chmod 600 ~/.ssh/config. Проверьте результат с помощью ssh -v: вы должны увидеть одну строку Offering public key: для этого хоста.
Почему ssh -i всё равно предлагает другие мои ключи?
Потому что -i добавляет идентификатор в список, а не ограничивает его. Ключи, загруженные в ssh-agent, остаются в списке и по-прежнему предлагаются, часто перед вашим ключом, поэтому сервер может достичь лимита MaxAuthTries до того, как дойдет очередь до вашего ключа. -o IdentitiesOnly=yes — это опция, которая ограничивает ssh только указанными вами идентификаторами. Используйте -i и -o IdentitiesOnly=yes вместе или -o IdentityAgent=none, чтобы полностью игнорировать агент для этого конкретного подключения.
Стоит ли увеличивать MaxAuthTries на сервере, чтобы исправить это?
Нет, почти во всех случаях. Клиент отправляет ключи, которые сервер никогда не примет, а увеличение лимита лишь заставляет сервер обрабатывать больше отклоненных предложений для каждого подключения, для каждого клиента и для каждой попытки перебора паролей. Кроме того, проблема вернется, как только в вашем агенте появится еще один ключ. Проверьте текущее значение с помощью sudo sshd -T | grep -i maxauthtries, если вам интересно, а затем исправьте настройки клиента с помощью IdentitiesOnly.
Почему это началось на сервере, который отлично работал в прошлом месяце?
Ваш агент стал содержать больше ключей. AddKeysToAgent yes в ~/.ssh/config сохраняет каждый используемый вами ключ загруженным, а агенты связок ключей на десктопах загружают ключи при входе в систему автоматически. Как только количество загруженных ключей превышает MaxAuthTries сервера, любой сервер, чей ключ находится в конце списка предложений, начинает выдавать ошибку. Выполните ssh-add -l и сравните количество с лимитом на сервере.
Может ли это привести к блокировке моего IP-адреса через fail2ban?
Да. Каждый отклоненный ключ создает строку Failed publickey for ... в журнале сервера, поэтому одно подключение может сгенерировать несколько ошибок с вашего адреса за секунды, и тюрьма sshd в fail2ban заблокирует адрес, как только будет достигнуто значение maxretry в течение findtime. Признаком этого является то, что ошибка сменяется зависанием, а затем тайм-аутом, так как пакеты отбрасываются, а не отклоняются. Снимите блокировку через консоль с помощью sudo fail2ban-client set sshd unbanip <your address> и исправьте настройки клиента перед повторным подключением.