Information / Assistance requerido no tunelamento reverso do SSH (convenções de nomenclatura etc)

3

Eu tenho vários pi de framboesa rodando o Arch Linux (No GUI) no qual preciso acessar. Esses pi's estão atrás de firewalls em cada local exclusivo. Atualmente eu uso o openvpn para me conectar a eles, mas os custos desse sistema são caros por licença. Eu uso o servidor de acesso deles.

Como resultado, estou tentando projetar e configurar um sistema que me permita acessar o servidor VPN (vps) e executar um comando para procurar um nome específico (OfficeDevice1991), como: customcommandsearch "OfficeDevice1991" e Em seguida, ele retorna o endereço IP da máquina ou algo que eu possa usar para o SSH. Eu também estou procurando a capacidade de executar um comando para listar todos os dispositivos conectados ativos. Ele lista de volta o IP, nome e talvez há quanto tempo ele está ativo.

Para esse objetivo, é claro que preciso criar algo que inclua o nome do dispositivo (neste caso, OfficeDevice1991) e, em seguida, que pi possa ser conectado ao meu servidor público vps. Do servidor público, posso fazer login e fazer uma pesquisa em todos os dispositivos conectados a ele e retornar as informações necessárias para o ssh.

Eu tenho procurado o SSH reverso e até agora eu tenho um dos meus testes de pi conectados e acessíveis dos meus vps usando os seguintes comandos:

PI:

ssh -fN -R 12345:localhost:22 -i /publickeyfile useraccount@ip //Pi's command to connect to vpn

VPS:

ssh -p 12345 useraccount@localhost //command for vpn to connect to pi

Isso funciona muito bem, mas usando esse método, se eu fosse implementá-lo, teria alguns problemas:

  1. Eu precisaria configurar portas não usadas exclusivas
  2. Alguma maneira de manter essas portas / túneis abertos
  3. Eu preciso criar um sistema para identificar cada dispositivo. Posso registrar cada porta para um nome como um arquivo de texto localmente? Seria benéfico poder incluir isso na configuração do ssh para cada dispositivo, se possível. Eu ainda precisaria ter certeza de que as portas que eu uso não estão sendo usadas por nenhum outro programa ou qualquer dispositivo que já esteja lá.

O que não quero ter que fazer

  1. Verifique quais portas estão livres para usar em cada RPI

  2. É necessário editar manualmente .ssh/config para adicionar um nome para representar cada porta atribuída ao RPI da parte 1 acima.

Estou escrevendo isso para obter informações / assistência sobre o que fazer para o meu objetivo.

Alguém poderia me fornecer uma solução adequada?

    
por irishwill200 11.04.2018 / 16:21

2 respostas

1

Aqui está uma solução usando o OpenSSH > = 6.7 + socat :

  1. 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 ProxyCommand para 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ção StreamLocalBindUnlink=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 (em sshd_config ) com um encaminhamento remoto ( -R ). OP encontrou . 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 yes
    

    Dependendo das opções padrão, também pode exigir AllowStreamLocalForwarding yes

    UPDATE2:
    Também defina em sshd_config os parâmetros ClientAliveInterval e ClientAliveCountMax , permitindo assim detectar uma desconexão em um tempo razoável, por exemplo:

    ClientAliveInterval 300
    ClientAliveCountMax 2
    

    Conexõ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@ip
    

    Em um arquivo de configuração, isso seria semelhante a isto:

    Host ip
    User useraccount
    RemoteForward /rpi-access/OfficeDevice1991:localhost:22
    IdentityFile /privatekeyfile
    

    Repetindo novamente: a opção StreamLocalBindUnlink yes definida em sshd no 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@OfficeDevice1991
    

    Como 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 -
    
  2. 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
    done
    

    Mesmo 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 yes atualizará vigorosamente o soquete unix para a nova conexão.

  3. já foi manipulado por 1.

    Não há customcommandsearch necessário. Com as configurações corretas definidas em 1. basta usar ssh OfficeDevice1991 para se conectar ao OfficeDevice1991.

    Se necessário no VPS, como root user 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.

por 11.04.2018 / 23:49
1

Este é um par de diferentes tomadas na situação. Eu omiti alguns dos detalhes aqui porque não há nada que o impeça de fazer uma pergunta adicional para detalhes se você tentar um desses rotas.

1. Substitua o servidor de acesso do OpenVPN

Se o custo do OpenVPN Access Server for um problema proibitivo, considere a possibilidade de implantar seu próprio servidor OpenVPN. O software é gratuito para uso; você precisaria apenas de um endpoint de servidor (um VPS ou equivalente, se você não tem nada localmente) e o conjunto de habilidades para configurá-lo. Muitos tutoriais estão disponíveis para isso, então você não precisa começar do zero.

Depois de configurar, você pode usar o DNS ou /etc/hosts para definir nomes de host, como o OfficeDevice1991 , para apontar para o endereço de ponto de extremidade da VPN apropriado em seu servidor.

2. Use autossh em vez de OpenVPN

Depois de ter seu próprio endpoint, você pode usar algo como autossh em cada um dos sistemas Pi para ssh para um ponto de extremidade "bem conhecido" na inicialização (um VPS ou equivalente, se você não tiver nada localmente).

Leve um túnel reverso ( ssh -R ) através de cada um, de modo que cada Pi apresente um número de porta diferente do seu servidor que mapeie de volta para sua própria ssh port 22.

O uso criterioso de entradas em ~/.ssh/config pode permitir que você execute ssh OfficeDevice1991 e faça o mapeamento automaticamente para algo como ssh -p 12345 localhost , que por sua vez corresponderia a uma conexão ssh normal ao Pi representando OfficeDevice1991. / p>

Respondendo ao seu conjunto de perguntas que você adicionou na sua edição,

who ou finger daria a você o tempo de conexão de cada RPI.

  1. As portas 49152 a 65535 são suas
  2. Isso é o que o autossh faz
  3. Hostnames

e

  1. Como # 1 acima
  2. Um pequeno loop for x ... do ... done poderia gerar automaticamente o arquivo para você. Também não gostaria de criar 1000 entradas manualmente.
por 12.04.2018 / 11:02