John Baber-Lucero
John Baber-Lucero

Reputation: 2652

How do I reattach to a detached mosh session?

How do I reattach to a detached mosh session or otherwise get rid of

Mosh: You have a detached Mosh session on this server (mosh [XXXX]).

i.e. what's the mosh equivalent of

screen -D -R

or possibly

screen -wipe

Furthermore, where can this answer be found in documentation?

Upvotes: 201

Views: 93817

Answers (6)

varta
varta

Reputation: 3416

For security reasons, you can not reattach, see https://github.com/keithw/mosh/issues/394

To kill the detached session, use the PID number displayed in that message (that's the 'XXXX' part.) For example, if you see --

Mosh: You have a detached Mosh session on this server (mosh [12345]).

And can run this command:

kill 12345

Also, to close all mosh connections you can:

kill `pidof mosh-server`

Note that if you are currently connected via mosh, this last command will also disconnect you.

Upvotes: 243

Irfy
Irfy

Reputation: 9587

The answers here claiming that killing mosh-server is the only option are largely obsolete, as we can use criu and reptyr to recover and reattach arbitrary processes.

Not to mention that nowadays we can kill -USR1 mosh-server to only kill detached sessions in a clean and safe way, without resorting to unsafe who output or cumbersome commands to avoid killing our own session.

Next to the criu answer from Michael R. Hines, there is the slightly more "light-weight" reptyr which can be used to reattach processes started by mosh-server (i.e. not the mosh-server itself). I typically use

pstree -p <mosh-server PID>

to list the tree of processes under the detached mosh-server, and then

reptyr PID

to reattach the desired process to my current terminal. After repeating the procedure for all processes I care about, I

kill -USR1 <mosh-server PID>

whereas I take care to only kill sessions I know are mine (shared system).

Upvotes: 7

studgeek
studgeek

Reputation: 14910

As @varta pointed out, the mosh owners are very against reattaching from different clients for security reasons. So if your client is gone (e.g. you restarted your laptop) your only option is to kill the sessions.

To kill only detached sessions you can use the following line (which I have as an alias in my .bashrc).

who | grep -v 'via mosh' | grep -oP '(?<=mosh \[)(\d+)(?=\])' | xargs kill

That command depends on the fact that who lists connected users including mosh sessions, only attached mosh sessions have "via mosh", and that mosh sessions have their pid in square brackets. So it finds the pids for just the detached mosh sessions and passes them to kill using xargs.

Here is an example who result for reference:

$ who
theuser    pts/32       2018-01-03 08:39 (17X.XX.248.9 via mosh [193891])
theuser    pts/17       2018-01-03 08:31 (17X.XX.248.9 via mosh [187483])
theuser    pts/21       2018-01-02 18:52 (mosh [205286])
theuser    pts/44       2017-12-21 13:58 (:1001.0)

An alternative is to use the mosh-server environment variable MOSH_SERVER_SIGNAL_TMOUT. You can set it to something like 300 in your .bashrc on the server side. Then if you do a pkill -SIGUSER1 mosh-server it will only kill mosh-servers that have not been connected in the last 300 seconds (the others will ignore the SIGUSER1). More info in the mosh-server man page. I am using the command above because, once aliased, it seems simpler to me.

Note, as mentioned by @Annihilannic, if you are using tmux/screen inside your mosh sessions then those tmux/screen sessions are still around after you kill the mosh sessions. So you can still attach to them (so you really don't lose much by killing the mosh sessions themselves).

Upvotes: 11

007
007

Reputation: 441

I realize this is an old post, but there is a very simple solution to this, as suggested by Keith Winstein, mosh author, here: https://github.com/mobile-shell/mosh/issues/394

"Well, first off, if you want the ability to attach to a session from multiple clients (or after the client dies), you should use screen or tmux. Mosh is a substitute (in some cases) for SSH, not for screen. Many Mosh users use it together with screen and like it that way."

Scenario: I'm logged into a remote server via mosh. I've then run screen and have a process running in the screen session, htop, for example. I lose connection (laptop battery dies, lose network connection, etc.). I connect again via mosh and get that message on the server,

Mosh: You have a detached Mosh session on this server (mosh [XXXX]).

All I have to do is kill the prior mosh session

kill XXXX

and reattach to the screen session, which still exists.

screen -r

Now, htop (or whatever process was running) is back just as it was without interruption.This is especially useful for running upgrades or other processes that would leave the server in a messy, unknown state if suddenly interrupted. I assume you can do the same with tmux, though I have not tried it. I believe this is what Annihilannic and eskhool were suggesting.

Upvotes: 34

Alexander Burmak
Alexander Burmak

Reputation: 171

As an addition to Varta's answer, I use the following command to close all mosh connections except the current one:

pgrep mosh-server | grep -v $(ps -o ppid --no-headers $$) | xargs kill

Upvotes: 17

Michael Galaxy
Michael Galaxy

Reputation: 1283

To my amazement, I used CRIU (https://criu.org) to checkpoint and restart a mosh client and it worked.

Shocking.

Find your mosh-client's PID:

$ ps -ef | grep mosh

Then, install CRIU according to their instructions.

Then, checkpoint it like this:

$ mkdir checkpoint

$ sudo ./criu dump -D checkpoint -t PID --shell-job

Then, restore it:

$ sudo ./criu restore -D checkpoint --shell-job

And, there it is. Your mosh client is back.

One thing to note, however, is that if your laptop reboots (which is the whole point of what we're trying to protect against), mosh uses a monotonic clock to track time on the client side, which doesn't work across reboots. This will NOT work, however, if your laptop just flat out crashes it won't work because mosh sequence numbers will be out of sync with the version that was checkpointed (the binary will resume, but communication will stop).

In order to fix this, you need to tell mosh to stop doing that and download the mosh source code. Then, edit this file:

cd mosh

vim configure.ac

Then, search for GETTIME and comment out that line.

Then do:

autoreconf # or ./autogen.sh if you've just cloned it for the first time

./configure

make

make install

After that, your CRIU-checkpointed mosh client sessions will survive reboots.

(Obviously you'd need to write something to perform the checkpoints regularly enough to be useful. But, that's an exercise for the reader).

Upvotes: 37

Related Questions