GNU screen and SSH agent forwarding

Tags: • 

Using GNU screen and ssh-agent together creates some problems; when detaching and reattaching, you lose the ability to use ssh-agent and have to resort to typing passwords and key phrases.

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


Post new comment

The content of this field is kept private and will not be shown publicly.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • You can use Markdown syntax to format and style the text.
  • Images can be added to this post.
  • You may use [inline:xx] tags to display uploaded files or images inline.
More information about formatting options