Welcome to End Point’s blog

Ongoing observations by End Point people

GNU Screen + SSH_AUTH_SOCK; my new approach

Over the years, I've played around with several different methods of keeping my forwarded SSH-Agent authentication socket up-to-date in long-running screen sessions (referenced via the $SSH_AUTH_SOCK shell variable). The basic issue here is that Screen sees the process environment at the time it was initially launched, not that which exists when reattaching in a subsequent login session. This means that the $SSH_AUTH_SOCK variable as screen sees it will refer to a socket which no longer exists (as it was removed when you logged out after detaching on the initial login when starting screen).

Some of my previous methods have included a hard-coded variable for the socket itself (downsides: if it's a predictable name you're potentially opening some security issues, plus if you open multiple sessions to the same account, you kill the latest socket), symlinking the latest $SSH_AUTH_SOCK to a hard-coded value on login (similar issues), dumping $SSH_AUTH_SOCK to a file, and aliasing ssh and scp to first source said file to populate the local window's enviroment (doesn't work in scripts, too much manual setup when adapting to a new system/environment, won't work with any other subsystem not already explicitly handled, etc).

Recently though, I've come up with a simple approach using screen's -X option to execute a screen command outside of screen and just added the following to my .bashrc:

screen -X setenv SSH_AUTH_SOCK "$SSH_AUTH_SOCK"

While not perfect, in my opinion this is a bit of an improvement for the following reasons:

  • It's dirt-simple. No complicated scripts to adjust/maintain, just a command that's almost completely self-explanatory.
  • It doesn't kill the environment for existing screen windows, just adjusts the $SSH_AUTH_SOCK variable for new screen windows. This ends up matching my workflow almost every time, as unless a connection dies, I leave the screen window open indeterminately.
  • If you have multiple sessions open to the same account (even if not running both in screen), you're not stomping on your existing socket.
  • Did I mention it's dirt-simple?

There are presumably a number of other environment variables that would be useful to propagate in this way. Any suggestions or alternate takes on this issue?


Mark Johnson said...

David, this is extremely useful. I had long ago just resigned myself to a tedious manual process to deal with this.

As a follow-up, you can further direct this activity to a specific screen in the event that multiple screen sessions are being used by different user sessions through the same user account:

screen -r myscreen -X ...

That way you don't update everyone's screens with your SSH_AUTH_SOCK.

JT Justman said...

Thanks, this is nice and simple. However with my current work environment I often find myself needing to pass the agent on to a long-lived screen window. I've been considering the symlink for some time now, but I still wonder if there's a more elegant way.

HarleyPig said...

In my crontab I have the following line

@reboot ssh-agent -s | grep -v echo > $HOME/.ssh-agent

Then I login and run ssh-add for each key I need and start my screen session.

It works for the most part, but it seems to lose the socket at random times, sometimes after months of working just fine. But its a workable solution for me.

Brian Buchalter said...

When executing your command, screen would start and then in the window title say cannot exec "SSH_AUTH_SOCK": no such file or directory.

I found that added your setenv option to my $HOME/.screenrc accomplished the same job.

David Christensen said...

Hi Brian,

Out of curiosity, did you have an already-running screen when this happened? This sounds like the behavior when it's launched afresh with a command name, so I wonder if it's either that or if your version may not be recognizing the -X flag. What screen version are you using?



Brian Buchalter said...


Screen version 4.00.03 (FAU) 23-Oct-06

Pretty old! Could be the issue, but the man page says it supports setenv.

Greg Sabino Mullane said...

I like this, but it breaks down for me in two ways: there are usually multiple screen sessions on the boxes I connect to, and as Mark points out, you have to go to extra lengths to not change everyone's env. Second, the lack of env changes on existing windows is a deal-breaker for my workflow. I suppose that means back to using named symlinks for the moment.