214

I added a ssh key to the agent by:

$ ssh-add ~/.ssh/id_rsa_mac
Identity added: /Users/alex/.ssh/id_rsa_mac (/Users/alex/.ssh/id_rsa_mac)

After a reboot the agent doesn't have this key added anymore:

$ ssh-add -l
The agent has no identities.

Why did this happen?

Incerteza
  • 2,671
  • I don't have time to answer fully right now, but gpg-agent in ssh mode will do what you want. Try that instead of the legacy ssh-agent. If this helps I could try and expand this when I get time later. – Vality Jul 01 '14 at 10:13
  • @Vality: I doubt the gpg-agent will be persistent accross reboots. – Pavel Šimerda Jul 01 '14 at 13:08
  • @PavelŠimerda It encrypts the private keys with the users password then places them into $HOME/.gnupg/private-keys-v1.d as soon as you add them with ssh-add. It really is persistent. Well assuming you have a non volatile home directory. – Vality Jul 01 '14 at 13:32
  • 1
    @Vality: Shouldn't that be considered a security issue? Couldn't you just as well use a key without a passphrase and be done with it without needing any agent? – Pavel Šimerda Jul 05 '14 at 20:09
  • 1
    @PavelŠimerda It is not really a security issue as the key is stored encrypted with the users password, it still needs the password typed each time the user logs in to decrypt it. Storing the key unencrypted means a user with root (or a thief who took your hard disk) could steal them from your home directory, with gnupg if they steal them they will be encrypted with your password and thus useless. – Vality Jul 05 '14 at 23:39
  • Ah, interesting. So the user once decrypts using the original passphrase for gpg-agent and it then reencrypts it with the system password so it can be automatically decrypted at login, like with the good old pam_ssh.so. And gpg-agent is somehow integrated to gdm, right? – Pavel Šimerda Jul 06 '14 at 07:28
  • @PavelŠimerda It is possible to plug it into a number of DMs, personally I am using it with slim but there is also support for gdm, xdm and several others. It is also possible to make a custom back end using scripting if your DM has no native support or even just have it ask the password again after login if you really cannot make it work with your DM, and yes, it is similar to pam_ssh in that sense. I hope that clears it all up :) – Vality Jul 07 '14 at 20:33

9 Answers9

221

The addition of keys to the agent is transient. They last only so long as the agent is running. If you kill it or restart your computer they're lost until you re-add them again. From the ssh-agent man page:

ssh-agent is a program to hold private keys used for public key authentication (RSA, DSA, ECDSA). The idea is that ssh-agent is started in the beginning of an X-session or a login session, and all other windows or programs are started as clients to the ssh-agent program. Through use of environment variables the agent can be located and automatically used for authentication when logging in to other machines using ssh(1).

The agent initially does not have any private keys. Keys are added using ssh-add(1). When executed without arguments, ssh-add(1) adds the files ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and ~/.ssh/identity. If the identity has a passphrase, ssh-add(1) asks for the passphrase on the terminal if it has one or from a small X11 program if running under X11. If neither of these is the case then the authentication will fail. It then sends the identity to the agent. Several identities can be stored in the agent; the agent can automatically use any of these identities. ssh-add -l displays the identities currently held by the agent.

macOS Sierra

Starting with macOS Sierra 10.12.2, Apple has added a UseKeychain config option for SSH configs. You can activate this feature by adding UseKeychain yes to your ~/.ssh/config.

Host *
  UseKeychain yes

OSX Keychain

I do not use OSX but did find this Q&A on SuperUser titled: How to use Mac OS X Keychain with SSH keys?.

I understand that since Mac OS X Leopard the Keychain has supported storing SSH keys. Could someone please explain how this feature is supposed to work.

So from the sound of it you could import your SSH keys into Keychain using this command:

$ ssh-add -K [path/to/private SSH key]

Your keys should then persist from boot to boot.

Whenever you reboot your Mac, all the SSH keys in your keychain will be automatically loaded. You should be able to see the keys in the Keychain Access app, as well as from the command line via:

  ssh-add -l

Source: Super User - How to use Mac OS X Keychain with SSH keys?

Above Sierra?

In later versions of MacOS you may encounter this message when attempting to use the -K or -A switches. For e.g.:

 $ ssh-add -K
WARNING: The -K and -A flags are deprecated and have been replaced
         by the --apple-use-keychain and --apple-load-keychain
         flags, respectively.  To suppress this warning, set the
         environment variable APPLE_SSH_ADD_BEHAVIOR as described in
         the ssh-add(1) manual page.

So instead use the guidance provided by the warning message:

