Ethan Pailes
2023-Mar-01 13:09 UTC
Uniquely Identifying the Local TTY of an SSH Connection
Hi, I'm working on a tool for persistent terminal sessions that works much like tmux, and I would like to be able to make it so that people can set things up so that when they ssh onto a remote host, they automatically connect to a persistent session based on the local terminal they are connecting from. The idea would be that users can just type `ssh my-host` if their connection drops and they will immediately be dropped back into their old session with all the context like they left it. Right now, I have two different approaches to this, both of which have some problems. The first thing I tried is setting up some config on the local machine in `~/.ssh/config` to make use of the RemoteCommand and LocalCommand options. I basically want to do the equivalent of sshing in and immediately running `tmux attach-session -t tty-1` (though for my tool the attach command obviously looks a bit different). The tricky bit is that I can't write down the name of the local tty in my RemoteCommand because it is dynamic, and I can't have my RemoteCommand derive it by itself because the RemoteCommand runs on the remote host. To work around this, what I do is have a RemoteCommand that connects to the session multiplexer and parks, occupying a single global slot, then I have a LocalCommand which is itself a nested invocation of `ssh` to connect to the remote host and inform this parked RemoteCommand about the name of the local tty. To make this a bit more concrete, the config block to make this work with my tool looks like ``` Host = your-ssh-target-name Hostname your.ssh.host.example.com RemoteCommand shpool plumbing ssh-remote-command PermitLocalCommand yes LocalCommand ssh -oPermitLocalCommand=no -oRemoteCommand="shpool plumbing ssh-local-command-set-metadata '%u@%h:%p$(tty)'" %n ``` This kinda works, but has several fairly big problems. A really obvious one is that single global parking slot which opens this protocol up to race conditions and limits the ability to quickly shell in from multiple terminals at once. The second big problem is that it requires sshing in twice to establish a connection, which means authenticating twice. This can be pretty slow depending on how exactly authentication has been set up. The second approach I have is much simpler and, except for one big issue, smoother. Instead of editing your local machine `~/.ssh/config`, you just edit the `.bashrc` on your remote machine to include the following block ``` if [[ $- =~ i ]] && [[ -n "$SSH_TTY" ]]; then shpool attach "ssh-$(basename $SSH_TTY)" fi ``` I think the equivilant for tmux is ``` if [[ $- =~ i ]] && [[ -n "$SSH_TTY" ]]; then tmux attach-session -t "ssh-$(basename $SSH_TTY)" fi ``` this works quite well, except that $SSH_TTY holds the path of the remote pty rather than the local pty, so there is nothing that ensures that you will reconnect to the same session if you ssh back into your remote machine from the same local terminal emulator. First of all, can anyone think of some obvious thing I'm missing that will make this easier? Perhaps there is some config feature of environment variable ssh sets or can be persuaded to set that I've missed. If so, apologies for the noise. If there really isn't such a feature, what do you think would be the easiest way to add support for uniquely identifying the local tty and would you be open to adding support for such a feature? I would be willing to try to contribute support if the ssh maintainers are open to it. I can think of two possible ways to uniquely identify the local tty. One way would be to add a new % format code that is available in the context of a RemoteCommand which contains the result of evaluating $(tty) on the local machine (or something semantically equivalent, it wouldn't have to actually fork a subprocess). Another way would be to just start injecting the information into the environment when sshd forks a new subprocess in a new env var called something like $SSH_LOCAL_TTY. Finally, some administrative notes: I wasn't able to sign up for this mailing list at https://lists.mindrot.org/mailman/subscribe/openssh-unix-dev because attempts to do so were met by a "Bug in Mailman version 2.1.39" page. I'd also like to pre-emptively apologize if I've accidentally sent an HTML email since I'm sending from a webmail client and this is my first attempt to send plaintext email. Thanks! - Ethan Pailes
Philipp Marek
2023-Mar-01 13:42 UTC
Uniquely Identifying the Local TTY of an SSH Connection
> if their connection drops and they will immediately be dropped back into their old session with all the context like they left it.Perhaps mosh fits your bill? Other than that, would it work to just build up the right command (tmux with args) locally in a shell script thats stored in /usr/local/bin/ssh?
Darren Tucker
2023-Mar-02 01:40 UTC
Uniquely Identifying the Local TTY of an SSH Connection
On Thu, 2 Mar 2023 at 00:12, Ethan Pailes <ethan at pailes.org> wrote: [...]> this works quite well, except that $SSH_TTY holds the path of the > remote pty rather than the local pty, so there is nothing that ensures > that you will reconnect to the same session if you ssh back into your > remote machine from the same local terminal emulator. > > First of all, can anyone think of some obvious thing I'm missing that > will make this easier? Perhaps there is some config feature of > environment variable ssh sets or can be persuaded to set that I've > missed. If so, apologies for the noise.Send the local tty name using SendEnv? You'd probably want to include some kind of host identifier so you don't get collisions if sshing in from multiple machines (although that might not matter for your use case). SendEnv variables are not accepted by default on the server side, so if you don't control the server you could maybe pack them into $TERM (which is required by the protocol for pty requests), although you'll need to unpack it on the server side before trying to use anything that cares about TERM. $ TERM="vt100 myhost:/dev/pts/0" ssh localhost Last login: Thu Mar 2 12:28:59 2023 from 127.0.0.1 $ echo $TERM vt100 myhost:/dev/pts/0> Finally, some administrative notes: I wasn't able to sign up for this > mailing list at > https://lists.mindrot.org/mailman/subscribe/openssh-unix-dev because > attempts to do so were met by a "Bug in Mailman version 2.1.39" page.I just tried that and didn't get that error, although I also haven't got the confirmation email yet. Could you please try again and if it happens again. mail me the error message off-list? -- Darren Tucker (dtucker at dtucker.net) GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA Good judgement comes with experience. Unfortunately, the experience usually comes from bad judgement.
Possibly Parallel Threads
- Uniquely Identifying the Local TTY of an SSH Connection
- [Bug 2558] New: Add RemoteCommand option to ssh client
- Uniquely Identifying the Local TTY of an SSH Connection
- Feature request/EOI: Match interactive config?
- Uniquely Identifying the Local TTY of an SSH Connection