Automatize o túnel reverso SSH no Raspberry Pi

Automatize o túnel reverso SSH no Raspberry Pi

Durante muitos dias, me perguntei 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 únicos para Raspberries remotos.

Cada Raspberry remoto verifica a cada minuto (crontab) a presença de comandos disponíveis e, se houver, 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 executá-lo a partir do script crontab, não funciona.

Criei os certificados sem senha e enviei do Raspberry remoto para o servidor para não fazer login.

Responder1

Você não precisa executar comandos cronvia sudo.

Crie algum script como este abaixo e coloque-o no diretório home do usuário que irá estabelecer 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.
A propósito, você pode querer executar este script com alguma restrição, Userem vez de rootapenas por segurança.

Você também precisa implementar alguma lógica que reverseSSHscript.shverifique se a conexão já está estabelecida, para evitar a criação de múltiplas 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 em seu servidor.

PS
As portas invertidas em cada Raspberry Pi devem ser diferentes, para evitar conflito entre as portas do seu servidor

informação relacionada