$ ssh-add --apple-load-keychain --apple-load-keychain
Identity added: /Users/slm/.ssh/somekey1_id_rsa (/Users/slm/.ssh/somekey1_id_rsa)
Identity added: /Users/slm/.ssh/somekey2_id_rsa (/Users/slm/.ssh/somekey2_id_rsa)

You can also suppress that warning using this environment variable, APPLE_SSH_ADD_BEHAVIOR with the value macos. From the ssh-add man page:

$ man ssh-add
...
APPLE_SSH_ADD_BEHAVIOR
        Enables or disables the older processing of the -A and -K 
        options used in earlier macOS releases.  These options have 
        been renamed --apple-load-keychain and --apple-use-keychain
        respectively. However, -A and -K still behave as in earlier 
        releases except in the following circumstances.  If a 
        security provider was specified with -S or SSH_SK_PROVIDER, 
        or if APPLE_SSH_ADD_BEHAVIOR is set to the value “openssh”, 
        then ssh-add uses standard OpenSSH behavior: the -A flag is 
        not recognized and the -K flag behaves as documented in the 
        DESCRIPTION section above.
    Otherwise, ssh-add -A and -K will behave as in earlier macOS 
    releases. A warning will be output to standard error unless
    APPLE_SSH_ADD_BEHAVIOR is set to the value “macos”.  Note: 
    Future releases of macOS will not support neither -A nor -K
    without setting this environment variable.

slm
  • 369,824
  • really? On Linux I don't have this issue. Do I have to "ssh-add my_key" each time I restart my computer? – Incerteza Jul 01 '14 at 02:37
  • 3
    @Alex As the answer explains, the agent automatically adds ~/.ssh/id_rsa. I'm guessing this is the location of your keyfile on linux. It is also possible you're not using the standard ssh key agent. There are others, such as gnome-keyring-daemon, which may have different behavior. – phemmer Jul 01 '14 at 02:41
  • but on Mac it's named "id_rsa_mac". How do I make the agent add it automatically? – Incerteza Jul 01 '14 at 02:45
  • @Patrick: I'm not sure whether the classic ssh-agent adds any keys automatically. In my opinion it's ssh-add that reads the standard locations, or the ssh client if you're not using the agent. – Pavel Šimerda Jul 01 '14 at 06:58
  • You could add ssh-add ~/.ssh/id_rsa_mac to your ~/.bashrc file so it runs every time you start a terminal. Of course that won't authorize apps started from the launcher. – joeytwiddle Jul 01 '14 at 08:14
  • @PavelŠimerda You are correct. The classic ssh-agent does not. I was thinking it did. I know some key agents do though, but now I cant remember which ones :-) – phemmer Jul 01 '14 at 11:13
  • 5
    Small sidenote, if your ssh-add command doesn't recognise the -K flag you probably are using the macports version of ssh-add ... you can bypass the macports version by specifying the full path to the OSX version of ssh-add like this : /usr/bin/ssh-add -K /path/to/private/key – ChrisR May 27 '15 at 12:16
  • Note that if you brew install openssh, the BSD version of ssh-add you get will not support the -K option that stores the passphrases in your keychain. You'll need to brew uninstall openssh unless you can rebuild it with keychain support. – Dennis Oct 27 '15 at 10:10
  • macOS Sierra changed how ssh-add needs to be used. See http://apple.stackexchange.com/a/254714/47362 – David Winiecki Jan 18 '17 at 05:55
  • It's better if you add it like explained in https://unix.stackexchange.com/a/335720/281129 – Aashutosh Rathi Jan 09 '20 at 11:17
  • 1
    As @PavelŠimerda noted, ssh-add also automatically checks for an id_ed25519 file now. – needfulthing Nov 16 '21 at 12:56
  • 1
    On Monterrey 12.6, I get this message with ssh-add -K:

    WARNING: The -K and -A flags are deprecated and have been replaced by the --apple-use-keychain and --apple-load-keychain flags, respectively. To suppress this warning, set the environment variable APPLE_SSH_ADD_BEHAVIOR as described in the ssh-add(1) manual page.

    – Justin Goldberg Apr 26 '23 at 22:23
  • @JustinGoldberg thanks for the details, added them to the answer. – slm Apr 28 '23 at 23:02
27

The ssh-agent is a session service that stores keys temporarily for the user.

The main purpose of SSH agent is to remember the cleartext version of a key secured using a passphrase. In other words, the key is stored on the disk encrypted using a passphrase and the owner of the key uses ssh-add or some GUI tool to provide the passphrase and instruct the agent to remember it until the session exits or the user requests removal explicitly.

