Tuesday, 13 November 2012

ssh-and-tmux: part three

On many of the hosts I connect to using my ssh-and-tmux script I want to be able to use git to connect to repositories via ssh. Initially this is as simple as ensuring that ssh-agent forwarding is enabled by passing -A to ssh. The problem comes when I disconnect and reconnect from somewhere else. This kills the ssh session and the socket used for the agent is removed and SSH_AUTH_SOCK ends up pointing to a file that doesn't exist.

The solution is to use a fixed name for the authentication socket and symlink that name to the real one as it changes.

#!/bin/sh
set -e

if [ -z "$SSH_AUTH_SOCK" ]; then
    echo No ssh agent found. Starting one.
    eval `ssh-agent`
fi

if [ -n "$SSH_AUTH_SOCK" ]; then
    export SSH_AUTH_SOCK_OLD=$SSH_AUTH_SOCK
    export SSH_AUTH_SOCK=$HOME/.ssh/.tmux-agent
    ln -sf "$SSH_AUTH_SOCK_OLD" $SSH_AUTH_SOCK
else
    echo Failed to start ssh agent

    # Set the socket anyway in case someone reattaches later with a
    # valid agent.
    export SSH_AUTH_SOCK=$HOME/.ssh/.tmux-agent
fi

# Use a specific name for the tmux/screen session so
# that we can tell that it's one that uses this scheme.
# We have to detach other clients with tmux so that we
# don't end up with a stale agent in them when we
# return to them later.
if which tmux >/dev/null 2>/dev/null; then
    tmux -2 -L ssh-agent "$@" attach -d || tmux -2 -L ssh-agent "$@"
else
    exec screen -S ssh-agent "$@" -x -RR
fi

Now the original script just needs to run this script on the remote host rather than executing tmux directly.

I've been using this final solution for quite a while now and it works really well.

No comments: