Сессия tmux убита при отключении от ssh

23

Резюме : я пытаюсь выяснить, почему мой сеанс tmux умирает, когда я отключаюсь от ssh

Детали :

Я установил tmux в систему Arch Linux. Когда я запускаю сеанс tmux, я могу отсоединиться от него, а затем снова подключиться, пока сеанс ssh активен. Но если я закончу свою сессию ssh, то сессия tmux будет уничтожена.

Я знаю, что это не нормальное поведение, потому что у меня есть другая система, в которой сеанс tmux продолжает работать, даже если сеанс ssh завершен, и я могу подключиться к сеансу tmux после установления нового соединения ssh. Система, в которой возникла проблема, и система, которая работает правильно, имеют очень похожие конфигурации, поэтому я не уверен, что проверять.

Я использую tmux версии 1.9a. Система, в которой возникла проблема (для которой у меня есть доступ с правами root), имеет версию ядра Linux 3.17.4-1, а система, которая работает правильно, имеет версию ядра 3.16.4-1-ARCH (у меня нет root на этом система). Я сомневаюсь, что версия ядра является источником проблемы, но я заметил только одно отличие.

Я решил спросить, видел ли кто-нибудь похожую проблему и знает ли ее решение.

Точные шаги, которые приводят к проблеме:

  1. SSH к машине
  2. беги tmuxчтобы запустить tmux
  3. ctrl-B D отсоединить (в этот момент я мог прикрепить с tmux attach
  4. закрыть сессию ssh (на данный момент сессия tmux прервана, я смог наблюдать это, когда я вошел в систему как root на другом терминале)
  5. переподключитесь с ssh и запустите, tmux attachи я получаю сообщение no sessionsи запускаю tmux lsвозвраты failed to connect to server: Connection refused. Это имеет смысл, потому что подача не работает. Что не имеет смысла для меня, так это то, почему он убивается на шаге 4, когда я отключаюсь от сеанса ssh.

данные страйса:

В ответ на один из комментариев я использовал strace, чтобы увидеть, какие системы вызывает процесс сервера tmux. Похоже, что когда я выхожу из сеанса ssh (набирая exitили ctrl-dнажимая), процесс tmux уничтожается. Вот фрагмент заключительной части вывода strace.

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 +++

Я сравнил это с другой системой, в которой tmux работает должным образом, и в этой системе процесс tmux продолжает выполняться даже после моего выхода. Таким образом, основной причиной является то, что процесс tmux завершается, когда я закрываю сессию ssh. Мне нужно потратить некоторое время на устранение неполадок, чтобы выяснить, почему, но я подумал, что обновлю свой вопрос, так как предложение strace было полезным.

Габриэль Южный
источник
чтобы быть уверенным, пожалуйста, опишите шаг за шагом: я предполагаю, что вы ssh, запускаете сеанс tmux, отсоединяетесь от сеанса и закрываете shh: когда вы снова запускаете ssh, у вас нет никакого способа снова присоединиться к сеансу tmix? т.е. сеанс больше не работает?
Оливье Дюлак
@OlivierDulac да, ваше предположение верно. Я также отредактировал свой вопрос, чтобы включить эти детали.
Габриэль Южный
как вы закрываете сессию SSH? и вы можете прикрепить strace к pid tmux, а другой к pid sshd, чтобы увидеть, получает ли он что-то, когда вы закрываете соединение ssh (очень многословно, перенаправить в файл)
Olivier Dulac
@OlivierDulac спасибо за предложение. Я обновил вопрос информацией от strace. Похоже, что процесс сервера tmux убивается, когда я заканчиваю сессию ssh. Я не думаю, что это должно произойти, поэтому мне нужно выяснить, почему это происходит.
Габриэль Южный
Запустите tmux с подробным ведением журнала и посмотрите, будет ли что-либо напечатано в журнале при отключении. Кроме того, что такое TERM на удаленной машине в tmux и из него?
Джейсонвриан

Ответы:

16

теория

Некоторые системы инициализации, включая systemd, предоставляют возможность уничтожать все процессы, принадлежащие сервису. Служба обычно запускает один процесс, который создает больше процессов путем разветвления, и эти процессы также могут это делать. Все такие процессы обычно считаются частью сервиса. В systemd это делается с помощью cgroups .

В systemd все процессы, принадлежащие сервису, прекращаются, когда сервис останавливается по умолчанию. Сервер SSH, очевидно, является частью службы. Когда вы подключаетесь к серверу, сервер SSH обычно разветвляется, и новый процесс обрабатывает ваш сеанс SSH. При ответвлении от процесса сеанса SSH или его дочерних элементов запускаются другие процессы на стороне сервера, включая ваш экран или tmux .

Killmode и активация сокета

Поведение по умолчанию можно изменить с помощью KillModeдирективы. В последнем проекте AFAIK нет .serviceфайлов, поэтому они различаются в зависимости от дистрибутива. Как правило, есть два способа включить SSH в вашей системе. Одним из них является классика ssh.service, поддерживающая длительное прослушивание SSH-демона в сети. Другой - через активацию через сокет, которая обрабатывается ssh.socketзапускаемой программой, sshd@.serviceкоторая выполняется только для одного сеанса SSH.

Решения

Если ваши процессы будут уничтожены в конце сеанса, возможно, вы используете активацию сокета, и он будет уничтожен systemd, когда он заметит, что процесс сеанса SSH завершился. В этом случае есть два решения. Один из них - избегать использования сокетов, используя ssh.serviceвместо ssh.socket. Другой - установить KillMode=processв Serviceразделе ssh@.service.

Этот KillMode=processпараметр также может быть полезен для классического приложения ssh.service, так как он предотвращает уничтожение процесса сеанса SSH или процессов экрана или tmux, когда сервер останавливается или перезапускается.

Будущие заметки

Этот ответ, по-видимому, приобрел уровень популярности. Хотя он работает для OP, может случиться так, что он не будет работать для кого-то в будущем из -за разработки или конфигурации systemd-logind . Пожалуйста, проверьте документацию по сеансам входа в систему, если вы испытываете поведение, отличное от описания в этом ответе.

Павел Шимерда
источник
Есть какие-то конкретные отзывы от downvoter или просто троллинга?
Павел Шимерда
3
Спасибо за подробный ответ. Переход на sshd.service устранил проблему.
Габриэль Южный
Я испытываю эту проблему в системе, использующей, initа не systemd. Но в любом случае это немного другое, см. Мой вопрос .
gerrit
5

Используете ли вы systemd с активацией сокета для SSH?

Если так, то есть известная проблема с этим . Согласно сторонникам systemd, это на самом деле особенность - systemd убивает все процессы, порожденные сеансом, когда сеанс завершается. (Я вижу, что это полезно, но в GNU screen, или tmux, в случае, вы определенно не хотите этого - и в большинстве других случаев, когда пользователи, конечно, могут запускать фоновые процессы.)

Если да, то попробуйте переключиться с sshd.socketкsshd.service .

mirabilos
источник
1
Я бы сказал, что вы, как правило, не хотите использовать эту функцию для входа в SSH, если вашим пользователям разрешено запускать процессы, которые выполняются после выхода из системы. Это не относится к screen или tmux, а скорее к SSH (с любыми фоновыми процессами на стороне сервера).
Павел Шимерда
2
@ PavelŠimerda да, я думал, что это неявно, но отредактировал пост, чтобы сделать его более явным сейчас.
Мирабилось
3

У меня была такая же проблема с tmux и экраном на Ubuntu 16.04 (kde neon). Когда сеанс ssh был отключен, screen / tmux был прерван.

Короче говоря, systemd изменил настройку по умолчанию на killuserprocess = yes, поэтому после выхода из сеанса ssh все созданные им процессы будут прерваны.

Легко исправить (после нескольких часов попыток) запустить screen / tmux с помощью этой команды

Для экрана

systemd-run --scope --user screen

для Tmux

systemd-run --scope --user tmux

Вы можете создать псевдоним, чтобы сделать его проще

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

mrbarletta
источник
-bash: systemd-run: command not foundна Red Hat Enterprise Linux Server release 6.8 (Santiago).
gerrit
Это работает, когда у меня нет рута?
gerrit
1
Я заметил, что нежелательное поведение tmux / screen kill не происходит в Ubuntu 18.04 LTS, только 16.04.
Сет
2

Другое решение этого, которое не требует перехода из sshd.socketв sshd.service, - это запуск tmuxсервера в качестве службы systemd [0]. Таким образом, tmuxсервер уже работает, когда вы запускаете SSH на сервер, а не порождается tmuxкомандой в SSH, поэтому он не будет уничтожен.

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

Сонг Гао
источник
Это работает, когда у меня нет рута?
gerrit
Да, это правильное решение. Но вы все еще хотите решить проблему с перезапуском службы SSH через сеанс SSH. :)
Павел Шимерда
Ребята, в случае, если вы используете OpenRC, я сделал initscript tmux, который делает то же самое, что и служебный файл, упомянутый в ArchWiki
Megver83
1

Лучший ответ, который я нашел, IMO, дан в Prevent Logoff from Killing tmux Session :

Это «особенность» существовала в systemdранее, но эти systemdразработчиках решили произвести изменения в значениях по умолчанию , чтобы включить параметр для прекращения дочерних процессов при выходе из сеанса.

Вы можете восстановить эту настройку в вашем logind.conf( /etc/systemd/logind.conf):

KillUserProcesses=no
Джонатан
источник