Como limpar o soquete de encapsulamento reverso do SSH após a conexão ser fechada?

3

Se eu executo algo assim:

ssh -4 -f -N -T -R "/home/dude/lol.socket:192.168.4.44:4444" dude@someserver -p 22 -i privatekey -o "ExitOnForwardFailure yes" -o ConnectTimeout=5 -o ConnectionAttempts=3 -o ServerAliveInterval=15 -o

E então vamos dizer que a conexão está fechada ou morre por qualquer motivo .. digamos que o computador seja reiniciado devido a manutenção ou erro ou há problemas de conectividade com a Internet ou o que quer que seja - > Nós temos um grande problema. O arquivo de soquete criado /home/dude/lol.socket no someserver não é excluído por sshd. Então, como o iniciador do túnel reverso está se recuperando e tenta recriar o túnel, não pode porque:

Error: remote port forwarding failed for listen path /home/dude/lol.socket

No lado do servidor, você recebe algo como:

error: bind: Address already in use
error: unix_listener: cannot bind to path: /home/dude/lol.socket

Qual seria o caminho suportado / melhor corte para limpar o soquete após a desconexão? Isso é um bug no sshd, não deveria ser feito automaticamente se / quando forem desconexas?

Histórico:

A idéia por trás do uso dos soquetes é simplesmente que o servidor vai lidar com n "dudes" criando túneis reversos para serviços m "lol" em qualquer porta e usando sockets torna muito mais fácil garantir que um "cara" só possa acesse e ligue-se a seus próprios sockets, mas não a outros sockets de dudes. Também me libera de ter que manter registro de qual cara está usando qual porta para expor qual serviço. E quando o cara quer se conectar ao serviço em algum outro servidor, tudo o que ele precisa saber é o nome do serviço e vinculá-lo a alguma porta local aleatória (ou soquete, se ele quiser), ou seja,

ssh -v -i -4 -N -T -L "127.0.0.1:3334:/home/dude/lol.sock" -p 22 dude@someserver -o "ExitOnForwardFailure yes" -o ConnectTimeout=5 -o ConnectionAttempts=3 -o ServerAliveInterval=15 -o ServerAliveCountMax=3

Não há necessidade de saber algum número de porta mágica em que o túnel reverso no servidor deve estar rodando. Então, se você tiver ideias melhores de como resolver esse problema, sou todo ouvidos.

Testado com o cliente / servidor executando Debian 9 (cliente atualmente no mac dentro do contêiner do docker) usando a versão openssh-client / server 7.4p1-10+deb9u2

    
por Timo 28.02.2018 / 13:24

1 resposta

7

TL; DR;

A solução é definir o valor de StreamLocalBindUnlink como yes na configuração de ssh: sudo echo "StreamLocalBindUnlink yes" >> /etc/ssh/sshd_config .

Longa história

A razão pela qual isso acontece é porque os arquivos de soquete unix não são removidos automaticamente quando o soquete é fechado. Eles precisam ser limpos manualmente ao fechar, se desejado, chamando remove / unlink com o caminho do arquivo, mas o openssh não faz isso. No entanto, como eu pesquisei o assunto mais eu cheguei à conclusão de que a "melhor prática" com sockets unix é a unlink right antes ligação a ele ( Verifique esta resposta SO para obter mais detalhes ). E é exatamente isso que o StreamLocalBindUnlink yes diz ao sshd para fazer.

Página man diz:

 StreamLocalBindUnlink
         Specifies whether to remove an existing Unix-domain socket file for local or remote port forwarding before creating a new
         one.  If the socket file already exists and StreamLocalBindUnlink is not enabled, sshd will be unable to forward the port to
         the Unix-domain socket file.  This option is only used for port forwarding to a Unix-domain socket file.

         The argument must be yes or no.  The default is no.

A desvantagem dessa abordagem é que a religação ao soquete agora é permitida, mesmo se a conexão antiga ainda estiver lá. Fazer isso parece deixar o velho túnel pendurado lá, de modo que qualquer conexão tcp existente permaneça intacta, mas todas as novas conexões vão para o novo túnel. Além disso, o túnel antigo parece ser permanentemente e irreversivelmente desconectado do endereço do soquete do sistema de arquivos e não poderá receber mais novas conexões mesmo se o novo túnel for fechado.

Referências

por 13.03.2018 / 10:50