Have a system that expires SSH keys every 90th day [closed]
I have a customer that now requires us to change every password every 90th day due to their interpretation of GDPR. That's fine for the web-based system we develop for them because we can just implement those rules. But they also require us to change the passwords on our SSH keys used to access the servers, which is, well, not fine.
- Is it possible to change the password on an existing SSH key?
-
If not, are there any tools we can use to handle this? I'm thinking:
a. Create new keys.
b. Distribute all public keys to existing servers.
c. Remove existing public keys.
d. Archive old private keys .I've read some posts here about Puppet, but as I understand it they aim to only solve the problem with distributing the public keys among the servers and not creating new keys every nth day? Should I go further with my research into Puppet?
What is the community standard when it comes to password retention and ssh keys? How do you do it?
Solution 1:
The customer is wrong here and does not understand what they're talking about. Changing the passphrase on a private key is a very bad idea, because it has very counter-intuitive security properties.
Normally, users think of passwords that they have changed as "no longer secret". They might become throwaway passwords for low-value sites, online handles/nicknames, punchlines to jokes, etc., and any paper on which they're written might become scrap that's exposed.
For a passphrase used to encrypt a private key , that's not how it works! The passphrase must be kept secret forever unless all privileges associated with the key have been revoked (and the following doesn't apply to ssh keys, but if the passphrase is for a key used not just for signing, but for receiving private messages, then forever really means forever). This is because of the possibility that the encrypted private key file has been obtained by an attacker or stored somewhere (like in a backup) where it might be obtained by an attacker in the future. If the passphrase is ever revealed, it's then compromised.
In some sense, a private key that has gone through N passphrases in its lifetime is 1/N as secure, since knowledge of anyone one of the past passphrases is sufficient to compromise the key if the attacker has had access to the encrypted private key file.
Now, back to your problem.
If the customer had not latched onto this "ssh passwords" misconception and dug in on it, the right thing to do would be just never bringing it up to them, and follow best practices for key handling yourself. But now that they have, you probably have to do something to satisfy them. You could try explaining how passphrases encrypting private keys have different security properties from passwords, but given how wrong the customer is about a lot of things here (password expiration is a bad idea in general) I doubt that's going to work.
That leaves you with the task of automating a system for distributing new keys. I would strongly discourage you from automating a system of generating the new keys centrally, since private keys should never be moved between machines. Instead, you should have processes/reminders/scripts to make it easy for the employees/contractors on your side who need access to generate new private keys and publish the corresponding public keys, and have the public key distribution system (Puppet or otherwise) that you use push these out to the systems they need to access.
In addition: One thing that might convince the customer to drop this is mentioning that there is fundamentally no way to enforce that the new private key have a different passphrase than the old one, or even that it have a passphrase at all.
Solution 2:
The answer to your first question: "Is it possible to change the password on an existing SSH key?" is yes. With openssh that is as simple as ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
The problem is that the password is in/on the private key file, which is a simple format that doesn't have support for an expiry date. Also a large part of the concept of key based authentication in ssh is that the private key is not centrally managed, it should only exist on the user's workstation which makes it nigh impossible to enforce a password expire policy on the private key.
Instead: in every environment I've been in before the password policy is on the user account object, not on the method used to access said account. When a password is expired or an account locked, all access methods get locked out including the ssh key.
Add multi-factor authentication when you need more security on an account.
But I'm curious what other people have done to address your valid concerns.
Solution 3:
One possibility that may or may not be sufficient is using an SSH user CA, which allows you to set a lifetime on the signed key. Whatever automation you put around key signing can refuse to sign for more than 90 days. Then, add the public key for your user CA to TrustedUserCAKeys in /etc/ssh/sshd_config and set AuthorizedKeysFile to none.
Solution 4:
Using AuthorizedKeysCommand some expiry mechanism could be implemented on the server side. From simple checking the file timestamp to something more complicated.
Solution 5:
You could use a tool like Hashicorp's Vault to create short lived, signed SSH keys. Each user would get a new key every day (or so). You would authenticate to Vault to get the certificate using whatever you use today, like an LDAP server.
The effort of setting this up is not immense, but in my experience larger that what @Mark refered to in his comment. You are basically replacing one problem (clueless client requirements) with another (shard management).
But it does enable a few other scenario like easily generating in-house X509 certs and managing database passwords, application secrets in text file. You judge the effort and ROI.
Also note that the open source version does not have DR capabilities (it has everything else).