Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSHKit Fails in OTP-23 #156

Closed
CharlesOkwuagwu opened this issue May 16, 2020 · 10 comments
Closed

SSHKit Fails in OTP-23 #156

CharlesOkwuagwu opened this issue May 16, 2020 · 10 comments

Comments

@CharlesOkwuagwu
Copy link

Environment

  • SSHKit.ex version (mix deps): {:sshkit, "~> 0.3"}

  • Elixir & Erlang/OTP version (elixir -v):
    Erlang/OTP 23 [erts-11.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]
    Elixir 1.10.3 (compiled with Erlang/OTP 21)

  • Operating system (local): Windows 10

  • Operating system (remote): SUN

  • SSH version (remote, ssh -V): 'SSH-2.0-Sun_SSH_1.1.5'

Expected Behavior

Works in OTP 22.3 and earlier.

Actual Behavior

Fails in OTP-23

iex> [2020-05-16 18:55:44.285] Erlang SSH :client 4.10 (OpenSSL 1.0.2d 9 Jul 2015).
Server: 'SSH-2.0-Sun_SSH_1.1.5'
Disconnects with code = 3 [RFC4253 11.1]: Key exchange failed
State = {kexinit,client,init}
Module = ssh_transport, Line = 393.
Details:
  Kexinit failed in client: error:{badmatch,{false,"kex"}}


iex> {:error, 'Key exchange failed'}
iex> [2020-05-16 18:55:44.686] Erlang SSH :client 4.10 (OpenSSL 1.0.2d 9 Jul 2015).
Server: 'SSH-2.0-Sun_SSH_1.1.5'
Disconnects with code = 3 [RFC4253 11.1]: Key exchange failed
State = {kexinit,client,init}
Module = ssh_transport, Line = 393.
Details:
  Kexinit failed in client: error:{badmatch,{false,"kex"}}

@pmeinhardt
Copy link
Contributor

pmeinhardt commented May 18, 2020

Hi @CharlesOkwuagwu, thanks for reporting this. 💚

Judging from the error output, it looks like this is an issue with OTP, not SSHKit.

I did a quick investigation, looking at recent changes in the ssh_transport module, more specifically key exchange ("kex"). A few key exchange algorithms have been disabled (by default) in the OTP 23 release because they're considered unsecure:

  1. https://github.com/erlang/otp/blame/OTP-23.0/lib/ssh/src/ssh_transport.erl#L149-L155
  2. https://github.com/erlang/otp/blob/OTP-23.0/lib/ssh/src/ssh_transport.erl#L2113-L2114
  3. erlang/otp@76ae185

Maybe your server's using one of those?

Apparently, as a means of validating this hypothesis, you can re-enable them by passing a modify_algorithms option (see the third link) to the client. You'd probably want to update your server SSH version/config though, if it's still using one of the phased-out algos.

This is just a hunch from a few minutes of research though. I hope it can help you figure out more of what's going on.

Happy to hear back from you. 🙂

@CharlesOkwuagwu
Copy link
Author

CharlesOkwuagwu commented May 18, 2020

@pmeinhardt Thanks for your response.

Please can you show me the settings needed to ensure SSH in OTP-23 works with all OTP-22 algorithms enabled?

i'm getting this error now, after following the third link you suggested above:

iex> {:error, {:eoptions, {{:modify_algorithms, :kex}, 'Bad value for this key'}}}
iex> [2020-05-18 11:22:35.939] Erlang SSH :client 4.10 (OpenSSL 1.0.2d 9 Jul 2015).
Server: 'SSH-2.0-Sun_SSH_1.1.5'
Disconnects with code = 3 [RFC4253 11.1]: Key exchange failed
State = {kexinit,client,init}
Module = ssh_transport, Line = 393.
Details:
  Kexinit failed in client: error:{badmatch,{false,"kex"}}

after applying this:

opt = [
      user_interaction: false,
      silently_accept_hosts: true,
      user: String.to_charlist(@server_username),
      password: String.to_charlist(@server_password),
      modify_algorithms: [{:append, [{:kex, ['diffie-hellman-group1-sha1']}]}]
    ]

@CharlesOkwuagwu
Copy link
Author

You'd probably want to update your server SSH version/config though, if it's still using one of the phased-out algos.

That's quite difficult to do, I don't control the servers / environments I am connecting to.
This new security update for SSH in OTP-23 should have been an opt-in feature.

@pmeinhardt
Copy link
Contributor

pmeinhardt commented May 18, 2020

That's quite difficult to do, I don't control the servers / environments I am connecting to.

Like I wrote before, I am only making a guess here that it is related to the changes in the algos enabled by default. I can't be 100% sure, but it seems like a reasonable place to start.

