0

For many days, I've wondered how to automate the establishment of a reverse tunnel.

I've many remote Raspberry using NAT inside their LANs, and one Raspberry that I use as server, reachable from the Internet.

I've implemented on my website a system to send to remote Raspberries single commands.

Every remote Raspberry checks every minute (crontab) the presence of commands available, and if is there is one, then it downloads the command, creates an executable file and runs it. Here is the code of the crontab file:

#! /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;

This system functions very well, but I can't use it to establish the reverse tunnel.

If, on remote server, I run this code:

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

then all works correctly, but if I run it from the crontab script, it does not work.

I created the certificates without a password, and I sent it from remote Raspberry to server in order to make no login access.

7
  • what errors you get?
    – Jakuje
    Jan 29, 2017 at 22:38
  • Error on autentication. Strange because if I run the command directly I do not receive anything error Jan 29, 2017 at 23:00
  • If you running locally as you show it in your question then you need to provide a password to your server. Setup public key authentication, then you don't need any password while it will keep your server safe from unauthorized connections
    – Alex
    Jan 30, 2017 at 3:09
  • I I've alredy did it, on remote machine: 1) ssh-keygen; (left blank on password request) 2) ssh-copy-id -i ~/.ssh/id_rsa.pub dyn.IP.adresse; Jan 30, 2017 at 7:18
  • I get these errors: Permission denied, please try again. Permission denied, please try again. Permission denied (publickey,password). Jan 30, 2017 at 16:18

1 Answer 1

0

You don't need to run commands from cron via sudo.

Create some script like this one below and put it in the home directory of the user that will establish reverse SSH connection to your server:

#!/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
) &

Then create cron's task to run it:

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

Then it should work.
BTW, you may want to run this script under some restricted User instead of as root just to be on a safe side.

You also need to implement some logic in reverseSSHscript.sh that checks whether the connection is already established, to prevent multiple session creation.

Run also some additional checks from cron periodically to test whether the reverse-connection port is still alive on your server; something like this:

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; )
}

If check failed, then try to establish a new reverse session to your server.

P.S.
Reversed ports on each Raspberry Pi should be different, to avoid conflict between ports on your server

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .