macOS Sierra doesn’t seem to remember SSH keys between reboots
I have to run this command since upgrading to macOS:
ssh-add -K
Corrects the problem after the reboot but I have to run this command every time I log on to my computer.
If I do not run the command above, my keys in ~/.ssh
are skipped and I am being asked server password in order to establish the connection.
As of macOS Sierra 10.12.2 Apple added an ssh_config
option called UseKeychain
which allows a 'proper' resolution to the problem. Add the following to your ~/.ssh/config
file:
Host *
AddKeysToAgent yes
UseKeychain yes
From the ssh_config
man
page on 10.12.2:
UseKeychain
On macOS, specifies whether the system should search for passphrases in the user's keychain when attempting to use a particular key. When the passphrase is provided by the user, this option also specifies whether the passphrase should be stored into the keychain once it has been verified to be correct. The argument must be 'yes' or 'no'. The default is 'no'.
I had this issue as well when attempting to deploy some code using Capistrano. Very frustrating. Here are two methods I know of to deal with this issue.
Method 1: Add all known keys to the SSH agent.
So one solution I found is to run ssh-add
with the -A
option—which adds all known identities to the SSH agent using any passphrases stored in your keychain—like this:
ssh-add -A
Now this works but it won’t persist across reboots. So if you want to never worry about this again, just open up your user’s ~/.bash_profile
file like this:
nano ~/.bash_profile
And add this line to the bottom:
ssh-add -A 2>/dev/null;
Now when you open a new Terminal window, all should be good!
Method 2: Add only SSH keys that are in the keychain to the agent.
So while the ssh-add -A
option should work for most basic cases, I ran into an issue recently where I had 6-7 Vagrant boxes (which uses SSH keys/identities for access) setup on a machine on top of the more common id_rsa.pub
in place.
Long story short, I ended up being locked out of a remote server due to too many failed tries based on SSH keys/identities since the server access was based on a password and SSH keys/identities are SSH keys/identities. So the SSH agent tried all of my SSH keys, failed and I couldn’t even get to the password prompt.
The problem is that ssh-add -A
will just arbitrarily add every single SSH key/identity you have to the agent even if it’s not necessary to do so; such as in the case of Vagrant boxes.
My solution after much testing was as follows.
First, if you have more SSH keys/identities added to your agent than you need—as shown with ssh-add -l
then purge them all from the agent like so:
ssh-add -D
With that done, then start the SSH agent as a background process like so:
eval "$(ssh-agent -s)"
Now, it gets weird and I am not too sure why. In some cases you can specifically add the ~/.ssh/id_rsa
key/identity to the agent like so:
ssh-add ~/.ssh/id_rsa
Type in your passphrase, hit Return and you should be good to go.
But in other cases simply running this is enough to get the key/identity added:
ssh-add -K
If that’s all worked, type in ssh-add -l
and you should see one lone SSH key/identity listed.
All good? Now open up your .bash_profile
:
nano ~/.bash_profile
And add this line to the bottom; comment or remove the -A
version if you have that in place:
ssh-add -K 2>/dev/null;
That will allow the SSH key/identity to be reloaded to the SSH agent on each startup/reboot.
UPDATE: Apple has now added a UseKeychain
option to the open SSH config options and considers ssh-add -A
a solution as well.
As of macOS Sierra 10.12.2, Apple has added a UseKeychain
config option for SSH configs. Checking the man page (via man ssh_config
) shows the following info:
UseKeychain
On macOS, specifies whether the system should search for
passphrases in the user's keychain when attempting to use a par-
ticular key. When the passphrase is provided by the user, this
option also specifies whether the passphrase should be stored
into the keychain once it has been verified to be correct. The
argument must be ``yes'' or ``no''. The default is ``no''.
Which boils down to Apple seeing the solution as either adding ssh-add -A
to your .bash_profile
as explained in this Open Radar ticket or adding UseKeychain
as one of the options in a per user ~/.ssh/config
.
As explained here, this is the recommended method since macOS 10.12.2:
-
Add the following lines to your
~/.ssh/config
file:Host * UseKeychain yes AddKeysToAgent yes
Any key you add to the ssh-agent using the
ssh-add /path/to/your/private/key/id_rsa
command will be automatically added to the keychain, and should be autoloaded upon reboot.
I'm adding this answer because:
- Other answers tell you to add the
IdentityFile ~/.ssh/id_rsa
line, but that option is not needed for autoloading the keys (and it'll actually bind that particular key for the host section your add it to, which you won't want if you use different keys for different hots). - The accepted answer mentions
UseKeychain
, but that is not enough to persist the keys inssh-agent
after a reboot.
I've written a short post about this topic that might help you.
A solution is calling ssh-add -A
command on every startup.
Just add .plist
file with the following content to the path ~/Library/LaunchAgents/
or create one with Lingon app:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ssh-add-a</string>
<key>ProgramArguments</key>
<array>
<string>ssh-add</string>
<string>-A</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
<!-- @@@@LingonWhatStart:ssh-add -A@@@@LingonWhatEnd -->
Since macOS 10.12.2 you can use the UseKeychain
option.
Read more here or look into man ssh_config
.
UseKeychain
On macOS, specifies whether the system should search for passphrases in the user's keychain
when attempting to use a particular key. When the passphrase is provided by the user, this
option also specifies whether the passphrase should be stored into the keychain once it has
been verified to be correct. The argument must be ``yes'' or ``no''. The default is ``no''.
So just do the following:
echo "UseKeychain yes" >> ~/.ssh/config