If you don't control the server yourself, you may want to reach out to someone who does, when you've confirmed the algorithms are really the problem.

As a last resort, if you're okay with the potential security risk for some reason, maybe you don't need to upgrade to OTP 23 right now, but can instead stick with 22.3 for a little bit longer to understand this problem better.

This new security update for SSH in OTP-23 should have been an opt-in feature.

I can somewhat understand your frustration. On the other hand there are a few things you might want to consider.

First off, it's a major version release, so you cannot expect everything to work exactly the same as before. I know for a fact that the people working on OTP are quite careful about introducing breaking changes. At the same time, secure defaults are more important than backwards compatibility. Finally, the SSHKit issues aren't really the place to complain about whether or not this update to OTP should have been opt-in or not. 🙂✌️

opt = [
      user_interaction: false,
      silently_accept_hosts: true,
      user: String.to_charlist(@server_username),
      password: String.to_charlist(@server_password),
      modify_algorithms: [{:append, [{:kex, ['diffie-hellman-group1-sha1']}]}]
    ]

The way you're passing the modify_algorithms option above looks alright at first glance. (http://erlang.org/doc/man/ssh.html#type-modify_algorithms_common_option)

Maybe someone on the Elixir or OTP message boards can provide further assistance. 🤔

@jfis
Copy link

jfis commented May 23, 2020

try as atom
modify_algorithms: [{:append, [{:kex, [:"diffie-hellman-group1-sha1"]}]}]
or more elixir-y
modify_algorithms: [append: [kex: [:"diffie-hellman-group1-sha1"]]]

@CharlesOkwuagwu
Copy link
Author

@jfis Thanks.

I get this now:

[2020-05-24 02:18:09.750] Erlang SSH :client 4.10 (OpenSSL 1.0.2d 9 Jul 2015).
Server: 'SSH-2.0-Sun_SSH_1.1.5'
Disconnects with code = 3 [RFC4253 11.1]: Key exchange failed
State = {kexinit,client,init}
Module = ssh_transport, Line = 393.
Details:
  Kexinit failed in client: error:{badmatch,{false,"kex"}}

@jfis
Copy link

jfis commented May 24, 2020

that is the same error as when there's no :modify_algorithms in options, so double check that it truly did get passed to the connect. also double check for typos.

you might need a different kex than diffie-hellman-group1-sha1.
you'll have to figure out what it used to use when connecting to the server before 23.
use :ssh.default_algorithms() to see what's available on your current erlang.
also run that on your previous erlang, if you have it available. the difference may give a clue on which has gone missing.
then you need to find out what the server supports.
use verbose mode with manual ssh in your terminal to view the list of available kex on the server (ssh -vv ...) (2 v's for debug level 2)

you'll see something like:
debug2: peer server KEXINIT proposal
debug2: KEX algorithms: diffie-hellman-group1-sha1,diffie-hellman-group14-sha1

one of the listed must be what it used to use

(i dont know how well this translates to Windows 10)
(also, my iex says
Erlang SSH :client 4.10 (OpenSSL 1.1.1g 21 Apr 2020))

@CharlesOkwuagwu
Copy link
Author

I Was doing something wrong ... this totally works

def ssh_test do
    SSHKit.SSH.connect('#{@server_ip}',
      port: @server_ssh_port,
      user: '#{@server_username}',
      password: '#{@server_password}',
      modify_algorithms: [prepend: [kex: [:"diffie-hellman-group1-sha1"]]]
    )
  end

@pmeinhardt
Copy link
Contributor

Hey @CharlesOkwuagwu, I am so happy you figured it out. 🙌
Thanks a lot for posting your solution as well. 💪

So the key was to :prepend rather than :append?

@CharlesOkwuagwu
Copy link
Author

CharlesOkwuagwu commented May 25, 2020

So the key was to :prepend rather than :append?

Either work.

I was totally not passing the modify_algorithms key to SSHKit ...

opt = [
      user_interaction: false,
      silently_accept_hosts: true,
      user: String.to_charlist(@server_username),
      password: String.to_charlist(@server_password),
      modify_algorithms: [prepend: [kex: [:"diffie-hellman-group1-sha1"]]]
    ]

    r= :ssh.connect(String.to_charlist(@server_ip), @server_ssh_port, opt)

    IO.inspect(r, @format)

    {:ok, conn} =
      SSHKit.SSH.connect('#{@server_ip}',
        port: @server_ssh_port,
        user: '#{@server_username}',
        password: '#{@server_password}',
       # was mssing our the line below!!!
        modify_algorithms: [prepend: [kex: [:"diffie-hellman-group1-sha1"]]]
      )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants