Re: Fixing exchange of host keys in the SSH key exchange
"denis bider \(Bitvise\)" <[email protected]>
| Newsgroups | gmane.ietf.secsh |
|---|---|
| Message-ID | <589D55C2CF5942E9910482788CBDB445@Khan> |
Mouse: > > if the client has to communicate one or more fingerprints > > of the server's host key(s) before KEXINIT, this prevents > > the situation where the client will present the user with > > a host key verification dialog, and the user will just > > click through it. > How? A server that enforces this policy (not all would) will reject the connection outright if the client fails to send at least one correct Expect-Key. The client must therefore have it. > Yes...but if the server does that, it also becomes > impossible for the client to do the now-usual "just > accept the key on the first connection" thing. Preventing this, and requiring a stringent host key setup, is the central feature of this mechanism. It's an option that some of our users would like. > You have to provide the host key to the client by > some out-of-band means. Yes. The idea is to make sure this actually happens. > Another possible benefit would be automatic defeat of > host-key-gathering bots. Interesting. Yes, that would be a side effect for hosts that configure this policy. > I strongly suggest that it instead be something like > Expect-Key: <hash-algorithm-name> <base64-hash> Agreed. Yes, definitely - for the reasons you described. > I can't help wondering if perhaps this is time to use > the uint32 in SSH_MSG_KEXINIT that is "0 (reserved for > future extension)", Unfortunately, there exist implementations that disconnect, or generate an invalid key exchange hash, if that value is not zero. When I last checked in 2015, libssh was one. > Also, 4253 says the server MAY send text before its > version number, but is silent on the question of > whether the client also may. Hmm, keen observation. Of course, even if it did say otherwise, there could exist server implementations that do not handle this properly. It seems that testing would be in order. > It seems more elegant to me for the server to signal > support with something like > Accept-Expect-Key: yes Or maybe the server sends something like "Expect-Key: support|require". The format can vary between client and server. That might still not work if there are clients that violate 4253, though. Another way that would work for sure would be: - The server includes "expect-key" among its host key algorithms. The client never includes this algorithm. Instead it just sends signature algorithms that correspond to keys it knows for this server. - If client sees "expect-key" among server's host key algorithms, then immediately after its own KEXINIT, it sends a newly defined message, SSH_MSG_EXPECT_KEYS, which contains fingerprints of host keys trusted for this server. The server can now act according to its policy, based on whether it receives SSH_MSG_EXPECT_KEYS, and what it finds in it. This approach has downsides compared to Expect-Key before version string: - If client is required to send Expect-Key before version string, server can just be quiet and send nothing. The server can avoid being accurately fingerprinted. The server can't do this in the method that uses KEXINIT. - The method that requires EXPECT_KEYS after KEXINIT complicates guessed key exchange, since the client does not know upfront if the server supports it. Generally, if the client could send fingerprints without the server signaling anything, this would be superior. It would allow the server to not let itself be fingerprinted as accurately. (The OS can still be fingerprinted based on properties of its TCP stack, even if the SSH server application sends nothing.) denis ----- Original Message ----- From: Mouse Sent: Thursday, March 23, 2017 06:24 To: [email protected] Subject: Re: Fixing exchange of host keys in the SSH key exchange > Iâ??m wondering if anyone - OpenSSH and PuTTY in particular? - would > be interested in implementing an extension to the way the initial SSH > handshake is done, in a way that would allow the SSH server to > require the client to communicate one or more fingerprints of the > serverâ??s host key(s), before exchanging KEXINIT. > This would have multiple benefits: > (1) Security benefit: [...] if the client has to communicate one or > more fingerprints of the serverâ??s host key(s) before KEXINIT, this > prevents the situation where the client will present the user with a > host key verification dialog, and the user will just click through > it. How? As far as I can see, in order to do that, you have to move that decision from the client to the server. This carries its own prices. > (2) Security benefit: on servers that enable this policy, and prevent > connections where the client does not communicate a correct server > host key, drive-by password guessing becomes largely impossible, > since unknown attackers do not know the serverâ??s host key. Yes...but if the server does that, it also becomes impossible for the client to do the now-usual "just accept the key on the first connection" thing. You have to provide the host key to the client by some out-of-band means. This of course could be an upside or a downside, depending. > (3) Practical benefit: the server [...] can avoid the situation where > introduction of a new host key, with no change to previous host keys, > would break connections for existing clients that prefer to negotiate > the algorithm of the new host key, but do not actually trust it. True. Another possible benefit would be automatic defeat of host-key-gathering bots. My logs are full of clients that connect, get my host key, and then disconnect. A few of them are honest about what they're doing ("SSH-2.0-ZGrab ZGrab SSH Survey", or "SSH-2.0-OpenSSH-keyscan"); others are...less so ("SSH-2.0-PUTTY"). Most just report a library version (eg, "SSH-2.0-sshlib-0.1"). Or, rather, clients used to be doing that; I now disconnect such clients before giving them any host keys (I prefer to not talk about the details of what I've configured my server to require to get it to talk to a specific client). > Implementation: > We have room for textual data that can be sent before the SSH version > string. To implement this, the client would send one or more lines > such as: > Expect-Key: <base64-sha256-fingerprint>\r\n I strongly suggest that it instead be something like Expect-Key: <hash-algorithm-name> <base64-hash> so that when SHA256 finally shows weaknesses, it does not become a major headache to switch hash algorithms. If the server thinks the hash algorithm is too weak, or doesn't recognize it at all, it can ignore that line. The client can of course send hashes of the same key under multiple algorithms, if it wants. I can't help wondering if perhaps this is time to use the uint32 in SSH_MSG_KEXINIT that is "0 (reserved for future extension)", though, rather than shoehorning it into something that's currently outside the protocol (almost) entirely. I see no guidance in 4253 for implementation behaviour if that value isn't 0 - but see below. Also, 4253 says the server MAY send text before its version number, but is silent on the question of whether the client also may. (I suspect most server implementations share that code with their corresponding client implementations, though.) > However, we could also change the protocol to include the Expect-Key > lines in the SSH key exchange hash. In this case, the client would > signal support by sending at least one Expect-Key line, and the > server would signal support in another way. One way would be to > include the name "expect-key" among its host key algorithms in > KEXINIT. The server has at least as much room to send text before its version string as the client does. It seems more elegant to me for the server to signal support with something like Accept-Expect-Key: yes there - or perhaps to use that RFU uint32 in SSH_MSG_KEXINIT if the client signals support (which would avoid the issue of an unaware client printing that and thus confusing the user and possibly breaking scripted uses, and also restrict nonzero values to implementations that have already advertised awareness of this extension). /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML [email protected] / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B