1

Я часто обнаруживал, что нужно быстро закрыть ноутбук, открыв несколько удаленных сессий ssh. И после пробуждения я нашел несколько мертвых снарядов, ведьма не была закрыта:/

Как я могу заставить чистый выход удаленных ssh-сессий на hibernate/suspend/shutdown?

PS на Gentoo и Ubuntu

2 ответа2

2

Убейте клиентов ssh перед переходом в спящий режим или приостановкой.

В Ubuntu lucid сценарии приостановки находятся в /etc/pm/sleep.d . Документация находится на странице руководства pm-action(8) . Добавьте /etc/pm/sleep.d/20_dariusz_kill_ssh содержащий что-то вроде

#!/bin/sh
case $1 in
  suspend|hibernate) pkill -x ssh;;
esac

Я не знаю, где находятся соответствующие скрипты на Gentoo. Возможно, вы захотите уточнить, чтобы исключить ssh для localhost, если вы когда-нибудь это сделаете.

Для завершения работы вам не нужно ничего делать, обычные сценарии завершения уже убивают клиентов ssh (поэтому они закрывают соединение).

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

Вот подтверждение концепции (полностью не проверено). В /etc/network/if-down.d/ssh-sessions-record (расположение Ubuntu) запишите IP-адрес, связанный с исчезающим интерфейсом, и время, когда интерфейс вышел из строя:

#!/bin/sh
{
  echo OLD_IP=$(ifconfig "$IFACE" | sed -n 's/^ *inet addr:\([0-9.]\+\).*/\1/p')
  echo OLD_DATE=$(date +%s)
} >"/var/run/$IFACE.ssh-sessions-record"

В /etc/network/if-up.d/ssh-sessions-record ssh-соединения, которые проходили через этот сетевой интерфейс, но только в том случае, если IP-адрес изменился или прошло достаточно времени для того, чтобы время ожидания сервера истекло:

#!/bin/sh
if [ -e "/var/run/$IFACE.ssh-sessions-record" ]; then
. "/var/run/$IFACE.ssh-sessions-record"
NEW_IP=$(ifconfig "$IFACE" | sed -n 's/^ *inet addr:\([0-9.]\+\).*/\1/p')
NEW_DATE=$(date +%s)
if [ "$NEW_IP" != "$OLD_IP" ] || [ $(($NEW_DATE-$OLD_DATE)) -ge 300 ]; then
  ## Kill all ssh processes that were connecting through $OLD_IP
  for pid in $(lsof -Fp -n -i "tcp@$OLD_IP"); do
    if [ "$(ps -$pid -o comm=)" = "ssh" ]; then
      kill $pid
    fi
  done
fi
0

Поскольку никто больше не наносил удар по этому, я попробую. Если ничего другого, возможно, это подтолкнет кого-то еще.

У меня нет ноутбука или актуального Gentoo, так что, может быть, Ubuntu подойдет. Мой текущий рабочий стол - Ubuntu 10.04 ... вы не упомянули свою версию - надеюсь, она близка.

В любом случае, я бы посмотрел на конфигурацию Upstart (или /etc /inittab, если вы не используете Upstart). Убедитесь, что вы используете upstart:

# dpkg --list | grep upstart
ii  upstart          0.6.5-7     event-based init daemon

Очевидно, что если вы не видите ничего похожего, скорее всего, вы используете init. Оба инструмента (upstart и init) предназначены для работы при запуске, завершении работы и т.д. (Т. Е. События).

В случае с Upstart, перейдите в каталог /etc /init и посмотрите там файлы. Так как я не на ноутбуке, у меня нет функции "гибернации или приостановки", но держу пари, что у вас есть. Попробуйте некоторые greps там, чтобы увидеть:

/etc/init# egrep -i "suspend|hibernate" *

Тем не менее, мой файл control-alt-delete.conf кажется мне чем-то интересным. Если я посмотрю на это, я увижу:

/etc/init# cat control-alt-delete.conf 
# control-alt-delete - emergency keypress handling
#
# This task is run whenever the Control-Alt-Delete key combination is
# pressed, and performs a safe reboot of the machine.

description     "emergency keypress handling"
author          "Scott James Remnant <scott@netsplit.com>"

start on control-alt-delete

task
exec shutdown -r now "Control-Alt-Delete pressed"

Могу поспорить, что вы можете настроить эту последнюю строку для сценариев некоторых выходов из системы SSH или чего угодно. Вы хотели бы обновить (или создать) правильный файл конфигурации. Я предполагаю, что при установке на ноутбуке будет что-то конкретное для hibernate/suspend/etc. Глядя на некоторые другие файлы (например, apport.conf), я вижу, что файлы конфигурации фактически поддерживают встроенные в них скрипты.

Если вы имеете дело с init, а не с upstart, попробуйте посмотреть на строки /etc /inittab, например:

# What to do when the power fails/returns.
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop
...
# What to do when CTRL-ALT-DEL is pressed.
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

Как только вы найдете идеальное место, основываясь на вашей конфигурации, вам будет не сложно собрать вместе bash-скрипт, который может их убить или тому подобное.

Простой пример:

#!/bin/bash
kill -9 `ps -ef | grep "[s]sh " | awk '{print $2}'`

Я надеюсь, что это по крайней мере дает вам отправную точку. Может быть, есть более простой способ, но я не использую ноутбуки достаточно, чтобы знать.

Почти забыл: если вы сделаете что-нибудь из этого, вам, вероятно, потребуется отослать init, чтобы он вступил в силу:

# kill -HUP 1

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .