How to Create a Reverse SSH Tunnel: Difference between revisions

From RidgeRun Developer Wiki
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
__TOC__
__TOC__


= Introduction =
== Introduction ==
Oftentimes, a remote device needs to be accessed through <code>SSH</code> but it's not reachable due to network conditions, security requirements, etc.
Oftentimes, a remote device needs to be accessed through <code>SSH</code> but it's not reachable due to network conditions, security requirements, etc.


Line 18: Line 18:
[[File:SSH Reverse Tunnel.png|500px|thumbnail|center|SSH Reverse Tunnel Diagram]]
[[File:SSH Reverse Tunnel.png|500px|thumbnail|center|SSH Reverse Tunnel Diagram]]


Actually the tunnel is created by the '''REMOTE device''', and the '''LOCAL device''' uses that tunnel to access the '''REMOTE'''. Then, to create the tunnel, you need some level of access to the '''REMOTE device''', but this process is done only once, whether you need to move to the '''REMOTE''' or you need the '''REMOTE''' owner's help.
The tunnel is created by the '''REMOTE device''', and the '''LOCAL device''' uses that tunnel to access the '''REMOTE'''. Then, to create the tunnel, you need some level of access to the '''REMOTE device''', but this process is done only once, whether you need to move to the '''REMOTE''' or you need the '''REMOTE''' owner's help.


= Instructions =
== Instructions ==
Now you will find instructions to create a '''reverse SSH tunnel'''.
You will find below the instructions to create a '''reverse SSH tunnel'''.


== Generate Key Pairs (REMOTE and LOCAL) ==
=== Overview ===
We are going to create the connection based on the following structure:
 
[[File:Reverse SSH Tunnel Block Diagram with Ports.png|1000px|thumb|center|Reverse SSH Tunnel Block Diagram with Ports]]
 
Basically, the tunnel can be achieved in two steps:
* '''Step 1''': the remote device will create an ssh connection with the local device. It will tell ssh to forward connections from 2210 to port 22, enabling the reverse tunnel.
 
* '''Step 2''': the local device has now a tunnel to access the remote device.
 
All the details are shown below.
 
=== Generate Key Pairs (REMOTE and LOCAL) ===
* On '''REMOTE'''
* On '''REMOTE'''
<source lang=bash>
<source lang=bash>
Line 39: Line 51:
}}<br>
}}<br>


=== Share Generated Public Keys ===
==== Share Generated Public Keys ====
We will share the public keys between both devices, so that no password is required when enabling the connections.
We will share the public keys between both devices, so that no password is required when enabling the connections.


Line 57: Line 69:
}}<br>
}}<br>


== Systemd Service (REMOTE) ==
=== Systemd Service (REMOTE) ===
We want the '''REMOTE''' to enable the tunnel every time it starts. Also, it will try to enable the tunnel if there's an error.
We want the '''REMOTE''' to enable the tunnel every time it starts. Also, it will try to enable the tunnel if there's an error.


Line 89: Line 101:
echo "Reverse SSH started at ${DATE}" | systemd-cat -p info
echo "Reverse SSH started at ${DATE}" | systemd-cat -p info


ssh -i /home/$USER/.ssh/id_rsa_remote -oStrictHostKeyChecking=no -N -R 2210:localhost:22 -p 2020 LOCAL_USER@LOCAL_IP
ssh -i /home/$USER/.ssh/id_rsa_remote -oStrictHostKeyChecking=no -N -R 2210:localhost:22 LOCAL_USER@LOCAL_IP
</source>
</source>


Line 105: Line 117:
</source>
</source>


== Enable Port (LOCAL)==
=== Enable SSH (LOCAL)===
We will enable the <code>2020</code> port to receive the reverse tunnel request in the '''LOCAL''' device.
 
* Search the following line inside the file <code>/etc/ssh/sshd_config</code>:
<pre>
#Port 22
</pre>
 
* And replace it with
<pre>
Port 2020
</pre>
 
