This question already has an answer here:

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 that requires the use of that algorithm.

This works fine at the command line:

$ ssh -o KexAlgorithms=diffie-hellman-group-exchange-sha256 user@

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

    KexAlgorithms diffie-hellman-group-exchange-sha256

Here is the relevant output:

$ ssh -vvv user@
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug3: kex names ok: [curve25519-sha256@libssh.org]
debug1: /etc/ssh/ssh_config line 72: Applying options for
debug3: kex names ok: [diffie-hellman-group-exchange-sha256]
debug1: Connecting to [] port 22.
debug1: Connection established.
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug2: kex_parse_kexinit: curve25519-sha256@libssh.org
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 curve25519-sha256@libssh.org instead of diffie-hellman-group-exchange-sha256, which of course fails.

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

marked as duplicate by Jakuje, roaima, jimmij, Gilles ssh Apr 4 '16 at 22:01

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • That is weird. What version of openssh are you using (it should be also in verbose log)? What distro? – Jakuje Apr 4 '16 at 20:40

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):

    KexAlgorithms diffie-hellman-group-exchange-sha256
Host *
    KexAlgorithms curve25519-sha256@libssh.org

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)
  • 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! – sampablokuper Apr 5 '16 at 9:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.