10 comments

[ 3.4 ms ] story [ 31.8 ms ] thread
You also need a way to revoke old and/or compromised keys (so maybe also have an option to send keys that should be removed from the known_hosts file) otherwise you can't use this to rotate to new keys: sure, clients will automatically know and trust the new key, but that's useless if they still trust the old/compromised key too.
No, it appears that they are automatically replaced. http://bxr.su/o/usr.bin/ssh/hostfile.c#hostfile_replace_entr...

I'm not sure if it's a good thing, though -- it kinda sounds like a race condition -- whether the good guys or the bad guys will be first to replace the keys. :-)

That doesn't make any sense.

Say the server is using key A, but you want to plan for the future, so you have it also offer keys B and C. But it's still using A. So clients connect, in addition to having A, they get B and C. Great, future-proofed.

Now A gets compromised. Or A is using a crappy algorithm that is easily broken. Mr. SysAdmin is happy since he's planned for this eventuality. Stop using key A, use B instead. Clients have no issues wondering if they should trust the new key (B) since they already have it in their known_hosts.

Attacker comes along. Somehow A is compromised (either that's why the admin moved to B, or the crappy algo made it easy for the attacker to get the key). Attacker uses key A. Clients already trust A. Connection compromised.

What I'm saying is that in this situation it would have been good if, when the server started using key B, it also had some way to send messages to client connections saying "delete A from your known_hosts" that way if someone does start using A again, it's flagged.

Yes, it's still a race condition. But much better than the alternative.

Well, I didn't look through every line of the patch, but my understanding is that once the server stops using key A, it'll automatically be revoked / deleted from the client. Why else would http://bxr.su/o/usr.bin/ssh/hostfile.c#hostfile_replace_entr... be calling hostkeys_foreach() function with the pointer to host_delete() as the parameter?

E.g. revoking the key is as easy for the server as simply no longer using it. Which is why I'm saying it's a race condition -- if the attacker comes first, it would appear that they're free to revoke every single valid key for the server, replacing all such keys with whatever keys they wish.

Unused private key material shouldn't just by lying around. It's better to generate it just in time, when migrating key material is needed, and use an authoritative method to distribute known hosts (Krb5, cfg mgmt). OpenSSH supports sahfp DNS records (RFC4255), but DNS often lacks end-to-end integrity. So that leaves cfg mgmt and directories like LDAP & Krb5. (PS: if a box is compromised, don't just change host keys, rebuild it (patched) on a private network... It's too expensive and nearly impossible to prove a compromised box isn't still rooted, undoing bandaids and creating more work. (Find out cause if possible and rachet up defenses too.) The avg rootkits these days are crazy modular and far more devious than even 5 years ago.)

If this adds an ability to add N keys, this could be useful for core boxes that you don't want to introduce cyclic dependencies upon other infrastructure (the cycles aren't always obvious).

Be aware that some boxes and services shouldn't depend on "ubiquitous" services like DHCP or DNS being alive, if you want your on-prem / datacenter network gear, BGP, security system, etc. to survive interruptions.

Yes, ssh will remove keys that are not in the set that the server sends it. I've updated the blog post to mention this :)
That all makes a lot more sense now.
Will this all work by default?

E.g. other than simply being enabled by default (looks like it is), does OpenSSH automatically generate new host keys every time the new host key algorithm is started being supported? If it's system-dependent, e.g. rc(8)-based, http://mdoc.su/o/rc.8, how do most systems behave here?

Also, looking at the code, http://bxr.su/o/usr.bin/ssh/clientloop.c#client_input_hostke... will be calling http://bxr.su/o/usr.bin/ssh/hostfile.c#hostfile_replace_entr..., doesn't it mean that it's quite easy for the attacker who can actually do MitM and has indeed obtained the keys, to effectively cause a race condition, and deprecate the non-exploited spare keys? Together with the existing key that has been compromised? In such a scenario, it sounds like the attacker could effectively replace the key they compromised (plus all the spare keys) with their own brand new key, which will then make the ssh client generate warnings should it try to connect to an sshd without MitM attack going on.

I'm kinda confused here -- is the possibility of such trick-playing not considered a big deal?

I think the point here is changing from older RSA and DSA keys to newer ECDSA and ED25519 keys.

Most of the issue you're bringing up a prerequisite of obtaining and/or compromising the the target host's private keys, at which point most of the other attacks have little value - what's the point of MitM-ing a host if the SSH host keys only apply to that specific host, and you already have root on it?

The only issue would be if you could take advantage of a flaw in the ssh client and put arbitrary content in their ~/.ssh/known_hosts file, but I'm betting this would be pretty easy to mitigate.

I'm not sure is this really is much of an improvement. SSH keys (as opposed to ssh certs) have lots of trust issues, the main one being no way to properly revoke a key, or for a key to expire.

I'm not sure adding this to the ssh server is better than just telling people to use DNS RR-records (or use ssh certs, which narrows the problem to one of distributing the ssh CA cert).

http://www.openssh.com/txt/rfc4255.txt

http://www.iana.org/assignments/dns-sshfp-rr-parameters/dns-...

I've yet to get around to managing my ssh keys via "ssh ca/ssh certs" (certs are relatively new -- at least when still running some Debian Old-stable LTS boxes...). Looks like this might help:

https://github.com/cloudtools/ssh-ca

As far as I can tell, there is no support to store SSH (CA) Certs in DNS -- which is a shame. Would've made sense to just have a SRV-record for the (sub)domain?