{{Ambox
|type=notice
|issue= '''Port 2020'''<br>You might have noticed that we have used ''2020'' as a port number multiple times . You can change it depending on your needs, but please take a look at the other sections of this wiki to change this port accordingly.
}}<br>
 
* Start the <code>ssh</code> service:
* Start the <code>ssh</code> service:


Line 129: Line 124:
</source>
</source>


== SSH Access (LOCAL) ==
=== SSH Access (LOCAL) ===
We are all set!
We are all set!



Latest revision as of 22:16, 7 December 2021

Introduction

Oftentimes, a remote device needs to be accessed through SSH but it's not reachable due to network conditions, security requirements, etc.

SSH Connection Blocked

A reverse SSH tunnel is a solution to that problem. Basically, the hard-to-reach device will create a tunnel to a specific device that we have access to. From now on, we will use the following notation:

  • LOCAL Device
The device to which we have easy access (your laptop, for example).
  • REMOTE Device
The device that is hard to access (usually it's far away from us, or it's someone else's device).

The following diagram represents the LOCAL device to the left, the REMOTE device to the right, and the tunnel enabling the connection.


SSH Reverse Tunnel Diagram

The tunnel is created by the REMOTE device, and the LOCAL device uses that tunnel to access the REMOTE. Then, to create the tunnel, you need some level of access to the REMOTE device, but this process is done only once, whether you need to move to the REMOTE or you need the REMOTE owner's help.

Instructions

You will find below the instructions to create a reverse SSH tunnel.

Overview

We are going to create the connection based on the following structure:

Reverse SSH Tunnel Block Diagram with Ports

Basically, the tunnel can be achieved in two steps:

  • Step 1: the remote device will create an ssh connection with the local device. It will tell ssh to forward connections from 2210 to port 22, enabling the reverse tunnel.
  • Step 2: the local device has now a tunnel to access the remote device.

All the details are shown below.

Generate Key Pairs (REMOTE and LOCAL)

  • On REMOTE
ssh-keygen -f /home/$USER/.ssh/id_rsa_remote
  • On LOCAL
ssh-keygen -f /home/$USER/.ssh/id_rsa_local


Share Generated Public Keys

We will share the public keys between both devices, so that no password is required when enabling the connections.

  • Copy the LOCAL's public key into the REMOTE's authorized_keys file.
cat id_rsa_local.pub >> ~/.ssh/authorized_keys
  • Copy the REMOTE's public key into the LOCAL's authorized_keys file.
cat id_rsa_remote.pub >> ~/.ssh/authorized_keys


Systemd Service (REMOTE)

We want the REMOTE to enable the tunnel every time it starts. Also, it will try to enable the tunnel if there's an error.

For this we'll create a systemd service running on the REMOTE.

  • Create the file /etc/systemd/system/reverse_ssh.service with the following contents:
[Unit]
Description=Reverse SSH Tunnel Example

[Service]
# Please replace "user" with the REMOTE's username
User=user
Type=simple
ExecStart=/bin/bash /usr/local/bin/reverse-ssh.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target


  • Create the script file /usr/local/bin/reverse-ssh.sh with the content:
DATE=`date '+%Y-%m-%d %H:%M:%S'`
echo "Reverse SSH started at ${DATE}" | systemd-cat -p info

ssh -i /home/$USER/.ssh/id_rsa_remote -oStrictHostKeyChecking=no -N -R 2210:localhost:22 LOCAL_USER@LOCAL_IP


And finally, start the service and enable it so that it starts on every boot.

sudo systemctl daemon-reload
sudo systemctl start reverse_ssh.service
sudo systemctl enable reverse_ssh.service

Enable SSH (LOCAL)

  • Start the ssh service:
sudo service ssh start

SSH Access (LOCAL)

We are all set!

Access the REMOTE with:

ssh -i ~/.ssh/id_rsa_local -p 2210 REMOTE_USER@localhost