34

Summary: I'm trying to figure out why my tmux session dies when I disconnect from ssh

Details:

I have tmux installed on an Arch Linux system. When I start a tmux session I can detach from it and then attach again while the ssh session is active. But if I end my ssh session then the tmux session gets killed.

I know this is not the normal behavior because I have other system where the tmux session continues running even if the ssh session is ended and I can attach to the tmux session after establishing a new ssh connection. The system that has a problem and the one that works correctly have very similar configurations so I'm not sure what to check.

I'm running tmux version 1.9a. The system that has a problem (that I have root access for) has a Linux kernel version of 3.17.4-1 and the system that works correct has kernel version 3.16.4-1-ARCH (I don't have root on that system). I doubt that the kernel version is the source of the problem though, that's just one difference I noticed.

I thought I'd ask to see if anyone has seen a similar problem and knows of a possible solution.

The precise steps that lead to the problem are:

  1. ssh to machine
  2. run tmux to start tmux
  3. ctrl-B D to detach (at this point I could reattach with tmux attach
  4. close ssh session (at this point the tmux session is killed, I've been able to observe this when I'm logged in as root in a different terminal)
  5. reconnect with ssh and run tmux attach and I get the message no sessions and running tmux ls returns failed to connect to server: Connection refused. This makes sense because the serve is not running. What doesn't make sense to me is why it gets killed in step 4 when I disconnect from the ssh session.

strace data:

In response to one of the comments I used strace to see what systems calls the tmux server process makes. It looks like when I exit my ssh session (by typing exit or with ctrl-d) that the tmux process is being killed. Here's a snippet of the final part of the strace output.

poll([{fd=4, events=POLLIN}, {fd=11, events=POLLIN}, {fd=6, events=POLLIN}], 3, 424) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=1, si_uid=0} ---
sendto(3, "\17", 1, 0, NULL, 0)         = 1
+++ killed by SIGKILL +++

