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
apt update
apt install openssh-server
Add an user called tunnel
tunnel
useradd -m -s /bin/bash tunnel
Setup the RSA key
Login as tunnel
user.
su - tunnel
Create an RSA key.
ssh-keygen -t rsa -b 4096
Now authorize tunnel's user RSA public key in its authorized_keys.
Copy the RSA public key.
cat /home/tunnel/.ssh/id_rsa.pub
Now edit /home/tunnel/.ssh/authorized_keys
nano /home/tunnel/.ssh/authorized_keys
Add the following content.
command="",restrict,port-forwarding PUT-THE-PUBLIC-KEY-HERE
It will look like this.
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]
Copy the content of the following files (we will use them to set up the on-premisse server).
cat /home/tunnel/.ssh/id_rsa
cat /home/tunnel/.ssh/id_rsa.pub
Setup the on-premisse server
This server will open the reverse tunnel to the tunnel server.
Install SSH server
apt update
apt install openssh-server
Setup the RSA key
Let's suppose you want the user ubuntu to be able to open the tunnel.
Create the RSA key.
nano /home/ubuntu/.ssh/tunnel.id_rsa
Paste the content from /home/tunnel/.ssh/id_rsa
you copied from the tunnel server.
Fix permissions.
chmod 700 /home/ubuntu/.ssh/tunnel.id_rsa
Add tunnel server's public RSA to authorized keys.
nano /home/ubuntu/.ssh/authorized_keys
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.
/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 tunnel@PUT-YOUR-TUNNEL-SERVER-HOST-HERE
Replace PUT-YOUR-TUNNEL-SERVER-HOST-HERE
with your tunnel server host or IP.
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.
netstat -natp |grep 1822
You should see something like.
tcp 0 0 127.0.0.1:1822 0.0.0.0:* LISTEN -
Now test the tunnel.
ssh -o StrictHostKeyChecking=no ubuntu@localhost -p 1822
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.
sudo nano /etc/systemd/system/ssh-tunnel.service
With the following content.
[Unit]
Description=Create a tunnel in the cloud back to SSH on this machine
After=network-online.target
[Service]
User=ubuntu
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 tunnel@PUT-YOUR-TUNNEL-SERVER-HOST-HERE
RestartSec=3
Restart=always
[Install]
WantedBy=multi-user.target
Replace PUT-YOUR-TUNNEL-SERVER-HOST-HERE
with your tunnel server host or IP.
Then start and enable the service to start on boot.
sudo systemctl daemon-reload
sudo systemctl enable ssh-tunnel.service
sudo systemctl start ssh-tunnel.service
Last updated