Ruby's Net::SSH ограничен тремя попытками аутентификации, а клиент OpenSSH — нет

У меня действительно странная проблема: когда я подключаюсь к SSH-серверу (который имеет довольно стандартную конфигурацию по умолчанию, включая значение по умолчанию MaxAuthTries, равное 6) с использованием Net::SSH, соединение завершается неудачей после 3 попыток аутентификации с исключением disconnected: Too many authentication failures (2) (Net::SSH::Disconnect), в то время как клиент командной строки OpenSSH подключается нормально.

Проблема в том, что мой SSH-агент уже знает около 4 идентификаторов и предлагает их автоматически — досадно, прежде чем идентификатор, настроенный в файле конфигурации SSH-клиента для этого сервера — и поэтому клиенту OpenSSH всегда удается подключиться, а клиенту Net::SSH всегда не удается подключиться. Я могу подключиться к клиенту Net::SSH, отключив агент SSH.

Моя установка:

$ ssh-add -l
2048 SHA256:fMBMXD1mpUpM/vmVcjaXDvdIvPy4GCCdG5lc8ga1cLU /home/odeda/.ssh/id_rsa (RSA)
3072 SHA256:nfsiFP9APVl6oOK5htpldBmknVTDt1lCLvuHpTaaAao odeda@vesho (RSA)
2048 SHA256:t3+SY5Ru+tJ3r/HE7qIW4fnXswQ16btCiIadVGa2XPM odeda@jior (RSA)
1024 SHA256:EKBzRjDE6twnRLlIT3IHEfu08tVXCSK1henMHB+s+p8  (DSA)
$ grep example.com ~/.ssh/config -A1
Host *.example.com
   IdentityFile ~/.ssh/my_example_identity.pem

Бегущая сеть::SSH

$ bundle exec ruby -rnet/ssh -e 'Net::SSH.start("server.example.com","ubuntu",{
  host_name:"3.456.789.12",
  verify_host_key: :never,
  user_known_hosts_file: "/dev/null",
  non_interactive: true}) do |ssh|
    puts "Connected";
    puts ssh.exec! "echo Hello";
    ssh.loop(3);
  end'
