Aqui está uma solução usando o OpenSSH > = 6.7 + socat :
-
OpenSSH > = 6.7 pode usar o encaminhamento de soquete de domínio Unix
Isso significa que o ponto de extremidade do túnel reverso será um soquete de escuta do UNIX em vez de um socket de escuta TCP tradicional. Você pode então gerenciar mais facilmente a flotilha de RPIs com um esquema de nomeação fácil: o nome do soquete será o nome escolhido (e fixo) do RPI, como
OfficeDevice1991. Pode até ser uma propriedade única do RPI, desde que seja um nome de arquivo válido (desde que os nomes de soquete unix estejam de acordo com as convenções de nome de arquivo). Por exemplo, seu hostname, o endereço MAC de sua placa ethernet ou wifi ...O SSH pode lidar com soquetes unix para túneis, não para se conectar. Ele precisará da ajuda de um
ProxyCommandpara poder funcionar como cliente unix-socket. O socat pode lidar com muitos tipos de conexões, incluindo soquetes unix.UPDATE:
Há também um problema específico a ser tratado: o arquivo de soquete unix não é excluído na saída limpa, nem seria excluído de qualquer maneira, por exemplo, após uma falha. Isso requer a opçãoStreamLocalBindUnlink=yes. Eu não achei inicialmente que, como o nome talvez sugere, esta opção deve ser definida no nó que cria o soquete unix. Então, no final, é definido no cliente com um encaminhamento local (-L) ou outro no servidor (emsshd_config) com um encaminhamento remoto (-R). OP encontrou lá . Esta solução usa um encaminhamento remoto.Configuração no VPS:
mkdir /rpi-access(como root) edite o arquivo
sshd_config(/etc/ssh/sshd_config). Requer essa opção adicional:StreamLocalBindUnlink yesDependendo das opções padrão, também pode exigir
AllowStreamLocalForwarding yesUPDATE2:
Também defina emsshd_configos parâmetrosClientAliveIntervaleClientAliveCountMax, permitindo assim detectar uma desconexão em um tempo razoável, por exemplo:ClientAliveInterval 300 ClientAliveCountMax 2Conexões ssh obsoletas devem então ser detectadas mais cedo no VPS (~ 10mn com o exemplo), e o processo sshd correspondente irá sair.
Uso no RPI:
ssh -fN -R /rpi-access/OfficeDevice1991:localhost:22 -i /privatekeyfile useraccount@ipEm um arquivo de configuração, isso seria semelhante a isto:
Host ip User useraccount RemoteForward /rpi-access/OfficeDevice1991:localhost:22 IdentityFile /privatekeyfileRepetindo novamente: a opção
StreamLocalBindUnlink yesdefinida emsshdno lado do VPS é importante: o soquete recém-criado não é removido, mesmo após a saída normal. Essa opção garante que o soquete seja removido se existir antes de ser usado, permitindo, dessa forma, ser reutilizado para reconexões adicionais. Isso também significa que não se pode considerar a mera presença do socket como significando que o RPI está conectado (mas veja depois).Agora isso permite fazer no VPS:
ssh -o 'ProxyCommand=socat UNIX:/rpi-access/%h -' rpiuseraccount@OfficeDevice1991Como arquivo de configuração, considerando, por exemplo, os RPIs têm um nome que começa com OfficeDevice :
Host OfficeDevice* User rpiuseraccount ProxyCommand socat UNIX:/rpi-access/%h - -
Para manter o link, basta usar um loop
O RPI pode executar um loop reconectando o ssh ao VPS sempre que as conexões terminarem. Para isso, não é necessário usar o modo de segundo plano (sem
-f). Um mecanismo keepalive também deve ser usado. TCPKeepAlive (nível de sistema) ou ServerAliveInterval (nível de aplicativo) estão disponíveis. Eu acho que o TCPKeepAlive é útil apenas no servidor (o lado que recebe a conexão), então vamos usar o ServerAliveInterval.Seu valor (assim como ServerAliveCountMax) provavelmente deve ser adaptado dependendo de vários critérios: um firewall perdendo conexões inativas após um certo tempo, o atraso de recuperação desejado, não gerando tráfego inútil, ... digamos 300s aqui.
OfficeDevice1991 RPI:
#!/bin/sh while : ; do ssh -N -o ConnectTimeout=30 -o ServerAliveInterval=300 -R /rpi-access/OfficeDevice1991:localhost:22 -i /privatekeyfile useraccount@ip sleep 5 # avoid flood/DDoS in case of really unexpected issues doneMesmo que o lado remoto ainda não tenha detectado a falha de conectividade anterior e, por mais algum tempo, a conexão ssh antiga ainda esteja em execução,
StreamLocalBindUnlink yesatualizará vigorosamente o soquete unix para a nova conexão. -
já foi manipulado por 1.
Não há
customcommandsearchnecessário. Com as configurações corretas definidas em 1. basta usarssh OfficeDevice1991para se conectar ao OfficeDevice1991.Se necessário no VPS, como
rootuser only, este comando:fuser /rpi-access/*pode mostrar quais RPIs estão atualmente conectados (é claro, exceto aqueles que recentemente perderam a conexão antes da detecção). Ele não mostrará os arquivos obsoletos do soquete unix porque não há nenhum processo vinculado a eles.