jasonwryan.com

Miscellaneous ephemera…

tmux & SSH Keys

image

I have posted before about tmux1, the terminal multiplexer. One of the (minor) frustrations that I have to-date done nothing about was setting up persistent SSH key management across sessions. The ability to enter the passphrase for my public keys once, and then to be able to access remote hosts—or {git,hg} push—without having to re-enter a passphrase.

My solution is quite hackish, but it works and, given the only other solutions I was able to find by searching seem even more convoluted, I thought I would share it.

There are a couple of separate steps, none of them of any real consequence, but each necessary.

First, in your $HOME/.tmux.conf you need to enable update-environment:

1
2
set -g update-environment "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK
SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY"

From the man page:

Set a space-separated string containing a list of environment variables to be copied into the session environment when a new session is created or an existing session is attached. Any variables that do not exist in the source environment are set to be removed from the session environment (as if -r was given to the set-environment command).

The next step is to create a script (mine is bound to a key sequence to launch from scratch, you can adopt a simpler approach) that starts tmux and initializes ssh-agent:2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
PID=$(pgrep tmux)
new="tmux -f $HOME/.tmux/conf new -s secured"
old="tmux attach -t secured -d"

if [[ -z "$SSH_AUTH_SOCK" ]]; then
    eval `ssh-agent`
    trap "kill $SSH_AGENT_PID" 0
fi

if [[ -z "$PID" ]]; then
    urxvtc -title "SSH" -e sh -c "${new}"
else
    urxvtc -title "SSH" -e sh -c "${old}"
fi

ssh-add

The final step is to install keychain, and set it up. I followed the instructions on the Arch Wiki and opted for a couple of lines in $HOME/.bash_profile3, like so:

1
2
3
/usr/bin/keychain -Q -q --nogui ~/.ssh/id_rsa
[[ -f $HOME/.keychain/$HOSTNAME-sh ]] &&
    source $HOME/.keychain/$HOSTNAME-sh

That’s it. Now, hitting a key sequence opens a terminal, I am prompted for my passphrase and then, if I open another window, or another tmux session as long is the first session is still running, attached or not, I am authenticated and can SSH or push without a prompt.

Updated 7/10/11

I refined the sequence to provide me a little more flexibility: now the keychain is only called if I start a specific named tmux session. To do this, I changed my $HOME/.bash_profile to test for that session:

1
2
3
4
5
6
7
8
tsess=$(tmux ls)

if [[ "${tsess%%:*}" = "secured" ]] &&
   [[ -f $HOME/.keychain/$HOSTNAME-sh ]]; then
    # start keychain
    /usr/bin/keychain -Q -q --nogui ~/.ssh/id_rsa
    . $HOME/.keychain/$HOSTNAME-sh
fi
Notes
  1. Previous posts:

  2. Updated to include session test.

  3. Alternatively, placing the script in /etc/profile.d/keychain.sh will start the agent when you login, as opposed to starting a specific shell. Your call on security versus convenience…

Creative Commons image from mer de glace

Comments