Quando pergunto ao Google como o encaminhamento de agentes ssh funciona, ele me dá muitos links para lixo otimizado para SEO explicando como provisionar o ssh-agent. NÃO é isso que estou perguntando.
Atualmente, tenho um problema em que os trabalhos iniciados em uma sessão de tela no lado mais distante de uma conexão VPN falham porque não conseguem se conectar via ssh depois que a VPN falha.
Normalmente, esses trabalhos dependem do encaminhamento de agente do cliente de origem para conectar. Tenho suspeitas sobre o que está errado aqui, mas um melhor entendimento de todo o encaminhamento de agente ajudaria aqui.
Quando eu conecto do host0 para o hosta, o ssh-agent no host0 fornece minha chave privada para o cliente ssh no host0. No hosta, vejo SSH_AUTH_SOCK preenchido referenciando um socket local. Se, no hosta, eu então ssh hostb, o cliente ssh de alguma forma se conecta ao ssh-agent no host0. Presumivelmente, isso está usando um canal alternativo na conexão ssh host0-hosta.
O que está acontecendo em $SSH_AUTH_SOCK no hosta?
(fuser $SSH_AUTH_SOCK sugere que nada está aberto)
No caso da minha sessão de tela, se a sessão SSH que iniciou a sessão de tela tiver terminado e eu iniciar uma nova sessão SSH do host0 para o hosta, as solicitações de chave da sessão de tela serão enviadas pela nova conexão?
Bem, qualquer coisa que precise do agente SSH, procura a variável de ambiente
SSH_AUTH_SOCK
para descobrir o caminho para um soquete Unix usado para alcançar o agente. Isso é mencionado pelo menos na página man parassh-add
. (O caminho pode parecer, por exemplo, algo como/tmp/ssh-XXXXi1AqzV/agent.1149174
.)Quando você inicia o agente, ele imprime um conjunto de comandos para definir essa e outras variáveis de ambiente. Além disso, quando você se conecta em algum lugar com
ssh -A
, o cliente pede o encaminhamento do agente, e o servidor SSH remoto define essa env var para a sessão.No entanto... quando você executa screen, os processos dentro da sessão screen não veem as variáveis de ambiente definidas pela sessão fora de screen. Tudo o que eles terão é
SSH_AUTH_SOCK
definido por quando a sessão screen foi iniciada (se houver). As variáveis de ambiente são herdadas do pai quando um processo é iniciado e não podem ser alteradas de fora, então você não pode dar automaticamente o novo caminho para os processos dentro de screen. (Você pode verificar o novo caminho e atribuí-lo separadamente a cada shell, mas isso ficaria cansativo muito rápido.)Qualquer solução exigiria que a var env fosse constante durante o tempo de vida da sessão screen. Felizmente, sockets Unix são apenas arquivos, então você pode fazer a var env apontar para um symlink com um caminho conhecido, e alterar o alvo do link ao abrir uma nova sessão SSH.
A solução que tenho é mais ou menos esta:
~/.screenrc
:~/.ssh/rc
:Pode haver outras maneiras. Uma desvantagem disso é que o link sempre aponta para o socket criado pela última sessão SSH aberta (com encaminhamento de agente). Então, se eu abrir duas sessões e fechar a segunda, os processos dentro da tela não conseguem encontrar o agente.
Embora @ikkachu tenha me indicado uma solução, estou compartilhando os detalhes do que implementei aqui.
A primeira coisa a notar é que o ssh-agent em execução na sua máquina local não é simplesmente um repositório para chaves; ele lida com a criptografia/descriptografia assimétrica usada para negociar a chave de sessão (simétrica). Portanto, sua chave privada não é exposta em nenhum outro lugar além da sua máquina local (menciono isso porque não vi isso nos resultados que o Google encontrou para mim). Vale a pena ter em mente que o ssh renegociará as chaves a cada hora de uso.
Para permitir a recuperação, adicionei isto ao meu bash_profile no servidor ssh:
Para facilitar a manutenção da conectividade, escrevi um wrapper em torno do ssh que se reconectará automaticamente se:
Além disso, configurei connectTimeout para 10 segundos e clientAliveInterval para 10 segundos. A outra parte útil da funcionalidade aqui foi incorporar síntese de fala para me alertar quando as coisas não estão indo como planejado:
Coletivamente, eles não impedem que o ssh de viagem posterior do host remoto falhe, mas reduzem enormemente as janelas durante as quais isso pode ocorrer. E eu deveria estar ciente quase imediatamente quando uma tarefa em uma janela minimizada/em segundo plano está falhando.