~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/transport/session.rb:198:in `block in poll_message':
    disconnected: Too many authentication failures (2) (Net::SSH::Disconnect)
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/transport/session.rb:190:in `loop'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/transport/session.rb:190:in `poll_message'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/transport/session.rb:175:in `next_message'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/session.rb:103:in `block in next_message'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/session.rb:102:in `loop'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/session.rb:102:in `next_message'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/methods/publickey.rb:50:in `authenticate_with_alg'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/methods/publickey.rb:100:in `block in authenticate_with'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/methods/publickey.rb:97:in `each'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/methods/publickey.rb:97:in `authenticate_with'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/methods/publickey.rb:19:in `block in authenticate'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/key_manager.rb:132:in `block in each_identity'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/key_manager.rb:124:in `each'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/key_manager.rb:124:in `each_identity'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/methods/publickey.rb:18:in `authenticate'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/session.rb:88:in `block in authenticate'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/session.rb:72:in `each'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh/authentication/session.rb:72:in `authenticate'
        from ~/my-project/.vendor/bundle/ruby/3.0.0/gems/net-ssh-7.2.3/lib/net/ssh.rb:262:in `start'
        from -e:1:in `<main>'

Запуск клиента OpenSSH

$ ssh -oHostname=3.456.789.12 -l ubuntu server.example.com -- echo Hello
Hello

Запуск Net::SSH без агента SSH

$ SSH_AUTH_SOCK= bundle exec ruby -rnet/ssh -e 'Net::SSH.start("server.example.com","ubuntu",{
  host_name:"3.456.789.12",
  verify_host_key: :never,
  user_known_hosts_file: "/dev/null",
  non_interactive: true}) do |ssh|
    puts "Connected";
    puts ssh.exec! "echo Hello";
    ssh.loop(3);
  end'
Connected
Hello

Журналы сервера

Ситуация становится ещё более странной, если мы посмотрим на логи сервера:

Это клиентское соединение OpenSSH:

Jul 03 07:50:44 172-24-51-231.us-east-2.example.com sshd[42437]:
  AuthorizedKeysCommand /usr/share/ec2-instance-connect/eic_run_authorized_keys ubuntu SHA256:fMBMXD1mpUpM/vmVcjaXDvdIvPy4GCCdG5lc8ga1cLU failed, status 22
Jul 03 07:50:45 172-24-51-231.us-east-2.example.com sshd[42437]:
  AuthorizedKeysCommand /usr/share/ec2-instance-connect/eic_run_authorized_keys ubuntu SHA256:nfsiFP9APVl6oOK5htpldBmknVTDt1lCLvuHpTaaAao failed, status 22
Jul 03 07:50:45 172-24-51-231.us-east-2.example.com sshd[42437]:
  AuthorizedKeysCommand /usr/share/ec2-instance-connect/eic_run_authorized_keys ubuntu SHA256:t3+SY5Ru+tJ3r/HE7qIW4fnXswQ16btCiIadVGa2XPM failed, status 22
Jul 03 07:50:45 172-24-51-231.us-east-2.example.com sshd[42437]:
  userauth_pubkey: key type ssh-dss not in PubkeyAcceptedAlgorithms [preauth]
Jul 03 07:50:45 172-24-51-231.us-east-2.example.com sshd[42437]:
  Accepted publickey for ubuntu from 213.546.879.21 port 47034 ssh2: RSA SHA256:6Azd3HzkKpBLJ+zsolTOpksL4XX8aNdGWtprUwRvsoY
Jul 03 07:50:45 172-24-51-231.us-east-2.example.com sshd[42437]:
  pam_unix(sshd:session): session opened for user ubuntu(uid=1000) by (uid=0)

А это соединение Net::SSH:

Jul 03 07:50:18 172-24-51-231.us-east-2.example.com sshd[42392]:
  AuthorizedKeysCommand /usr/share/ec2-instance-connect/eic_run_authorized_keys ubuntu SHA256:fMBMXD1mpUpM/vmVcjaXDvdIvPy4GCCdG5lc8ga1cLU failed, status 22
Jul 03 07:50:18 172-24-51-231.us-east-2.example.com sshd[42392]:
  userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]
Jul 03 07:50:18 172-24-51-231.us-east-2.example.com sshd[42392]:
  AuthorizedKeysCommand /usr/share/ec2-instance-connect/eic_run_authorized_keys ubuntu SHA256:nfsiFP9APVl6oOK5htpldBmknVTDt1lCLvuHpTaaAao failed, status 22
Jul 03 07:50:19 172-24-51-231.us-east-2.example.com sshd[42392]:
  userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]
Jul 03 07:50:19 172-24-51-231.us-east-2.example.com sshd[42392]:
  AuthorizedKeysCommand /usr/share/ec2-instance-connect/eic_run_authorized_keys ubuntu SHA256:t3+SY5Ru+tJ3r/HE7qIW4fnXswQ16btCiIadVGa2XPM failed, status 22
Jul 03 07:50:19 172-24-51-231.us-east-2.example.com sshd[42392]:
  userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]
Jul 03 07:50:19 172-24-51-231.us-east-2.example.com sshd[42392]:
  error: maximum authentication attempts exceeded for ubuntu from 213.546.879.21 port 56414 ssh2 [preauth]
Jul 03 07:50:19 172-24-51-231.us-east-2.example.com sshd[42392]:
  Disconnecting authenticating user ubuntu 213.546.879.21 port 56414: Too many authentication failures [preauth]

Итак, мы видим, что четвертый ключ, который у меня есть в моем агенте (это ключ DSA, который больше не поддерживается по умолчанию на современных серверах), отправляется клиентом OpenSSH и отклоняется из-за PubkeyAcceptedAlgorithms, а затем пятый открытый ключ (из конфигурационный файл) принимается. В случае клиента Net::SSH 3 ключа RSA от агента — те же ключи, что и раньше — отклоняются PubkeyAcceptedAlgorithms, а четвертый не отправляется — вместо этого мы получаем error: maximum authentication attempts exceeded всего после 3 попыток.

Я пытался найти параметр конфигурации в Net::SSH (или конфигурации клиента OpenSSH), который, возможно, управляет какой-то функцией (о существовании которой я не знаю), где клиент сообщает серверу, сколько попыток аутентификации разрешить - но, конечно Я не смог найти такого, потому что это не имеет смысла.

Я, конечно, пытаюсь установить для параметра Net::SSH number_of_password_prompts значение, большее, чем значение по умолчанию, равное 3, и, конечно, это ничего не дает, потому что этот параметр предназначен для запроса пароля, чего мы вообще не делаем.

Любая идея будет оценена по достоинству, ТИА!

Выбор ключа, вероятно, различается в разных реализациях. Таким образом, если возможно, часто гораздо лучше указать, какие ключи использовать. С помощью конфигурации ssh (которая также частично считывается в net/ssh) вы можете использовать опцию IdentitiesOnly, чтобы указать клиенту использовать только один указанный ключ. Количество возможных попыток аутентификации полностью контролируется сервером (в противном случае это было бы бесполезно).

Holger Just 05.07.2024 13:09

Как видно из фрагментов журналов, обе реализации обслуживают одни и те же ключи в одном и том же порядке. Действительно, использование IdentitiesOnly в конфигурации решает проблему указания ключа в файле конфигурации, но не решает все проблемы, например, когда мне действительно нужен ключ, который должен быть предоставлен агентом.

Guss 06.07.2024 21:31
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
0
2
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема заключается в ошибке в Net::SSH - проблема 886 : по какой-то причине Net::SSH не может определить, какой алгоритм ключа использовать для ключей RSA, и по умолчанию настроен на попытку обоих rsa-sha2-256 ( вариант SHA2) и ssh-rsa (SHA-1, который теперь отклонен конфигурациями SSH-сервера по умолчанию), один за другим.

В результате Net::SSH попытается аутентифицировать каждый открытый ключ RSA дважды, исчерпав стандартные 6 попыток после всего лишь 3 ключей RSA.

Текущий обходной путь — использовать (недокументированный) Net::SSH#start параметр pubkey_algorithms и установить для него значение ["rsa-sha2-256"] (или какое-либо другое подмножество списка алгоритмов по умолчанию, если вы намерены поддерживать аутентификацию на основе сертификатов) — это предотвратит использование Net::SSH использование ключей RSA с подписями SHA-1, взлом этих типов ключей, если вы планируете их использовать.

Другие вопросы по теме