mantém a conexão de encaminhamento de porta SSH viva

3

Estou fazendo um encaminhamento de porta permanente via SSH. É basicamente

while true; do
        ssh <somewhere> \
                -R <dst-port>:localhost:<src-port> \
                -N -n -o ExitOnForwardFailure=yes
        sleep 10
done

No entanto, isso não é muito confiável. Às vezes, a porta não é encaminhada de todo (não tenho certeza se a conexão está corretamente ativa, mas eu posso ver o processo no cliente e ele já está funcionando por várias horas), às vezes a conexão certamente não está mais ativa (porque a interface de rede está inativa), mas leva muito tempo (às vezes até 30 a 60 minutos) para o tempo limite.

Como posso tornar isso mais confiável? Eu quero ter um tempo limite de talvez um minuto.

Acabei de encontrar esta questão muito relacionada / semelhante . No entanto, a primeira resposta indica que ExitOnForwardFailure deve resolvê-lo, mas eu já o tenho e não o faço (agora posso ver o processo ssh em execução com essa opção, mas a porta não é encaminhada).

    
por Albert 07.08.2012 / 18:53

5 respostas

1

Esta versão envia freqüentemente alguns dados para o servidor. Se a conexão tiver morrido, o tubo deverá quebrar mais cedo ou mais tarde.

while true; do
        { while true; do echo echo ping; sleep 10; done } | \
        ssh <somewhere> \
                -R <something> \
                -o ExitOnForwardFailure=yes \
                >/dev/null
        sleep 10
done
    
por 10.08.2012 / 12:16
4

Eu coloquei isso no arquivo config do cliente SSH:

ServerAliveInterval = 60
ServerAliveCountMax = 3

Como alternativa, essas opções podem ser passadas na linha de comando ssh via -o .

Alguns clientes podem não ter esse controle de configuração, como os vários clientes escassos para dispositivos móveis. Nesse caso, ainda é possível configurá-lo globalmente em cada servidor conectado, o que obviamente requer privilégios na máquina do servidor. A implementação do OpenSSHD parece não ter como os usuários personalizarem os parâmetros do servidor (nenhum arquivo ~/.ssh/sshd_config é lido onde os parâmetros selecionados podem ser personalizados do lado do servidor).

    
por 07.12.2012 / 21:24
3

Eu uso o autossh assim em minha máquina de trabalho para configurar o desenvolvimento remoto da web:

autossh -M0 -N -R \*:8080:localhost:80 -R \*:5051:localhost:22 home

O autossh é um programa que continua reiniciando o ssh se ele travar ou parar por qualquer razão diferente de "kill -9". O comando acima configura dois túneis: um para encaminhar a porta 80 em minha máquina de trabalho para 8080 em minha máquina doméstica, o outro encapsula o servidor ssh em minha máquina de trabalho para minha máquina doméstica. O * na frente da porta faz este trabalho com qualquer nome de host, não apenas localhost. Talvez seja necessário definir "GatewayPorts yes" no seu sshd_config para que isso funcione. Eu tenho hosts em ~ / .ssh / config e / etc / hosts em minha máquina doméstica para tornar isso ainda mais transparente. Para outros sistemas, é necessário usar o ProxyCommand ( link ), mas não tenho o host que uso este comando com ligado no momento para agarrá-lo.

~ / .ssh / config:

Host work
    hostname localhost
    port 5051

Então é só

autossh -M0 -t home 'ssh work'

de qualquer host para se conectar.

    
por 07.08.2012 / 20:29
0

Você pode tentar alterar seu comando SSH para:

ssh SOMEWHERE -R DSTPORT:localhost:SRCPORT -n -o ExitOnForwardFailure=yes \
    "while true; do echo ping; sleep 10; done" >/dev/null

Isso faz com que uma pequena quantidade de dados seja enviada pela conexão TCP a cada 10 segundos (sinta-se à vontade para alterar esse período). Isso pode ser suficiente para manter a conexão ativa.

    
por 07.08.2012 / 20:09
0

Como citado anteriormente por Kaz, a conexão não parece exigir nenhum tráfego explícito para se manter vivo. Algo como:

ssh you@there 'read ANYTHING' < $PIPE

apenas funciona. $ PIPE é um pipe nomeado para o qual você vai escrever quando terminar.

Bem, vamos ser explícitos - o $ PIPE é mais complexo do que 'ler QUALQUER COISA' e vale a pena um exemplo detalhado. Aqui está o código que eu uso para criar uma máquina em uma rede que não consigo acessar diretamente:

p_user=myself
p_bridge=me@there
p_host=192.168.xxx.yyy
p_port=9999

p_size=100%      # or: p_size=1280x1024
p_trace=stderr   # or: p_trace=null

s_trace() {  echo "$*" > /dev/$p_trace; }

PIPE=$TEMP/${0##*/}.$$
mkfifo $PIPE.0
mkfifo $PIPE.1

trap 'rm $PIPE.0 $PIPE.1' 0

# ----------------------------------------------------
ssh $p_bridge \
    -L $p_port:$p_host:3389 \
    'read CONNECT; date; read QUIT' \
  < $PIPE.1 \
  > $PIPE.0 \
  & 
# ----------------------------------------------------

# note: "type -p" is somehow required with xinit
# note: "-p -" reads password from stdin
DESKCMD="$(type -p rdesktop) -P -z -u $p_user -p - -g $p_size localhost:$p_port"

{
  echo connect >&3; read CONNECT <&4; s_trace "CONNECTED: $CONNECT"
  $DESKCMD -f    # or: xinit $DESKCMD -- :1
  echo quit >&3
} \
  3> $PIPE.1 \
  4< $PIPE.0

wait
    
por 25.04.2016 / 22:27