Hacker News new | ask | show | jobs
by tialaramex 1860 days ago
> The message wouldn't show up unless the server offers this new key type, would it?

Good point. I think you can probably guard this so that neither clients nor servers ever see the new SSH authentication message if they aren't onboard with this plan, but it's a bit complicated.

The problem is on your first flight you don't know the ID, so your SSH_MSG_USERAUTH_REQUEST will definitely fail. That's OK, the protocol expects this, it's how lots of things already work. The server sends SSH_MSG_USERAUTH_FAILURE but unlike REQUEST, the FAILURE message isn't extensible, the only way forward it imagines is to tell you other methods that might work, and your method might work, you just don't know the ID.

So you're going to need to have this failure step function as a signal to inject the new message, a hypothetical SSH_MSG_USERAUTH_SECURITYKEY_ID_LIST or something, with one or more IDs for which the server claims to know a corresponding public key, the same way protocols like WebAuthn work.

The more I write about this, the more I'm convinced somebody could have actually built it, but since the OpenSSH people did the work to bring FIDO to SSH and I did not, I don't really have the right to criticise. For all I know they spent six months trying this approach and ended up in a cul-de-sac.

> It's not the job of the SSH server to write to authorized_keys, so it's not the job of the SSH server to write these blobs either.

Good point, you could probably build something where the ID lives in (the new type of) SSH public keys or some equivalent file, so it gets concatenated to authorized_keys and then the server just needs to know to dredge the ID out from there and send it to a client in the new message.

1 comments

> The more I write about this, the more I'm convinced somebody could have actually built it, but since the OpenSSH people did the work to bring FIDO to SSH and I did not, I don't really have the right to criticise. For all I know they spent six months trying this approach and ended up in a cul-de-sac.

These were my thoughts exactly when I first read about the new feature in 8.2.

Would be really cool to learn about the internal reasoning for the solution that they ended up with.

> Good point, you could probably build something where the ID lives in (the new type of) SSH public keys or some equivalent file, so it gets concatenated to authorized_keys and then the server just needs to know to dredge the ID out from there and send it to a client in the new message.

That would open you up to being fingerprinted by the server, right? WebAuthN combats this by scoping the ID to the RP domain name, but SSH servers aren't guaranteed to have a (canonical) name.

> That would open you up to being fingerprinted by the server, right?

I actually don't think it makes this worse, if the client is coded carefully. At least, it's not clearly worse.

SSH public key authentication has a back-and-forth, the client proposes public keys for which it claims it knows the corresponding private key, and the server can choose to say "Yeah, that'll work, prove you know that one".

Filippo's fingerprinting trick (whoami.filippo.io) takes all the GitHub public keys and considers whether your SSH client claimed it can authenticate as them. But I believe it doesn't actually test that your claim was true, so it would actually be fooled if your client says it can authenticate as somebody else...

So this would be a bit different from that, but again a carefully configured client just won't admit to knowing how to do Security Key authentication to talk to some server it has never heard of, and the server needs to make a reasonable stab at guessing your ID, I think OpenSSH isn't going to allow a remote server to say "Here are 100MB of FIDO IDs, are any of these yours?"

The lack of scope restriction isn't ideal, but it feels like a parallel to the way TOFU was more or less enough for SSH in practice whereas the Web really needed the Web PKI. Normal people can probably list the SSH servers they connect to, but you connect to huge numbers of HTTPS servers in normal web use.