Advanced multiply raspberry pi reverse ssh tunnels

I need to control more than one pi from ssh, and I found some questions without answers about it in StackOverflow.

I’ll write my own solution, any suggestion is welcome.

Architecture

Raspberry Pi

Installation:

sudo apt install  sshpass
echo "cat ~/.ssh/support.pub" >> /tmp/script
sshpass -p [SUPPORT_PASSWORD] ssh [SUPPORT_USER]@[SUPPORT_SERVER] 'bash -s' < /tmp/script >> /tmp/support.pub
cat /tmp/support.pub >> ~/.ssh/authorized_keys 

Usage

We’ll write a script that tries to connect to the server every minute if there is a connection continue, if not create one.

vim /opt/reversesssh

#!/bin/bash

SUPPORT_USER="openhabian"
SUPPORT_SERVER="192.168.178.55"

function getPort() {
  echo "/opt/next.py $(cat /var/lib/dbus/machine-id)" > /tmp/script
  port=$(ssh -l $SUPPORT_USER $SUPPORT_SERVER 'bash -s' < /tmp/script)
  echo $port
}

createTunnel() {
  getPort
  /usr/bin/ssh -N -R $port:localhost:22 -l $SUPPORT_USER $SUPPORT_SERVER
}

/bin/pidof ssh
if [[ $? -ne 0 ]]; then
  echo Creating new tunnel connection
  createTunnel
fi

sudo chmod +x  /opt/reversessh

crontab -e

*/1 * * * * /opt/reversessh

Server

Installation

create an ssh key with empty passphrase

ssh-keygen -f ~/.ssh/support -C support -t rsa

create the next port script

vim /opt/next.py

#!/usr/bin/python3
import sys
import json
import os.path

pi = {}
pi[sys.argv[1]] = 10000

dbPath = '/opt/portdb'
if not os.path.isfile(dbPath):
    with open(dbPath,'w+') as f:
        f.write(json.dumps(pi))
else:
    with open(dbPath,'r') as f:
        data = json.load(f)
        if not sys.argv[1] in data:
            data[sys.argv[1]] = 10000+len(data)

with open(dbPath,'w+') as f:
    f.write(json.dumps(data))

print(data[sys.argv[1]])

make it executable

sudo chmod +x /opt/next.py

 

Usage

From the server to connect to the pi

 ssh -l pi -p [PI_PORT] localhost

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *