94

I've started using SSH keys instead of passwords just recently (thanks to GitHub, of course), so please keep in mind that I'm pretty new to this whole concept. Currently my keys simply lie under ~/.ssh, but I'm not sure if this is a good practice. E.g. if I have multiple machines, I'd need to duplicate my private keys, which I think is undesirable. Or, if my HDD goes kaput, then I'll lose those keys, which (I guess) is undesirable as well.

So, what are best practices on storing SSH keys securely, conveniently, and reliably?

Seems like using a smartcard is an option (see Smartcards for storing gpg/ssh keys (Linux) - what do I need?), is this the best one?

Update: The reason for the question was that many services (like GitHub, AWS EC2) provide guides on how to set up SSH keys for using the service, but little to no background (like, what to do if you already have a key generated by ssh-keygen [1], what are recommended security measures). And it's unclear whether that info is in fact unimportant, or you're expected to know it ‘by default’.

To sum up answers up to this point (but please read them, and if you have something to add—please do): seems like in this case it's fine if you just leave your private keys in ~/.ssh, as long as you keep them from other people; but make sure that you have another way to access the service to upload or generate a new key if you lose one (which is normally the case).

[1] GitHub used to provide help on how to manage multiple keys.

4
  • That link seems to be broken help.github.com/multiple-ssh-keys
    – KJ Price
    Aug 22, 2015 at 2:13
  • @KJ Price, thanks to the Internet Archive's Wayback Machine, the page is still available online, though not at its original link. A copy of the page archived on September 2, 2011 can be found at Multiple SSH keys.
    – moonpoint
    Aug 22, 2015 at 12:48
  • 1
    "it's fine if you just leave your private keys in ~/.ssh, as long as you keep them from other people". And how to you do that? Every app you download, every script you run, every makefile you execute, every dependency you install in python/ruby/rust/node could be stealing your .ssh folder contents
    – gman
    May 3, 2020 at 3:59
  • @gman Wouldn’t password-protecting the key and keeping the password in e.g. Keychain help? Sep 8, 2022 at 10:37

7 Answers 7

52

E.g. if I have multiple machines, I'd need to duplicate private keys, which I think is undesirable.

No, actually you don't. If you have multiple machines, you just create a separate private key on each one. For each private key, just upload the corresponding public key to GitHub using the same process.

Also, if my HDD go kaput, I'll lose my private key, which (I guess) is undesirable as well.

Not really; if you lose your private key, just generate a new one and upload the corresponding public key.

For what it's worth, you're right that duplicating a private key is highly undesirable. Ideally, a private key should be generated in one file (~/.ssh/id_rsa for example) and should never leave that file - that is, it should never be copied, moved, and especially not transferred over a network. (e.g. I exclude them from backups) Because of the nature of asymmetric authentication protocols, you only need to worry about keeping your private key out of the hands of others. If you go a bit overboard and you lose track of it yourself, it's generally not a big deal. (This is not to be confused with asymmetric encryption private keys, e.g. GPG keys, which you probably want to hold on to.)

9
  • 19
    This only works if you have some other method of accessing the servers that that private key provides access to. You can upload the new public key only if you have that backup access.
    – TREE
    Aug 16, 2011 at 20:08
  • 2
    @TREE: right, but in my experience it's exceptionally rare to find a server that doesn't provide some alternative method of access (or at least of adding an additional public key without going through SSH).
    – David Z
    Aug 16, 2011 at 20:11
  • 3
    Thanks, that clears things up a lot. Really, losing private SSH key doesn't look like an issue, since for all services I'm using there always seems to be another way to access a service to upload a new one. Aug 16, 2011 at 20:58
  • 3
    AWS doesn't provide any other form of access besides the private key. You have to disconnect the drive and fool around with it to get access once you've lost your private key. Jan 8, 2016 at 23:10
  • 1
    Note that you can put a password on your private key if you want another layer of security.
    – sudo
    Jun 19, 2016 at 17:34
12

