GNU screen and SSH agent forwarding
This is my old site that I'm keeping up for historical purposes and is no longer updated. You probably want to see my new site.
The problem
Finding information in this problem is difficult on the Internet (probably because of the noise of terms like "SSH" and "screen" with search engines), so this is one more page to detail a problem and my solution.
SSH looks at certain environment variables (some which point to socket files) to determine how to connect to either a locally running or forwarded copy of SSH agent.
Sessions within GNU screen (only?) have their environment created when the session is created. With subsequent detaching and reattaching, some environment variables (such as the ones required for SSH agent) will become out-of-date and point to copies of SSH agent that may no longer be running.
The quick way to see this: SSH with agent forwarding to a remote machine. Start screen and create a new session. SSH elsewhere--SSH agent forwarding works. Now, detach, and logout of the original SSH session. SSH back to that machine with SSH agent, and reattach to the screen session you started earlier. Now try to SSH elsewhere; you will be prompted for a password/passphrase, as the environment in that screen session points to a copy of SSH agent that no longer exists and falls back to other means of authentication.
The solution
My solution follows an idea proposed elsewhere (see links below)--it's not a very good one, but it is functional. When reattaching to a screen, save all needed environment variables somewhere. Once inside the screen session, reimport all these environment variables into the current environment.
I do this via the wrapper scripts scratch and screen-fix, whose code is displayed below. scratch is for screen attach. It will reattach to any running screen sessions or create one in the process, saving environment variables in the process. screen-fix imports these saved variables back into the current environment when it is run.
This solution would be that much nicer if it were automatic. One of the resource links below mentions adding running a command before the display of each prompt (done by setting the $PROMPT_COMMAND variable in bash) and fixing environment variables then, automatically. What I did not like about these methods is that they required the opening/closing of a file each time a prompt was displayed, which seems ridiculously inefficient and undesirable.
So, for the time being, screen-fix needs to be run manually once a screen session has been re-attached. For the simple way of fixing things automatically, you could simply set $PROMPT_COMMAND to screen-fix, so the environment variables are reimported each time a prompt is displayed.
scratch
#!/bin/bash
# Wrapper script for screen
if [ -n "$SSH_CLIENT" ]; then
mkdir -p "$HOME/.screen"
# Variables to save
SSHVARS="SSH_CLIENT SSH_TTY SSH_AUTH_SOCK SSH_CONNECTION DISPLAY"
for x in ${SSHVARS} ; do
(eval echo $x=\$$x) | sed 's/=/="/
s/$/"/
s/^/export /'
done 1> "$HOME/.screen/session-variables"
fi
exec screen -d -R -A
screen-fix
#!/bin/bash # Reimports certain env variables into the current screen session if [ -f "$HOME/.screen/session-variables" ]; then source "$HOME/.screen/session-variables" fi
Other Resources
Linux