Dotfile magic: terminal multiplexers and SSH Agents

Making GNU screen and tmux work properly with your SSH Agent socket using a few lines of config and some shell magic.

January 22, 2016
productivity hacks

If you are a bit like me, you happen to run a few things in a terminal. Or more accurately: a lot of things, in a lot of terminals. On multiple hosts. All the time. In this case, you probably already resolved the obvious issues with running command line tools on remote hosts, where you want your tool/job to keep running when your connection dies, or where you don’t want to wait at the office for a non-interactive job to finish. In other words, you are probably already using a terminal multiplexer like GNU Screen or Tmux.

The problem

When you connect to a remote host with Agent Forwarding enabled, a socket gets created with a semi-random filename, like /tmp/ssh-TdasdJrABQ/agent.8765. The path to this socket is stored in the $SSH_AUTH_SOCK environment variable. When you then start your screen or tmux session, it takes your $SSH_AUTH_SOCK and is able to use it. Great.

Now, when you detach your session (or lose your connection) and connect again later, a new socket gets created, but the $SSH_AUTH_SOCK environment variable in your screen or tmux session is still pointing to the old one, which no longer exists. Bummer.

The fix

The fix consists of two parts, or three if you use both screen and tmux (but seriously, who does that?).

Part one - Shell config

The first part of the fix is configuring your shell to do some magic with your SSH Agent socket whenever you run tmux or screen. Here’s the relevant config part from my Bash config:

# Function for linking your random SSH agent to a fixed location
link_ssh_agent() {
  if [[ $SSH_AUTH_SOCK =~ "/tmp/" ]]; then
    ln -sf $SSH_AUTH_SOCK ${HOME}/.ssh/ssh-auth-sock
  fi
}

# Shell aliases to use the linking function when running screen or tmux
alias screen='link_ssh_agent ; screen'
alias tmux='link_ssh_agent ; tmux'

What happens is that whenever you run the screen or tmux command, it actually runs link_ssh_agent to link your (new) random SSH Agent socket to a fixed location.

Part two - Screen and Tmux config

The second part of the fix is configuring screen and tmux to use the fixed path instead of the actual $SSH_AUTH_SOCK. This can be done in the following way:

Screen:

setenv SSH_AUTH_SOCK ${HOME}/.ssh/ssh-auth-sock

Tmux:

set -g update-environment -r
setenv -g SSH_AUTH_SOCK ${HOME}/.ssh/ssh-auth-sock

That’s it!

That’s all there’s to it. You can now safely detach and re-attach sessions, or re-attach from different hosts, and you will not lose your SSH agent.