There is a very nice tool named KeePass2 (http://keepass.info/) with the extension (http://lechnology.com/software/keeagent/)

You can store there Passwords, SSH Keys, and a lot more(on the official KeePass page are a lot more usefull extensions)
If you want to login automaticaly with your SSH Keys, you just need to install PuTTY, Pageant and KeePass with KeeAgent. If you are configuring it correctly you dont have to setup the Keys in PuTTY, Pageant or FileZilla.

I use it myself and i'm pretty happy about it. I have over 30 VPS and Root Server with a certain amount of different SSH Keys and the only thing i have to do ist open KeePass(Its not my primary Password Safe) and then i just need to type in the console my passphrase.

10

I would add that ~/.ssh/ is readable by your browser if you are using the same user account to run both.

Try it! Point your browser to your private key in your home directory. It's fun.

So I would recommend storing ssh-keys in the home directory of another user account.

a word on passphrase protecting keys

  • These days, cracking non-randomized passwords is super fast . Check out hash cat
    • ( Though random and long 12+ char passwords still take reasonably long to brute force)
    • So AES encrypted ssh keys are uncrackable for the foreseeable future as long as you use good long passphrases. See github recommendations
  • So some website can guess-grab your key w/o JavaScript . And then brute-force the key offline.
  • And browsers can look into your Clipboard w/ JS too. So copy-pasting very long passphrases also puts you at risk from the more sophisticated javascript attacks.

look_at_keys.html

 9 <HTML>
10 <HEAD>
11 <TITLE>look at keys</TITLE>
12 </HEAD>
13 <FRAMESET cols="20%, 80%">
14   <FRAMESET rows="100, 200">
15       <FRAME src="/Users/yourname/.ssh/stuff.pem">
16       <FRAME src="blah.html">
17   </FRAMESET>
18   <FRAME src="contents_of_frame3.html">
19 </FRAMESET>
20 </HTML>
3
  • 24
    To be clear, just because the browser can read your private key that doesn't mean a website running in the browser can.
    – Ajedi32
    Aug 27, 2013 at 18:55
  • 9
    But, if you inject a process in browser's process. Then you can take control of browser as well. So this argument is perfectly valid.
    – BigSack
    Apr 5, 2014 at 10:16
  • 1
    But then you have to hack the process that injects processes in your browsers's processing unit's process register.
    – Skid Kadda
    Oct 18, 2017 at 6:43
4

I would recommend storing private keys:

  • offline (not in the cloud)
  • in more than one place
  • apart from anything it's related to, e.g. a key for your encrypted data, store it in a separate place from the data

I'd say, the best place would be:

  • an external hard drive
  • a flash key
  • a computer not plugged into the internet

Even better, just print it out, and put it in a fire proof safe.

1
  • 7
    Security/best practices work hand in hand with practicality. If a security strategy hamstrings the ability to use a system, it s going to be bypassed by the user rather than the attacker.
    – zaTricky
    Jul 19, 2017 at 13:28
2

You can store your ssh keys in a separate directory inside an encrypted partition. Then you can use ssh pointing to that directory with -i:

ssh -i identity_file [email protected]

Full description (man ssh):

-i identity_file

Selects a file from which the identity (private key) for public key authentication is read. The default is ~/.ssh/identity for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. Identity files may also be specified on a per-host basis in the configuration file.
It is possible to have multiple -i options (and multiple identities specified in configuration files). If no certificates have been explicitly specified by the CertificateFile directive, ssh will also try to load certificate information from the filename obtained by appending -cert.pub to identity filenames.

My approach to security is that I divide information into private and general. I don't want to encrypt my whole home partition, that's why I copy secret files (like those in ~/.ssh) into an encrypted partition.

I think this gives some rather efficient security, because malware won't find anything in ~/.ssh, and probably it won't scan your whole system or shell profiles to find that location.

-F configfile 

sets path to config file.

P.S. I would create an alias alias ssh='ssh -i ... -F ...' and put it into your profile.

P.P.S. I didn't check this yet, and I don't know how other programs (like git) will work with these ssh settings.

1

I have a tar file which has my user dir setup (.bashrc, .ssh/ and other config files) that I keep in a safe place. When I get a new shell account anywhere, I unzip the tar file into it.

You should only put your private keys onto servers you trust, otherwise you should create a new private key on the server just for that server, and allow it access to things you want it to have access to.

Personally, I'm comfortable just copying my .ssh/ stuff around everywhere (it also means by regular ssh key gets ssh access instantly, since it's already in the authorized_keys file).

5
  • I guess, having encrypted ~/.ssh hanging around on a usb stick would save from the need to generate and upload new key in case of the hardware failure. However, since there're very few servers that I use SSH keys to access (and very few machines I connect from), generating new keys won't cause much overhead. Aug 16, 2011 at 21:35
  • 2
    It's horses for courses and depends on why you use the keys. I don't see a problem copying an ssh private key over an already encrypted SSH link. But if you don't trust the target machine and don't know who has root access, you shouldn't put anything on the server you can't afford to lose. Aug 16, 2011 at 22:12
  • You don't want put your private key on someone else's server. Anyone with Root access on that server can read your private key and then they can impersonate you on systems that you access with that private key. You should only be putting your public key for access to the server. And don't think the passphrase helps that much if you are using it on a remote machine to decrypt a private key.
    – Codeguy007
    Dec 1, 2017 at 4:15
  • You can forward ssh-agent over ssh. That way you don't need to store the private key on the server or send your passphrase over the net. stackoverflow.com/questions/12257968/…
    – Codeguy007
    Dec 1, 2017 at 4:34
  • @Codeguy007 you can do this (I use agent forwarding frequently), but the agent's process on the remote server is available to any user with sufficient privileges on that system, and the keys can be extracted, so care should be taken.
    – Schlueter
    May 29, 2020 at 21:32
1

You can also try https://github.com/omegion/ssh-manager It supports multiple providers like 1Password, Bitwarden and AWS S3.

2
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    May 27, 2022 at 14:40
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
    – Toto
    May 27, 2022 at 14:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .