Reverse SSH Tunneling is the connection from the destination to the source instead of the default procedure which is the connection from the source to the destination. We can use this method to establish a connection to a remote network without knowing it’s external IP or making any changes to the network’s configuration. Unless a firewall restricts SSH traffic, the following guide using a Raspberry PI and an ENC28J60 module should be enough to establish a connection to the remote network by plugging the device to the remote network through ethernet.
How it works
A Remote Device, the "Drone", will initialize a reverse tunnel from "any" network with an active Internet connection back to your Local Network. Just plug the Drone to the remote network using an Ethernet cable (the remote network must have DHCP enabled) and you are ready to go. When the device power up, it will establish an ssh connection to a "MIDDLE_HOST" (an always online server with static IP) from where you can connect using SSH without the need to know the IP of the Drone.
Use Case
- Access a remote network without knowing any details or making any configuration changes for monitoring, file exchange, etc
Pre-requisites
In order to accomplish the following project and connect to the Drone you must:
- Configure an always on "Middle Host" with known external IP (must either be a static one, or have a way to know which is the one currently in use). Skip this step if you want the Drone to connect to your pc, but make sure that your computer is powered on when the Drone will try to initialize the connection.
- Access the Internet Provider’s Modem/Router at the Local Network and setup the appropriate port forwarding.
- Be able to understand if the Provider’s Modem/Router device has enabled any firewall rules which may conflict with your configuration.
"Middle Host" configuration
On your internet provider’s device (modem/router) set port forwarding for redirecting from a specific external port (this port will be used at step 14) to port 22 of the device. There is no standard procedure for applying this settings so you will have to search how you make this changes on the specific model of the device and your internet provider.
Drone Configuration
The configuration can be simplified by using a standard Raspberry PI (anyone with a built-in ethernet).
The current implementation was made using a Raspberry PI Zero, and an ENC28J60 Ethernet Module as follows:
Schematic [skip if using a Raspi with built-in ethernet]
ENC28J60 Pinout
ENC28J60 Module | Raspberry PI |
---|---|
VCC / 3.3 | 3V3 (PIN #1) |
GND | GND (PIN #6) |
CS | GPIO8 (PIN #24) |
SI | GPIO10 (PIN #19) |
SCK | GPIO11 (PIN #23) |
SO | GPIO09 (PIN #21) |
INT / IRQ | GPIO25 (PIN #22) |
Shut Down Button Pinout
Shut Down on Raspbian Stretch 2017.08.16 and newer versions can be accomplished using the shutdown overlay through the config.txt file of the boot partition. The only hardware change required to add a Shut Down button using this method, is the connection of a push button between a GPIO pin (here GPIO21-PIN #40) is used. If you choice to use GPIO3 (PIN #5), then the same button can be used both for Shut down and Power Up.
Configuration
- Prepare a new sd-card with Raspbian lite
- In the boot partition of the sd-card:
- Create an empty file, name it "ssh" and make sure it has no extension.
- Edit the config.txt file and append the following at the end of the file. [This step is only required if your using the ENC28J60 Module.]
# Enable SPI Interface. Required for communication with the ENC28J60 module dtparam=spi=on # Activate the enc28j60 ethernet interface dtoverlay=enc28j60
- If you plan to use a shut down push button connected to the GPIO 21 (PIN #40) as the above schematic also add the following code: [Skip or Modify this step according to your needs]
# Set the GPIO pin 21 as a shutdown pin dtoverlay=gpio-shutdown,gpio_pin=21
- You can also minimize any emissions (Wifi and Bluetooth), for less power consumption and less detection, by adding the following code:
# Disable onboard wifi and bluetooth dtoverlay=pi3-disable-wifi dtoverlay=pi3-disable-bt
- Insert the SD card in your Raspi, connect it to your local network and power it up.
- Establish an SSH connection to the raspi using the default credentials (pi/raspberry). If you don’t know how to connect using SSH, use the official guides for Windows or Linux or Mac
- After connecting using SSH, update and upgrade your distribution
sudo apt update sudo apt upgrade -y
- Install autossh
sudo apt-get install autossh -y
- Change the hostname from raspberrypi to NEW_HOSTNAME (Use a hostname which will seems out of importance to avoid easy detection). [Optional]
sudo hostname NEW_HOSTNAME sudo sed -i 's/raspberrypi/NEW_HOSTNAME/g' /etc/hosts sudo sed -i 's/raspberrypi/NEW_HOSTNAME/g' /etc/hostname
- Use this guide to add a new user to the raspberry and delete the default pi user. [Optional but highly reccomended to increase security]
- Generate a public/private RSA key pair for password-less connection to the Middle Host.
ssh-keygen -t rsa -b 4096 -f remote_id_rsa
You will be asked for a passhphrase twice (the second one is for confirmation).
After that you will be provided with the SHA-256 hash of the key and the random seed used for the generation. - Key generation is now completed. Copy the public key to the "middle" host
ssh-copy-id -i remote_id_rsa.pub -p 22 MIDDLE_HOST_USER@MIDDLE_HOST_IP_ADDRESS
You will be asked and you have to provide the password for the current user of the "Middle host" in order to establish the communication and copy the public key.
- Check the connection to the middle host issuing the command:
ssh -i remote_id_rsa MIDDLE_HOST_USER@MIDDLE_HOST_IP_ADDRESS
- We can remove the public key as we don’t need it any more.
rm remote_id_rsa.pub
- Move the private key to the appropriate location
mv remote_id_rsa ~/.ssh/
- Try a new connection to the "Middle host" using the external ip and appropriate port of the "Middle Host" (The one you set at "Middle" Host preparation)
ssh -i ~/.ssh/remote_id_rsa MIDDLE_HOST_USER@MIDDLE_HOST_EXTERNAL_IP -p MIDDLE_HOST_PORT
- The first time you login to the "Middle host" you have to add this host to the "known hosts" list. You do this by typing yes in order to complete the connection.
- After the successful login, if you are using ssh and you are still login to the "Middle host" logout to finish the preparation using the command.
logout
- Schedule a crontab job to reconnect to the "Middle host" when the Drone boots. Use Crontab by typing:
crontab -e
If you have never before used the crontab you will be asked to select your preferred editor. Nano is the easiest to use, so choice 1 and press enter.
- Schedule the connection to established using autossh on each boot using the command:
@reboot autossh -N -f -i ~/.ssh/remote_id_rsa -p MIDDLE_HOST_PORT -R MIDDLE_HOST_PORT:localhost:22 MIDDLE_HOST_USER@MIDDLE_HOST_EXTERNAL_IP &
In case you have problems keeping the connection alive, you can use additional options. Specifically you can try :
-o ServerAliveInterval=60 -o ServerAliveCountMax=3
The configuration is now completed. Each time the drone boot’s up it will initialize a connection to the "Middle host". From there you can connect to the device using ssh and be a part of the remote network.
Connect to the Drone
From the "Middle host" use the command:
ssh DRONE_USERNAME@locahost -p MIDDLE_HOST_PORT
and enter the Drone’s user password.
Download the 3d files
Further optimizations
- Customize the ethernet module to support POE.
- Use the Drone as a SOCKS proxy server.
- Use HTTPS to hide the network traffic.
Your point of view caught my eye and was very interesting. Thanks. I have a question for you.