Sessões de shell remotas logout no modo de hibernação

1

Encontrei muitas vezes para fechar o laptop rapidamente, com algumas sessões ssh remotas abertas. E depois do despertar eu encontrei algumas conchas mortas, a bruxa não foi fechada: /

Como posso forçar a saída limpa de ssh-sessions remotas no hibernate / suspend / shutdown?

PS No gentoo e no ubuntu

    
por canni 07.09.2010 / 11:20

2 respostas

1

Mate os clientes ssh antes de hibernar ou suspender.

No Ubuntu lúcido, os scripts de suspensão estão em /etc/pm/sleep.d . A documentação está na página pm-action(8) man. Adicione /etc/pm/sleep.d/20_dariusz_kill_ssh contendo algo como

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

Eu não sei onde estão os scripts correspondentes no Gentoo. Você pode querer refinar para excluir ssh para localhost se você fizer isso.

Para o desligamento, você não precisa fazer nada, os scripts normais de desligamento já matam os clientes ssh de forma limpa (assim eles fecham a conexão).

Note que deixar a sessão aberta não é um grande problema. Tudo o que você ganha, matando-o cedo, é recuperar alguns recursos no servidor ssh e alguns firewalls no caminho. Então você pode matar os clientes no currículo, e somente se a conexão for perdida. Se você escolher essa abordagem, acho que o lugar certo está nos scripts de rede: registre sessões ssh ativas quando a rede cair e, possivelmente, as mate quando a rede voltar.

Aqui está uma prova de conceito (completamente não testada). Em /etc/network/if-down.d/ssh-sessions-record (local do Ubuntu), registre o endereço IP associado à interface que está desaparecendo e o tempo que a interface caiu:

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

Em /etc/network/if-up.d/ssh-sessions-record , elimine as conexões ssh que passaram por essa interface de rede, mas apenas se o endereço IP foi alterado ou se decorreu tempo suficiente que o servidor pode ter expirado:

#!/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.]\+\).*//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
    
por 07.09.2010 / 20:47
0

Já que ninguém mais tentou isso, vou tentar. Se nada mais, talvez isso estimule outra pessoa.

Eu não tenho um laptop ou um Gentoo atual à mão, então talvez o Ubuntu seja suficiente. Meu desktop atual é o Ubuntu 10.04 ... você não mencionou sua versão - esperamos que seja próximo.

De qualquer forma, eu olharei para a configuração do Upstart (ou / etc / inittab se você não estiver usando o Upstart). Verifique se você está executando o upstart por:

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

Obviamente, se você não vir algo parecido, provavelmente está usando o init. Ambas as ferramentas (upstart e init) são projetadas para fazer coisas na inicialização, desligamento, etc (ou seja, eventos).

No caso do Upstart, vá para o diretório / etc / init e dê uma olhada nos arquivos lá. Como não estou em um laptop, não tenho a função "hibernar ou suspender", mas aposto que sim. Tente alguns greps para ver:

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

No entanto, meu arquivo control-alt-delete.conf me parece interessante. Se eu espiar, vejo:

/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 <[email protected]>"

start on control-alt-delete

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

Eu estaria disposto a apostar que você poderia personalizar essa última linha para fazer o script de alguns logoffs SSH, ou apenas sobre qualquer coisa que você gosta. Você deseja atualizar (ou criar) o arquivo de configuração adequado. Eu estou supondo que uma instalação de laptop terá algo específico para hibernar / suspender / etc. Olhando para alguns dos outros arquivos (como o apport.conf), vejo que os arquivos de configuração realmente suportam scripts embutidos neles.

Se você está lidando com o init, em vez do upstart, tente ver as linhas / etc / inittab como:

# 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

Uma vez que você localizou o local ideal, com base na sua configuração, não seria muito difícil reunir um script bash que poderia matá-los ou algo parecido.

Exemplo simples:

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

Espero que isso, pelo menos, lhe dê um ponto de partida. Talvez haja uma maneira mais fácil, mas eu não uso laptops o suficiente para saber.

Quase esqueci: supondo que você faça algo disso, provavelmente precisará devolver o init para que ele entre em vigor:

# kill -HUP 1
    
por 07.09.2010 / 20:17