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