SSH сессии зависают при выключении / перезагрузке

13

У меня есть сервер, на котором запущены Debian и sshd, и в случае, если мне нужно перезагрузить сервер, мой SSH-сеанс зависает на стороне клиента до истечения времени ожидания TCP. Я предполагаю, что это потому, что когда sshdон завершается, он явно не закрывает открытые сеансы SSH с хостом. Что я должен сделать, чтобы sshdсначала отключить всех, а затем завершить себя как обычно? Пока что я не вижу параметра, man sshd_configкоторый связан с поведением выключения.

вечерний звон
источник
1
Когда ничего не помогает, вы можете в любое время убить SSH-клиента, нажав [Enter] [~] [.]. Объяснение того, как на самом деле решить вашу проблему, также подходит.
n.st

Ответы:

32

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

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

Но, конечно, есть более точное решение (как это должно быть сделано) systemd-logind.
systemd-logindотслеживает активные пользовательские сессии (локальные и SSH) и назначает все процессы, порожденные в них, так называемым «срезами». Таким образом, когда система выключается, systemd может просто SIGTERM все внутри пользовательских срезов (что включает в себя разветвленный процесс SSH, который передает определенный сеанс), а затем продолжать закрывать службы и сеть.

systemd-logindтребуется модуль PAM для получения уведомлений о новых сеансах пользователя, и вам необходимо dbusиспользовать его loginctlдля проверки его состояния, поэтому установите оба из них:

apt-get install libpam-systemd dbus

Убедитесь, что на /etc/ssh/sshd_configсамом деле вы собираетесь использовать модуль с UsePAM yes.

n.st
источник
Хорошо, цель достигнута, и спасибо за объяснение. (Хотя мне нужен какой-то способ управления зависимостями для завершения работы, чтобы SIGTERM все сначала выполнял, когда мог завершить свою работу, это может быть многоуровневым решением.)
Vesper
По какой-то причине я не был уведомлен об ответе при посещении только StackOverflow. Weird.
Веспер
1
Итак, для краткости, просто чтобы сбрить несколько секунд при выключении, мы должны установить целую загрузку дерьма, чтобы правильно завершить наши соединения? Шутки в сторону ? Это становится ошибочным. Мы обречены.
Leucos
3
Обратите внимание, что первая перезагрузка после установки libpam-systemd и dbus по-прежнему будет приводить к зависанию сеанса SSH. Чтобы избежать этого, вместо этого rebootвыполните a, shutdown -rкоторое по умолчанию имеет задержку в 1 минуту, оставляя вам время для закрытия сеанса SSH.
Mivk
9

Это то, что вам нужно установить на стороне клиента, а не на стороне сервера. Изменить ваш, ~/.ssh/configчтобы содержать

ServerAliveInterval 15
ServerAliveCountMax 5

Это означает, что после 15 секунд бездействия ваш клиент отправит сообщение на сервер. Если он не получит никакого ответа, он попытается снова до 5 раз, а когда он все еще не получит ответа, он закроет сеанс.

Дженни Д
источник
2
Это приведет к задержке в 75 секунд до того, как клиент ssh сообщит о смерти сервера. Правильно?
Веспер
1
Да, и вы можете настроить параметры, чтобы сократить время ожидания.
Теро Килканен
Это решило проблему для меня. Такая раздражающая проблема.
Джастин Андруск
5

О таком поведении сообщается об этой ошибке Debian : вам нужно только правильно настроить сценарии завершения работы, поставляемые с пакетом, потому что автоматически они не копируются по умолчанию:

cp /usr/share/doc/openssh-client/examples/ssh-session-cleanup.service /etc/systemd/system/
systemctl  enable ssh-session-cleanup.service
Rfraile
источник
1

Вы можете указать параметры, о которых говорила Дженни Д. в своем ответе, только для одной команды ssh, например:

ssh -t -o ServerAliveInterval=1 -o ServerAliveCountMax=1 user@host sudo poweroff

если вы делаете это часто, вы можете написать это.

Диего Медалья
источник
0

У меня работает с lshd. Таким образом, решение будет

apt install lsh-server
apt remove openssh-server
Бог
источник
0

к сожалению serverfault не позволил мне ответить по причине потока слишком мало пунктов с годами. Но мне не нужно спамить в других блогах, чтобы получить разблокировку ^^ ... так что выделенный ответ:

Как сказал Рфрейл

cp /usr/share/doc/openssh-client/examples/ssh-session-cleanup.service /etc/systemd/system/
systemctl  enable ssh-session-cleanup.service

работает. Чтобы использовать его без перезагрузки экземпляра / сервера, вы должны выполнить дополнительные задачи:

systemctl daemon-reload
systemctl start ssh-session-cleanup.service

поэтому служба зарегистрирована и запущена, и systemd необходимо остановить ее для перезагрузки / выключения.

Reiner030
источник
Так ты просто повторяешь другой ответ?
RalfFriedl
Нет? Я использовал только 2 строки в качестве ссылки для верхнего ответа, потому что я пока не могу ответить так, как написано. Я добавил необходимые шаги, чтобы использовать его без перезагрузки. Это может быть дано также в другой ветке вопросов, но я не проверил.
Reiner030