Reconnecting SSH Agent forwarding when resuming an interrupted screen session
Asked Answered
Z

2

5

So this has proved to be a very difficult thing to google. I have a work setup where I run everything off of a laptop that I hibernate or shut down at the end of the day. Doing so obviously cuts off my SSH session in puTTY. After a bit of poking, I discovered a good way to auto-boot screen and pick up the disconnected session when connecting via puTTY (namely, adding if [ -z "$STY" ]; then screen -R; fi to the end of my .bashrc).

This works wonderfully, but I still have a problem. I use SSH agent forwarding via Pageant on my laptop (where I initially enter the password) to secondary servers. From what I can tell, this socket is broken when the puTTY session breaks and does not reconnect when reloading and reconnecting to screen.

Here's my test:

20:01:38 {~/test}$ git clone [email protected]:coldcandor/env.git
Cloning into 'env'...
remote: Counting objects: 1105, done.
remote: Total 1105 (delta 0), reused 0 (delta 0), pack-reused 1105
Receiving objects: 100% (1105/1105), 341.06 KiB | 453.00 KiB/s, done.
Resolving deltas: 100% (544/544), done.
Checking connectivity... done.
20:01:43 {~/test}$ rm -rf env

Disconnect puTTY and reconnect

20:01:58 {~/test}$ git clone [email protected]:coldcandor/env.git
Cloning into 'env'...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

As you can see, it doesn't preserve the forwarding. However, if I either do not reconnect to screen, or fully exit and reopen screen after reconnecting, then it's fine.

How do I get around this?

Zanze answered 30/12, 2015 at 20:26 Comment(0)
Z
5

Amusingly, in the process of trying to make the solution provided by Jakuje work, I stumbled upon a git link which in turn had a Superuser post which had a working version of the idea. Here's the short version:

if [ -S "$SSH_AUTH_SOCK" ] && [ ! -h "$SSH_AUTH_SOCK" ]; then
    ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock

Be sure to view that page if you want more details or other potential methods. There is discussion there that this may not work in very specific circumstances.

Zanze answered 11/1, 2016 at 20:36 Comment(0)
C
4

screen is retaining your environment variables from the first connection and the socket gets disconnected. New ssh session creates you a new socket, but the environment variable $SSH_AUTH_SOCK of that session gets overwritten by the screen one.

Clean way how to get out would be to preserve this variable into the restored screen, but I didn't find a way to do so.

As a workaround I can think of adding few lines into your .bashrc:

# move auth socket to known place so even restored screen can find it
if [ -n "$SSH_AUTH_SOCK" ]; then
  [ -f "~/.ssh/agent.socket" ] && rm -f "~/.ssh/agent.socket"
  ln "$SSH_AUTH_SOCK" "~/.ssh/agent.socket"
  SSH_AUTH_SOCK="~/.ssh/agent.socket"
fi
# you already have
if [ -z "$STY" ]; then screen -R; fi 

(didn't test it. I hope there are no syntax errors, but I believe you get my point and you can fix it -- there is edit button under my answer).

Casease answered 30/12, 2015 at 22:12 Comment(2)
That explanation why makes perfect sense. I'll play around with your proposal and see if it works out (coming back here to update after, of course). Thanks!Zanze
You were on the right track! It didn't quite work, but while trying to fix it I stumbled on a working version - see my accepted answer. Apparently my original google-fu was not good...Zanze

© 2022 - 2024 — McMap. All rights reserved.