Aguarde até que o SSH consiga criar um encaminhamento de porta

7

Estou chamando ssh (OpenSSH) de um aplicativo OSX / Linux-C ++ - via fork / exec para criar um encaminhamento de porta dinâmico. Isso é feito usando o modo em lote (-o BatchMode = yes) e uma chave privada fornecida ao ssh (-i Option). A chamada SSH em si não abre um shell (-N Opção).

Esta é a minha chamada SSH completa:

ssh -N -D 9000 -o BatchMode=yes -i /path/to/private-key user@host

Gostaria de prosseguir com meu aplicativo assim que possível e, portanto, tenho que descobrir se o ssh conseguiu criar o canal. O próprio SSH retornará apenas se houver um problema.

Existe a possibilidade de detectar um encaminhamento de porta bem-sucedido?

É claro que posso esperar até que a porta seja aberta pelo SSH, mas estou procurando uma solução mais elegante. Outra solução é inspecionar o Log (-v) do SSH aguardando "Entrando na sessão interativa", mas isso não me parece muito portátil.

nob
fonte

Respostas:

4

Use a -fopção e sshentrará em segundo plano (por exemplo, forke sairá no processo pai), para que você possa concluir waitpido original sshe saber (com base no status da saída) que a conexão falhou ou o encaminhamento de porta já está configurado.

R ..
fonte
1
Isso parece bom. Mas agora eu teria o problema de não conseguir descobrir o PID do processo SSH bifurcado e, portanto, não conseguir limpar facilmente após o término do programa. Existe essa discussão no Debians Bugzilla: bugzilla.mindrot.org/show_bug.cgi?id=1473 A única chance que vejo de usá-lo em conjunto com -f é usar o ControlMaster / Slave-Communication.
1
@nob, você pode sinalizar o neto usando grupos de processos. Basicamente, quando o aplicativo bifurca o exec ssh, o processo filho deve se tornar um líder de grupo de processos antes de chamar o exec. Aqui está um exemplo em perl de fazer isso.
Kenster
Os grupos de processos soam como a melhor solução, mas também pode ser possível organizar o processo ssh quando um determinado tubo ou soquete é fechado pelo seu processo.
R ..
1

Acho que encontrei outra solução (também hackiana). Ao iniciar o SSH com

ssh -S /some/domain/socket -M ...args... host

ele criará apenas o soquete do domínio de controle e estabeleceu com êxito a conexão. Então, eu teria que esperar o soquete do domínio aparecer no sistema de arquivos. Ainda não é bonito, mas isso parece mais robusto do que esperar que um soquete de rede apareça.

Curiosamente, isso também pode ser usado para descobrir o PID do mestre (consulte a Resposta da R.). Usando

$ ssh -S /some/domain/socket -O check host
Master running (pid=25503)
nob
fonte