Page MenuHomePhabricator

HostKeyAlgorithms: Check if there is an entry in known_hosts and prefer that
Open, NormalPublic

Description

Before we negotiate a HostKey with the server, libssh should check the known_hosts file if there is an entry and prefer the key in the hosts file. This will avoid that keys in the hosts file are not accepted if newer host keys get supported.

Event Timeline

asn created this task.Sep 21 2018, 4:22 PM
asn triaged this task as Normal priority.
Jakuje added a subscriber: Jakuje.Oct 18 2018, 11:57 AM

This is actually implemented by the function ssh_known_hosts_get_algorithms(), but behaves a bit differently than a similar function in OpenSSH client:

  • This function limits the offered list to only key types found in known_hosts. The OpenSSH counterpart takes the default and puts the known in front and the supported to the end of the list.
  • This function does not consult the global known hosts file if I am right
  • In my local setup, I noticed that the libssh selects only the ed25519 key, while openssh finds also the ecdsa, which I have stored in my known hosts.

From ./examples/ssh-client -vvvvv localhost:

[2018/10/18 11:46:38.912159, 3] ssh_client_select_hostkeys:  Changing host key method to "ssh-ed25519"
[...]
[2018/10/18 11:46:38.912229, 4] ssh_list_kex:  server host key algo: ssh-ed25519

From OpenSSH 7.8 ssh -vvv localhost:

debug3: hostkeys_foreach: reading file "/home/jjelen/.ssh/known_hosts"
debug3: record_hostkey: found key type ED25519 in file /home/jjelen/.ssh/known_hosts:3
debug3: record_hostkey: found key type ECDSA in file /home/jjelen/.ssh/known_hosts:8
debug3: load_hostkeys: loaded 2 keys from localhost
debug3: order_hostkeyalgs: prefer hostkeyalgs: ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519
[...]
debug2: host key algorithms: ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256,ssh-rsa

Do you happen to remember what was the exact use case that was broken by this? I will indeed work on the above issues, but I would like not to miss the original issue.

asn added a comment.Oct 18 2018, 1:23 PM

a) We what the same what OpenSSH does. I think the function ssh_known_hosts_get_algorithms() just gets the one from known_hosts but dosn't deal with the supported defaults.
b) The global hosts file is not supported in the new known_hosts API I totally forgot to impelment that. See T107

The following changes should settle the behavior to more sane that follows openssh and does not cause problems if there are more host keys stored in the known_hosts files:

https://gitlab.com/jjelen/libssh-mirror/tree/prefer-known-keytypes

It also updates tests to make sure this use case is validated.

I am still running the CI and memcheck, but this should resolve this issue.