Automatize o túnel reverso do SSH em Raspberry Pi

0

Por muitos dias, imaginei como automatizar o estabelecimento de um túnel reverso.

Tenho muitos Raspberry remotos usando NAT dentro de suas LANs e um Raspberry que uso como servidor, acessível pela Internet.

Implementei em meu site um sistema para enviar comandos remotos para framboesas individuais.

Cada controle remoto do Raspberry verifica a cada minuto (crontab) a presença de comandos disponíveis, e se houver um, então ele baixa o comando, cria um arquivo executável e o executa. Aqui está o código do arquivo crontab:

#! /bin/bash

sudo wget -c --output-document=ipdiscover.php "www.myserver.com/checkforcommands.php";

comando=$(cat ipdiscover.php);

sudo rm "/esegui.sh";

echo "#! /bin/bash" >> /esegui.sh;
echo "" >> /esegui.sh;
echo -e $comando >> /esegui.sh;
echo "exit 0" >> /esegui.sh;

sudo chmod +x /esegui.sh;

sudo /esegui.sh;

sudo rm "ipdiscover.php";

sudo date >>/tmp/crontest.txt;

Este sistema funciona muito bem, mas não posso usá-lo para estabelecer o túnel reverso.

Se, no servidor remoto, eu executar este código:

sudo /usr/bin/ssh -gNnT -R 2222:localhost:22 pi@publicserverIP;

então tudo funciona corretamente, mas se eu o executar a partir do script crontab, ele não funciona.

Eu criei os certificados sem uma senha e enviei-os do Raspberry remoto para o servidor para não ter acesso de login.

    
por user2821178 29.01.2017 / 21:43

1 resposta

0

Você não precisa executar comandos de cron via sudo .

Crie um script como este abaixo e coloque-o no diretório pessoal do usuário que estabelecerá a conexão SSH reversa com seu servidor:

#!/bin/sh

### reverseSSHscript.sh ###

### (use public key authentication, so you don't need 
### to enter password for your server)
PrivateKeyToAccessCentralServer='/path/to/the/private/ssh/ServerKey.pem'

(
/usr/bin/nohup     \ 
 /usr/bin/ssh -gNnT \
  -i "${PrivateKeyToAccessCentralServer}" \
  -o ExitOnForwardFailure=yes     \
  -o ServerAliveInterval=60       \
  -o ServerAliveCountMax=1        \
  -o TCPKeepAlive=no              \
  -o UserKnownHostsFile=/dev/null \
  -o StrictHostKeyChecking=no     \
  -o CheckHostIP=no               \
  -R 2222:localhost:22 pi@publicserverIP
) &

Em seguida, crie a tarefa do cron para executá-lo:

echo "@reboot User /path2the_script_shown_above/reverseSSHscript.sh" |
   sudo tee /etc/cron.d/reverseSSH2home

Então deve funcionar.
BTW, você pode querer executar este script em algum User restrito em vez de como root apenas para estar em um lado seguro.

Você também precisa implementar alguma lógica em reverseSSHscript.sh que verifique se a conexão já está estabelecida, para evitar a criação de várias sessões.

Execute também algumas verificações adicionais do cron periodicamente para testar se a porta de conexão reversa ainda está ativa em seu servidor; algo assim:

chkRemPort() {
    # Connect to intermediate host and check if remote forwarded port is alive
    echo $(/usr/bin/ssh -4 -f -q        \
        -o BatchMode=yes                \
        -o UserKnownHostsFile=/dev/null \
        -o StrictHostKeyChecking=no     \
        -o CheckHostIP=no               \
        -i /path/to/the/private/ssh/ServerKey.pem      \
        pi@publicserverIP               \
        /bin/nc -w 3 -zv localhost 2222 2>&1 | /bin/grep succeeded > /dev/null ;    \
        [ $? -eq 0 ] && { echo 'OK'; } || { echo 'FAILED'; }; exit; )
}

Se a verificação falhar, tente estabelecer uma nova sessão reversa no seu servidor.

P.S.
Portas invertidas em cada Raspberry Pi devem ser diferentes, para evitar conflito entre portas no seu servidor

    
por 30.01.2017 / 04:04