If you're not using a passphrase and you're not using agent forwarding (which is insecure for most purposes anyway), you don't need the agent at all. Any SSH client should be able to read the key from the disk, either from a standard location, or from an explicitly specified ones.

The standard locations are listed in the manual page ssh(1):

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.

When using nonstandard locations, you can use the -i switch to ssh described in the same manual page, or the respective option in the SSH client you are using.

15

In Sierra:

Use UseKeychain. (I haven't tried this but it sounds like the most correct solution.)

Or

ssh-add -K /your/key
echo ssh-add -A | cat >> ~/.bash_profile

Or create a plist file instead of appending to ~/.bash_profile.

Disclaimer: as others have noted, I don't know how secure it is to store ssh passphrases in keychain.

8

I do these to help me enable SSH identities after Mac reboot. Works on updated macOS 10, 11 and 12.

  1. Make sure your SSH key has a passphrase when you create it because it is required for keychain. If you don't have a passphrase, you still can modify your no-passphrase-privatekey to have one by running this command:

    ssh-keygen -p -f ~/.ssh/<.your-privatekey-filename.>
    
  2. Add your ssh private key to keychain by running this command:

    ssh-add --apple-use-keychain ~/.ssh/<.your-privatekey-filename.>
    
  3. Add all your SSH related private keys in the keychain to your ssh-agent by running this command: ssh-add --apple-load-keychain

  4. Verify by running ssh-add -l. You should see a list of results if everything works well.

You would notice, after you reboot your computer you lost your SSH identity (ssh-add-l shows no identity found ...). You can fix it in either of two ways:

  1. Add ssh-add --apple-load-keychain to your terminal profile; for example if you use zsh, add ssh-add --apple-load-keychain to ~/.zshrc or any of your profile configuration files.

  2. You can add a macOS startup script by creating a file in ~/Library/LaunchAgents/com.<.yourusename.>.<.name of command.>.plist. For example, com.myusername.ssh.plist, containing:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
      <dict>
      <key>Label</key>
        <string>com.user.loginscript</string>
      <key>ProgramArguments</key>
        <array>
          <string>ssh-add</string>
          <string>--apple-load-keychain</string>
        </array>
      <key>RunAtLoad</key>
        <true/>
      </dict>
    </plist>
    

    Tell launchd to load this script every reboot:

    launchctl load ~/Library/LaunchAgents/com.myusername.ssh.plist
    

    (If you don't know your username, run the id command to see your current username.)

tripleee
  • 7,699
5

Note that almost none of the answers above have a solution for this issue. I have both Linux and MacOs solutions listed below.

On Linux, this same issue occurs. As others have stated, this is because ssh-add is only temporary. The solution is to either add ssh-add command to .bashrc or simply not use it.

The solution is as described by this answer to How to tell git which private key to use?

Option 4: ~/.ssh/config

Use the ~/.ssh/config file as suggested in other answers in order to specify the location of your private key, e.g.

Host github.com
  User git
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa

On Mac, the following line added to config in ~/.ssh/config worked for me

Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/github

I didn't test this answer to macOS Sierra doesn’t seem to remember SSH keys between reboots but I think this is what you're looking for.

Greenonline
  • 1,851
  • 7
  • 17
  • 23
Jacob Waters
  • 151
  • 1
  • 2
3

For me only solution to keep keys persistent after boot in ssh agent was to add these lines to ~/.bash_profile:

ssh-add -A 2>/dev/null;
ssh-add ~/.ssh/your_key 2>/dev/null;
Maksim Luzik
  • 2,423
  • your_key is the real ssh key or id_ed25519 ? – James78 Mar 05 '22 at 15:26
  • @James78 when I configured this I think the key was generated with RSA algorithm. But it should work for any algorithm generated key as it is just a path to the actual key that matters – Maksim Luzik Mar 05 '22 at 22:00
1

As an alternative (especially in Linux where -K does something else), you can add the following line to your ~/.ssh/config:

AddKeysToAgent yes

This way when you first use a given key after reboot, you'll get asked for the password, but then SSH will keep it in agent. This way the password isn't stored anywhere and it's still very convenient.

Rafał G.
  • 125
1

If you use ZSH, there is a very good plugin:

https://github.com/hkupty/ssh-agent

To install using zplug (a better oh-my-zsh):

zplug "hkupty/ssh-agent", from:github
Henry H.
  • 111
0

My issue was that while I generated keys at /home/user/.ssh, the home directory of my user was not at /home/user.

  • 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 Jun 19 '23 at 15:35