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.
Raspberry Pi
Installation:
sudo apt install sshpass
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' 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 an empty passphrase
ssh-keygen -f ~/.ssh/support -C support -t rsa
create the next python 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