Назад | Перейти на главную страницу

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

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

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

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

Но есть, конечно, более изящное решение (как это «предполагается» делать): 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.

Это то, что вам нужно установить на стороне клиента, а не на стороне сервера. Отредактируйте свой ~/.ssh/config содержать

ServerAliveInterval 15
ServerAliveCountMax 5

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

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

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

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

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

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

У меня работает с lshd. Итак, решение было бы

apt install lsh-server
apt remove openssh-server

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

Как упоминал Rfraile

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 необходимо остановить ее для перезагрузки / завершения работы.