DevOps Buzz
Search…
Bash / Shell
Bitbucket
Distros
Elasticsearch
General
Guidelines / Standards
microk8s
Prometheus
RabbitMQ
VirtualBox
Reverse tunnel
Open SSH connections to servers under NAT without needing to redirect ports on the router.
Consider the following scenario: you are about to deploy a server on-premisse and you cannot deal with router ports redirection and firewall rules.
The solution is open a reverse tunnel, so you have a secure backdoor open to SSH connections:

Setup the tunnel server

This server (which can be on the cloud) will handle all connections from on-premisse servers.

Install SSH server

1
apt update
2
apt install openssh-server
Copied!

Add an user called tunnel

1
useradd -m -s /bin/bash tunnel
Copied!

Setup the RSA key

Login as tunnel user.
1
su - tunnel
Copied!
Create an RSA key.
1
ssh-keygen -t rsa -b 4096
Copied!
Accept all defaults (do not input a password)
Now authorize tunnel's user RSA public key in its authorized_keys.
Remember we are creating a reverse tunnel. So the on-premisse server will use the same private RSA key, so the compatible public key must be authorized.
Copy the RSA public key.
1
cat /home/tunnel/.ssh/id_rsa.pub
Copied!
Now edit /home/tunnel/.ssh/authorized_keys
/home/tunnel/.ssh/authorized_keys
1
nano /home/tunnel/.ssh/authorized_keys
Copied!
Add the following content.
/home/tunnel/.ssh/authorized_keys
1
command="",restrict,port-forwarding PUT-THE-PUBLIC-KEY-HERE
Copied!
It will look like this.
/home/tunnel/.ssh/authorized_keys
1
command="",restrict,port-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQChoOyIa8Z5VtXm0AKYxsszkjwtfI7h4I00rgMQOKoWF6DR14l43fQrNq3I/lpUJBCOxHwcH6QkPCI/Oj8oXQkyg7NgpDBQ6y7IDaP5RX3MCUTcrjfvjUyuc3NPS3loB5g6bHFpkyULj9mmQp4/IOfCL55bzenQQSUQmmDk4LGAFQVjiBoIYFMEkpar87QYX/qktP2np+z3jpUD6Dz2F5MVccxbqsoHJZmSPBtw1rV9cr61HebPvrK5Ir6r50PXOVVRHbH0lILJdxOQOxbslDkcq5SypsEYSNsiAArWwzxM4YcXaTt/vzL8/fqsy8Nhx26BjmGTQ8Yptsl2KX7VdpF95Q7fHL7ElVr6C+COb2BOoEls/pHgCJzEbjKSnLPKTFacovPjzbch52MqCBNWsrr9JRHuxLP+35VgD5LqhVlGkeOuqKVx+TQcsp4ITKBpKX6d2iFni26SynjnzsLAdqOGSrYy7ZTRlHQnJGrY9LsbUrxVrM6+tZZq2PiCdbxhtsg1IKxp14lAF/L6ZOgpUxJlgZNIepxUfBYEEdwGIXHOhUv4/4ipmgMPCOVKlvTwNaGURW7RNHkn2iziYd7EUcWpKdkLK4IQMg9UXmbxg7HyhvZGcLBeLpmBnUBiN7+NJGbn/DLultYLcNIUN90FHgdJ+r0RE91FKsqW0UI0FLXJIw== [email protected]
Copied!
command="",restrict,port-forwarding will restrict the access. If someone get physical access to the on-premisse server it will not be possible to allocate a TTY using the RSA key.
Copy the content of the following files (we will use them to set up the on-premisse server).
1
cat /home/tunnel/.ssh/id_rsa
2
cat /home/tunnel/.ssh/id_rsa.pub
Copied!

Setup the on-premisse server

This server will open the reverse tunnel to the tunnel server.

Install SSH server

1
apt update
2
apt install openssh-server
Copied!

Setup the RSA key

Let's suppose you want the user ubuntu to be able to open the tunnel.
Create the RSA key.
1
nano /home/ubuntu/.ssh/tunnel.id_rsa
Copied!
Paste the content from /home/tunnel/.ssh/id_rsa you copied from the tunnel server.
Fix permissions.
1
chmod 700 /home/ubuntu/.ssh/tunnel.id_rsa
Copied!
Add tunnel server's public RSA to authorized keys.
1
nano /home/ubuntu/.ssh/authorized_keys
Copied!
Paste the content from /home/tunnel/.ssh/id_rsa.pub you copied from the tunnel server.

Test connection

From your on-premisse server

Open a tunnel to test the connection.
1
/usr/bin/ssh \
2
-o ServerAliveInterval=20 \
3
-o ServerAliveCountMax=3 \
4
-o ExitOnForwardFailure=yes \
5
-o StrictHostKeyChecking=no \
6
-i /home/ubuntu/.ssh/tunnel.id_rsa \
7
-N -T -R1822:localhost:22 [email protected]
Copied!
Replace PUT-YOUR-TUNNEL-SERVER-HOST-HERE with your tunnel server host or IP.
You can change the port 1822 to any port you want (just keep me same port for the rest of the tutorial)
This command will open a the tunnel using the port 1822 on the tunnel server. All connections on port 1822 on the tunnel server will be redirected to port 22 on the on-premisse server.
If everything is OK the command above will hang the tunnel. Leave it running.

From your tunnel server

Login as tunnel user and check if the tunnel port is open.
1
netstat -natp |grep 1822
Copied!
You should see something like.
1
tcp 0 0 127.0.0.1:1822 0.0.0.0:* LISTEN -
Copied!
Now test the tunnel.
1
ssh -o StrictHostKeyChecking=no [email protected] -p 1822
Copied!
You should be able to SSH to your on-premisse server.

Configure the tunnel as a service on the on-premisse server

Go back to your on-premisse server. You can cancel/stop the test tunnel we opened before.
Create the following file.
1
sudo nano /etc/systemd/system/ssh-tunnel.service
Copied!
With the following content.
/etc/systemd/system/ssh-tunnel.service
1
[Unit]
2
Description=Create a tunnel in the cloud back to SSH on this machine
3
After=network-online.target
4
5
[Service]
6
User=ubuntu
7
ExecStart=/usr/bin/ssh -o ServerAliveInterval=20 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -o StrictHostKeyChecking=no -i /home/ubuntu/.ssh/tunnel.id_rsa -N -T -R1822:localhost:22 [email protected]
8
RestartSec=3
9
Restart=always
10
11
[Install]
12
WantedBy=multi-user.target
Copied!
Replace PUT-YOUR-TUNNEL-SERVER-HOST-HERE with your tunnel server host or IP.
You can change the port 1822 to any port you want
Then start and enable the service to start on boot.
1
sudo systemctl daemon-reload
2
sudo systemctl enable ssh-tunnel.service
3
sudo systemctl start ssh-tunnel.service
Copied!