This article got published in 2600 Volume Thirty-Five Number One! / Spring 2018
The Secure Shell protocol was invented in 1995 to overcome the lack of strong, encrypted authentication of remote tools like telnet, rlogin, rsh and similar protocols. Security improvements have been implemented in version 2, which was released in 2006. More detailed information on SSH can be found in the RFC 4251 – RFC 4256 (and a couple of other RFCs, but these are the basic ones) and a web search.
This article will focus on the SSH-2 protocol, which basically utilizes a Diffie-Hellman key exchange and public key cryptography to authenticate the remote computer. The user can authenticate either via passwords, or as well by a public key authentication.
In general SSH keys are known to be more secure than a password authentication, since when using SSH keys no password is being transmitted over the wire at any point in time. It is important to not though, that the authentication method has no influence on the security of the connection itself.
To authenticate with a private key, the client will first sen the user ID to the server, which will then refer to the corresponding authorized_keys file (the location and the file can be set in the sshd configuration file, so it’s not necessarily authorized_keys), utilizes the contained public key to encrypt a random number and sens it back to the client. The client will be able to de-crypt the value with the correct private key and calculate a hash value of the number and sends this back to the server. The server can now compare the hash values and if these match, the user is authenticated.
Private keys can and should in any case be protected with a passphrase. A passphrase is nothing different than a password, hopefully longer.
Since it is of course more secure, not transmitting passwords over the wire at all and if protected by a decent passphrase the private key might be better secured as well, there are still a lot of challenges that SSH keys cause in enterprise environments. I’m not necessarily trying to come up with solutions for these challenges, but want to try to help admins face these and help them to come up with decent processes and workflows. Since I have seen quite a few enterprises using SSH key authentication, I can tell there are many misunderstandings and sometimes even thoughts, that haven’t popped up before, when talking to administrators.
I want to stress again, that the SSH connection initiated with SSH keys is NOT any more cryptographically secure, than the one with password authentication. While this seems to be a no-brainer, I’ve met too many IT-people that really think it is. It is just another way to authenticate, which for sure has advantages. So in any conversation, I try to find out the reasons, why people insist on using SSH keys to authenticate.
Now let’s dig a little deeper into the challenges of SSH keys in an enterprise environment. While when using SSH keys yourself, to log on remotely to your box at home, to one in the cloud, to any device supporting it, it is your responsibility to know, which key you use for which account. Maybe you just use one single key for every device, protect the private key with a strong passphrase and keep it in a secure place. But what happens in an enterprise environment? There are several, sometimes hundreds or even thousands of users with one or more key pair. One challenge is the private key security. As you already knew, or read further above in this article, the server just receives a hash value of an encrypted random number it sent to the client. The server does not know about the private key security. Is it protected with a passphrase? There is no control on the server, if the private key is protected and if, if the passphrase is strong enough. It’s completely up to the user. And users somethings tend to be lazy. So they might use a passphrase, or not. We cannot put any technical mechanism in place, to enforce a passphrase on a private key.
A private key is a file, and in contrast to a password has to be stored somewhere. With passwords it’s nowadays quite commonly known that you shouldn’t write those on PostIts and stick those to your screen or place them under the keyboard. But where to store your private key? In combination with the fact, that there is no way to enforce passphrase protection for the private key in common SSH implementations, this can become a security risk.
Especially since the public key authentication is not bound to a named user account. A named user account is an account that belongs to an identity, so a real human being it identifies. A generic account is an account like for example root, which is not exclusively connected to a single identity.
Whatever public key is in the authorized_keys file on an account will enable the corresponding private key to log in as this account. There is no difference in behavior for named or generic user accounts here. So someone who had once access to an authorized_keys file could place his public key in it and now log on as someone else. Authenticated, not being highlighted in any log file as an attack. This might work for years, without the real user noticing, since often there is not a process in place to force a user to change his key pair on a regular base. This could almost turn a named user account into a generic one. I’ve seen people, especially in automotive R&D add colleagues SSH public keys to their authorized_keys file (which is owned by the user/account), to enable them to work on their projects when they are off sick or on vacation.
For generic accounts it’s even hard to find out, if a key in the authorized_keys file is supposed to be in it, or not. A public key entry in the authorized keys cannot be identified, or connected to the user that once created it. There is a comment field for the entry, but that can be altered to whatever value, or just left blank (Hohoho firstname.lastname@example.org now has access to root on several machines… let’s go out and find him!). In a grown IT-landscape, it is very hard to identify which public keys are wanted and could be marked as ‘approved’ or ‘known’ and which are not.
How do we know, if an entry is used by an application for automation, or by an entitled co-worker, by someone who already changed departments years ago, or maybe even by an attacker?
In most cases, it is very risky to remove entries from authorized_keys files, since they might really be used by applications, scripts, or something alike and then it’s hard to find out, what else will fail, when we remove the entry. So often, these entries are just left alone.