Ssh – Avoid separately adding ssh keys (with password) to shell sessions

ssh-agenttmux

Note: Adding a few lines to the .<name of shell>rc will not solve the problem here, since this particular ssh key has a password and that would not eliminate the need to keep typing it.

So I don't really understand how ssh-agent works under the hood. I just use ssh-agent and ssh-add ~/.ssh/id_rsa every time I need to add a key to access some remote resource. One I've added the key once, I don't need to add it again for the same "shell session" ("shell session" is probably not the appropriate jargon).

Unfortunately, I'm creating new shell sessions all the time. I'm running zsh under tmux on OS X and have a ssh key creatively named id_rsa. That ssh key has a password associated with it.

Every time I start a new shell I have to do the following

$ eval `ssh-agent`
$ ssh-add ~/.ssh/id_rsa
<type password>

which is really irritating.

I've noticed in the output of ssh-agent that the SSH_AGENT_PID environment variable is different every time. My hunch is that this environment variable and the SSH_AUTH_SOCK are the reason that keys don't need to be re-added within a single shell session. When I call the ssh program, it will use these environment variables to communicate with the ssh-agent and authentication will succeed.

I'm wondering if there's a way of sharing ssh-agents between sessions. Maybe the right approach is to add my SSH keys before starting tmux and configure tmux to preserve the SSH_AUTH_SOCK and SSH_AGENT_PID environment variables. I'm really not sure. What's the standard way of solving this problem?

Best Answer

The way ssh-agent is intended to work is that you have one agent per session. The agent starts and ends with the session.

A session starts when you log in, not when you open a terminal or when you start a shell. Systematically running ssh-agent as part of your shell startup script is definitely wrong.

I'm not an OSX user so I may be missing something, but to my understanding, on non-ancient OSX versions (since 10.5), SSH is integrated with the OSX keychain. So you shouldn't run ssh-agent at all. The SSH_AUTH_SOCK variable should point to a launchd socket (launchd provides an ssh-agent service). See How to use Mac OS X Keychain with SSH keys? and How to prevent ssh from adding my key to ssh-agent on Snow Leopard?

If you want to stick with ssh-agent for some reason, and you want to have a single agent for all sessions (which also makes sense), you can use a fixed path for the SSH socket. (I've done that on Windows.) In your .profile, set SSH_AUTH_SOCK to a fixed path, and start ssh-agent if it isn't already running.

export SSH_AUTH_SOCK=~/.ssh/auth_sock
if ! fuser "$SSH_AUTH_SOCK" >/dev/null 2>/dev/null; then
  # Nothing has the socket open, it means the agent isn't running
  ssh-agent -a "$SSH_AUTH_SOCK" -s >~/.ssh/agent-info
fi

Note that my code doesn't try to kill the agent. If you want to kill the agent when you log out, add a kill instruction to your logout scripts. Of course, if you kill all the processes running as your user, that includes the agent.

Related Question