12 Comments
User's avatar
foo borker's avatar

I believe socket symlinking works fine with both screen and tmux so a small shell wrapper around screen/tmux should do the job. Did OP try that route and give up?

Julio Merino's avatar

And what do you do with the symlink when the session owning it disconnects and you have some other session attached?

Read the original article at https://blogsystem5.substack.com/p/ssh-agent-forwarding-and-tmux-done . It answers your question.

foo borker's avatar

I read the article, very nicely written, but I don't seem to encounter the problem that you mentioned of the dangling symlink causing problems after disconnect. It's possible we have different authentication modules at $work that are hiding the issue you are seeing but I've used the symlink refreshing wrapper for years now without issue. Although I've recently switched to mosh ...

Julio Merino's avatar

Do you ever access the same remote system with two concurrent connections? That's when the issue would arise with the symlinks solution, if you disconnect from the first connection and continue using the other.

foo borker's avatar

ah, no, I always serially connect from the same laptop to remote machine either at $work or at home, so the concurrent access issue never arises. and with mosh, it kinda feels like I don't even disconnect.

Rainbow Roxy's avatar

Hey, great read as always. I've often wondered about this ssh-agent and tmux issue. It's truly amazing how you built such a cleaver fix for it!

Neural Foundry's avatar

Really elegant write-up on the async migration path. The tokio choice makes total sense here given the event-driven nature of socket proxying, and the fact that signal handling became trivial is such a hidden win. I've been bitten by similar issues when dealing with forwarding sockets in CI piplines where tmux sessions would just hang randomly. The stable socket path at /tmp is way cleaner than symlinking hacks I've seen before.

Justin's avatar

I did something similar years ago by having non-login shells symlink the socket exposed at $SSH_AUTH_SOCKET to a known location and then re-export $SSH_AUTH_SOCKET to point to the symlink. Along with some aliases to restart the agent if needed and automatically starting ssh-agent in login shells, it worked well with screen. But I haven't needed the use case since moving to tmux, not sure if it's still as smooth. I will have to look into your solution next time I need smooth agent forwarding. You're up to 42 stars on Github!

Julio Merino's avatar

Yeah, the idea of using symlinks came up as well when I first did this and my peers claimed "it'll be easier!" but then... when the session owning the symlink target disconnects, the symlink breaks and you have to somehow re-detect a different one to point it to... so how does that happen? And who triggers the re-pointing? :P

Ah, and the 42 stars... the project already had accumulated 40 over the last two years. They are not the result of today's post, but those 40 are what told me that there does seem to be some interest in this!

foo borker's avatar

a shell wrapper around screen or tmux creates a fresh socket, updates the symlink to point to the new target, and runs screen/tmux with appropriate values for environment variables. I've used this at $work for years

Mykola Dzham's avatar

I didn't even have a wrapper. I had it directly in remote .profile something like this:

```

SSH_AUTH_SOCK_STABLE=~/.ssh/auth_sock

if [ -n "$SSH_AUTH_SOCK" -a "$SSH_AUTH_SOCK" != "SSH_AUTH_SOCK_STABLE" ] ; then

ln -sf "SSH_AUTH_SOCK" "SSH_AUTH_SOCK_STABLE"

export SSH_AUTH_SOCK="$SSH_AUTH_SOCK_STABLE"

fi

```

Yes it doesn't work well when you have multiple concurrent connections.

Julio Merino's avatar

> Yes it doesn't work well when you have multiple concurrent connections.

OK, so it does something, but it doesn't solve the problem I had and that ssh-agent-switcher solves.