TMUX and SSH auto-login with ssh-agent (finally!)

I finally got this working, so I thought I’d blog about it.

Here’s what I wanted to achieve:

This is harder than you might think, as it requires several things to work together. After reading through loads of blog posts I worked out how to do it:

It was the last step I was struggling with. To setup the first two steps follow the guide here.

However, if you then don’t do the final step, it will always ask for a passphrase for your key whenever you try to SSH:

[rwmorris@dev:~] $ ssh qa
Enter passphrase for key '/home/rwmorris/.ssh/id_dsa.pub':

For step 3 you need your tmux session to be aware of the ssh-agent environment, which isn’t too hard.

The problem in step for is that, stupidly, ssh-agent processes persist even if you log out of your terminal, and then if you spawn a new one when you log in again you end up with hundreds of orphaned processes and the sysadmins get upset.

The solution to that is to make sure you start you ssh-agent with the “-a” option to specify the socket it should use, and then make sure you store the process ID (PID) somewhere. That way you can re-set the $SSH_AUTH_SOCK and $SSH_AGENT_PID environment variables to the correct values when you login again, and everything will work.

1: Fire up the ssh-agent process before you run your tmux session, making sure you only start a new one if there isn’t an existing one already.

# ~/.bashrc

if [ -z "$TMUX" ]; then
    # we're not in a tmux session

    if [ ! -z "$SSH_TTY" ]; then
        # We logged in via SSH

        # if ssh auth variable is missing
        if [ -z "$SSH_AUTH_SOCK" ]; then
            export SSH_AUTH_SOCK="$HOME/.ssh/.auth_socket"
        fi

        # if socket is available create the new auth session
        if [ ! -S "$SSH_AUTH_SOCK" ]; then
            `ssh-agent -a $SSH_AUTH_SOCK` > /dev/null 2>&1
            echo $SSH_AGENT_PID > $HOME/.ssh/.auth_pid
        fi

        # if agent isn't defined, recreate it from pid file
        if [ -z $SSH_AGENT_PID ]; then
            export SSH_AGENT_PID=`cat $HOME/.ssh/.auth_pid`
        fi

        # Add all default keys to ssh auth
        ssh-add 2>/dev/null

        # start tmux
        tmux attach
    fi
fi

2: Make sure tmux is configured to pass through appropriate environment variables so it can find the socket for your ssh-agent session:

# ~/.tmux.conf
set -g update-environment -r

And win. Sorry it’s not more simple. You’d think a lot of this would be the default use-case so it would just work out of the box, but sadly that’s not the way the unix world works.

By @nottrobin