7

By default, my SSH client disallows the use of the diffie-hellman-group-exchange-sha256 key exchange algorithm. However, I need to access a server on 10.0.0.1 that requires the use of that algorithm.

This works fine at the command line:

$ ssh -o KexAlgorithms=diffie-hellman-group-exchange-sha256 [email protected]
Password:

However, it fails if I attempt to rely on the following addition at the end of /etc/ssh/ssh_config:

Host 10.0.0.1
    KexAlgorithms diffie-hellman-group-exchange-sha256

Here is the relevant output:

$ ssh -vvv [email protected]
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug3: kex names ok: [[email protected]]
...
debug1: /etc/ssh/ssh_config line 72: Applying options for 10.0.0.1
debug3: kex names ok: [diffie-hellman-group-exchange-sha256]
...
debug1: Connecting to 10.0.0.1 [10.0.0.1] port 22.
debug1: Connection established.
...
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug2: kex_parse_kexinit: [email protected]
...
debug2: kex_parse_kexinit: first_kex_follows 0 
debug2: kex_parse_kexinit: reserved 0 
debug2: kex_parse_kexinit: diffie-hellman-group-exchange-sha256
...
debug2: kex_parse_kexinit: first_kex_follows 0 
debug2: kex_parse_kexinit: reserved 0 
debug2: mac_setup: setup hmac-ripemd160
debug1: kex: server->client aes256-ctr hmac-ripemd160 none
debug2: mac_setup: setup hmac-ripemd160
debug1: kex: client->server aes256-ctr hmac-ripemd160 none
Unable to negotiate a key exchange method

What I find puzzling about this is that SSH is clearly reading the relevant line in /etc/ssh/ssh_config and seems to be happy with it. But then it tries to negotiate a key exchange with the server using [email protected] instead of diffie-hellman-group-exchange-sha256, which of course fails.

Why does it do that, and how can I rectify it?

1
  • That is weird. What version of openssh are you using (it should be also in verbose log)? What distro? Commented Apr 4, 2016 at 20:40

1 Answer 1

11

OpenSSH options might behave somehow strange on the first sight. But manual page for ssh_config documents it well:

For each parameter, the first obtained value will be used. The configuration files contain sections separated by “Host” specifications, and that section is only applied for hosts that match one of the patterns given in the specification. The matched host name is usually the one given on the command line (see the CanonicalizeHostname option for exceptions.)

You might rewrite your config like this to achieve what you need (the star * match should be last):

Host 10.0.0.1
    KexAlgorithms diffie-hellman-group-exchange-sha256
#[...]
Host *
    KexAlgorithms [email protected]

From my duplicate answer

And to explain why the commandline option works, also from the same manual page for ssh_config:

  1. command-line options
  2. user's configuration file (~/.ssh/config)
  3. system-wide configuration file (/etc/ssh/ssh_config)
1
  • Spot on, thanks! I'm sure this has happened to me before, and I should have RTFM more carefully. In a world where specific options are usually declared later and override more general options (e.g. CSS, and even the SSH CLI, user-config, system-wide config ordering at the end of your answer above), it's hard to remember that ssh_config files work in the opposite order! Commented Apr 5, 2016 at 9:34