I compared this with a different system where tmux works properly and on that system the tmux process continues running even after I exit. So the root cause appears to be that the tmux process is being terminated when I close the ssh session. I'll need to spend some time troubleshooting this to figure out why, but I thought I would update my question since the strace suggestion was useful.

  • to be sure, please describe step by step : I assume you ssh, start a tmux session, detach from the session, and close the shh : when you ssh again, you don t have any way to re join the tmix session? ie, the session is no longer running? – Olivier Dulac Dec 04 '14 at 18:18
  • @OlivierDulac yes your assumption is correct. I've also edited my question to include these details. – Gabriel Southern Dec 04 '14 at 18:47
  • how do you close the ssh session? and you could attach a strace to the pid of tmux and another to the pid of the sshd, to see if it receives something when you close the ssh connection (very verbose, redirect to a file) – Olivier Dulac Dec 05 '14 at 08:53
  • @OlivierDulac thanks for the suggestion. I've updated the question with info from strace. It looks like the tmux server process is getting killed when I end the ssh session. I don't think this is supposed to happen, so I need to figure out why it is happening. – Gabriel Southern Dec 05 '14 at 22:52
  • Start tmux with verbose logging enabled and see if anything is printed to the log when you disconnect. Also, what is the TERM on the remote machine in and out of tmux? – jasonwryan Dec 05 '14 at 23:08
  • Anything exotic in .tmux.conf? A crazy idea, but does screen do the same, with "autodetach on" in your .screenrc? That would imply that some external watcher is sending the kill signal.

    ~$ tmux show-options -g | grep tach destroy-unattached off detach-on-destroy on

    – Ian McGowan Dec 10 '14 at 02:01
  • @jasonwryan thanks for the suggestion. I didn't see anything noteworthy when running with verbose logging. The TERM is xterm out of tmux and screen-256color in tmux. – Gabriel Southern Dec 10 '14 at 05:42
  • @IanMcGowan there's nothing exotic in the .tmux.conf file. I don't have screen installed right now, but I'll try that later. But I am starting to suspect that systemd is sending a signal to the tmux process. So I don't know if it's a tmux problem or some other configuration in my system. I've also posted to the Arch Linux forum asking about this (https://bbs.archlinux.org/viewtopic.php?pid=1482809). It's not a high priority for me, but it would be nice to fix so I appreciate the suggestions. – Gabriel Southern Dec 10 '14 at 05:53
  • Is there anything curious in your ~/.bash_logout (or shell equivalent), or a trap in your ~/.bashrc that would propagate a hangup signal into the equivalent of pkill -9 -P $$ ? Consider tracing the bash parent of the tmux process and see if it is sending a SIGKILL to tmux. – zackse Dec 22 '14 at 20:47
  • @Gabriel Before I award the bounty to mirabilos, did his answer solve your issue? – eyoung100 Dec 26 '14 at 18:08
  • @eyoung100 I'm traveling right now so I was planning to look at the answers/comments once I got back. I hadn't even noticed there was a bounty for the question. I don't want to try to change my ssh settings till I get back because I don't have any other way to access the system remotely in case there's a problem. The answer sounds like it will fix the problem, but I won't be able to check till Jan 2. – Gabriel Southern Dec 27 '14 at 00:36
  • Also related: https://unix.stackexchange.com/questions/490267/prevent-logoff-from-killing-tmux-session – Jonathan Jun 23 '19 at 23:28

5 Answers5

23

Theory

Some init systems including systemd provide a feature to kill all processes belonging to the service. The service typically starts a single process which that creates more processes by forking and those processes can do that as well. All such processes are typically considered part of the service. In systemd this is done using cgroups.

In systemd, all processes belonging to a service are killed when the service is stopped by default. The SSH server is obviously part of the service. When you connect to the server, SSH server typically forks and the new process handles your SSH session. By forking from the SSH session process or its children, other server side processes are started, including your screen or tmux.

Killmode and socket activation

The default behavior can be changed using the KillMode directive. The upstream project doesn't AFAIK include any .service files and so those vary by distribution. There are typically two ways to enable SSH on your system. One is the classic ssh.service that maintains a long running SSH daemon listening on the network. The other is via socket activation handled by the ssh.socket that in turn starts sshd@.service which only runs for a single SSH session.

Solutions

If your processes get killed at the end of the session, it is possible that you are using socket activation and it gets killed by systemd when it notices that the SSH session process exited. In that case there are two solutions. One is to avoid using socket activation by using ssh.service instead of ssh.socket. The other is to set KillMode=process in the Service section of ssh@.service.

The KillMode=process setting may also be useful with the classic ssh.service, as it avoids killing the SSH session process or the screen or tmux processes when the server gets stopped or restarted.

Future notes

This answer apparently gained a level of popularity. While it worked for the OP it might happen that it doesn't work for someone in the future due to systemd-logind development or configuration. Please check documentation on logind sessions if you experience behavior different from the description in this answer.

13

I was having the same problem with tmux and screen on Ubuntu 16.04 (kde neon). When the ssh session was disconnected screen / tmux was terminated.

long story short, systemd changed their default setting to killuserprocess=yes so after leaving a ssh session every process created by it will be terminated.

Easy fix (after hours of trying) run screen/tmux using this command

For screen

systemd-run --scope --user screen

for Tmux

systemd-run --scope --user tmux

You can create an alias to make it easier

alias tmux= "systemd-run --scope --user tmux"

  • -bash: systemd-run: command not found on Red Hat Enterprise Linux Server release 6.8 (Santiago). – gerrit Nov 14 '16 at 19:49
  • Does this work when I have not got root? – gerrit Nov 14 '16 at 20:42
  • 1
    I noticed the undesired tmux/screen killing behavior does not happen on Ubuntu 18.04 LTS, only 16.04. – Sysfu Aug 04 '18 at 17:11
  • Note that this only works when you have any other login session active, as soon as you logout the last session, all processes started in a separate scope like this will still be killed. This can be prevented by enabling lingering (run loginctl enable-linger, only needs to be done once). See https://www.freedesktop.org/software/systemd/man/systemd-run.html#Examples (example 5) for more details. – Matthijs Kooijman Jul 03 '20 at 08:59
  • Still fails for me. sudo loginctl enable-linger, then systemd-run --scope --user tmux gives
    Job for run-r835c0bf5a0014105adf82bf21dd95434.scope failed.
    journalctl -xe gives
    run-r835c0bf5a0014105adf82bf21dd95434.scope: Failed to add PIDs to scope's control group: Permission denied
    run-r835c0bf5a0014105adf82bf21dd95434.scope: Failed with result 'resources'.
    – Tino May 02 '21 at 14:49
  • Perhaps there is a solution for this problem but I cannot test currently. The machine is ~100km away and 802.1x is a bit fragile there, such that the machine sometimes does not get back into the network without manual intervention (this is: unplug+replug network cable. AFAICS it's a Cisco bug introduced to support some bad BIOS variants found on Windows hardware when PXE boot is required as well. A bit esoteric, but harmful combination). – Tino May 02 '21 at 15:09
  • Thank. I have the same problem that screen and tmux is terminated after ssh session end in Ubuntu 20.04. Adding the alias into .bashrc solve it. – Anh Tuan May 25 '23 at 07:57
5

Do you use systemd with socket activation for SSH?

If so, there’s a known issue with that. According to the systemd proponents, this is actually a feature – systemd kills all processes spawned by a session when the session terminates. (I can see that being useful, but in the GNU screen, or tmux, case, you definitely don’t want that ☺ nor in most other cases where users may run background processes, of course.)

If so, try switching from sshd.socket to sshd.service.

mirabilos
  • 1,733
  • 1
    I would say you generally don't want to use that feature for SSH logins if your users are allowed to run processes that are running after logging out. That's not specific to screen or tmux but rather to SSH (with any background processes on the server side). – Pavel Šimerda Dec 25 '14 at 09:14
  • 2
    @PavelŠimerda yes, I thought that implicit, but edited the post to make it more explicit now. – mirabilos Dec 28 '14 at 12:54
  • 4
    The links are down, answer would be more useful if it had the information from the links. – Jonathan Jan 19 '20 at 16:18
3

Another solution to this, which doesn't require moving from sshd.socket to sshd.service, is to start tmux server as a systemd service [0]. This way, the tmux server is already running when you SSH into the server, instead of spawned by the tmux command in SSH, thus won't be killed.

[0] https://wiki.archlinux.org/index.php/tmux#Autostart_with_systemd

Song Gao
  • 131
2

I found the following to work from https://pastebin.com/2cifCXGk (answer copied from this reference).

Create the file /etc/systemd/system/tmux@.service with the contents:

[Unit]
Description=Start tmux in detached session
Documentation=man:tmux(1)

[Service] Type=forking User=%I ExecStart=/usr/bin/tmux new-session -s %u -d ExecStop=/usr/bin/tmux kill-session -t %u

[Install] WantedBy=multi-user.target

And then enable the service for each user:

sudo systemctl enable tmux@${USER}.service
sudo systemctl start tmux@${USER}.service
sudo systemctl daemon-reload

Alternatively, you can place this file within your systemd/User directory (without User=%I), for example ~/.config/systemd/user/tmux.service. This way the tmux service will start when you log in, unless you also enable automatic start-up of systemd user instances.

Jonathan
  • 775