When connecting to a remote server via SSH it is often convenient to use SSH agent forwarding so that you don't need a separate keypair on that server for connecting to further servers.
This is enabled by adding the
ForwardAgent yes
option to any of your Host
entries in ~/.ssh/config
(or alternatively with the -A
option). Don't set this option in a wildcard Host *
section since any user on the remote server that can bypass file permissions can now als use keys loaded in your SSH agent. So only use this with hosts you trust.
Unfortunately, this doesn't work as-is with GNU screen. On every new SSH connection, agent forwarding is setup via a socket specified in the SSH_AUTH_SOCK
environment variable (usually somewhere in /tmp
). So the socket location will be different on each connection. However, your typical screen session will live over several SSH connections and the shells in your screen session won't know where to find the current socket (their environments are not updated).
A simple fix is to symlink to the current socket from a fixed location on each new connection and have SSH look for the socket in that fixed location (specified by the SSH_AUTH_SOCK
environment variable). We'll use ~/.ssh/ssh_auth_sock
for the symlink location.
To have SSH within a screen session use the symlink, add the following line to ~/.screenrc
:
setenv SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
To update the symlink we'll use the ~/.ssh/rc
file which is executed by SSH on each connection. This can be any executable file, so something like the following script will do:
if test "$SSH_AUTH_SOCK" ; then
ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
fi
Unfortunately, this will break X11 forwarding because SSH runs xauth
on each connection, except when there is a ~/.ssh/rc
file. We can fix this by running xauth
from our ~/.ssh/rc
as suggested in the sshd(8)
manual page.
This is our complete ~/.ssh/rc
file:
#!/bin/bash
# Fix SSH auth socket location so agent forwarding works with screen.
if test "$SSH_AUTH_SOCK" ; then
ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
fi
# Taken from the sshd(8) manpage.
if read proto cookie && [ -n "$DISPLAY" ]; then
if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then
# X11UseLocalhost=yes
echo add unix:`echo $DISPLAY |
cut -c11-` $proto $cookie
else
# X11UseLocalhost=no
echo add $DISPLAY $proto $cookie
fi | xauth -q -
fi
Credits go to this blog post: Managing SSH Sockets in GNU Screen
This is not really an alternative because it would only update the symlink when a new bash session has been opened. In instances where we want to continue where we left off in an existing pane, .bashrc would never be sourced and as a consequence the symlink would not be updated. The only sure-fire way to update the symlink is to do it when a new SSH session is created as per original gist.