Start Reverse Tunnel on boot using autossh for Debian 7

As usual, most of the how-to guides out there are too brief (I’m guilty) or apply to other distros:

This works on Linux Debian 7 all-around, and this is a complete how to. It works. You just have to follow a very long thread. No A.D.D. here!

We will create a Persistent Reverse SSH Tunnel between 2 machines using autossh. We will be using our desktop as a third machine.

This is convoluted, but then good things are seldom easy.

If you are not very experienced with Private/Public key GPG encryption, doing reverse tunneling is doubly confusing. Not only is a reverse tunnel a convoluted concept, then you also have the equally convoluted issue of Private/Public Key Encryption to deal with. So one-issue-at-a-time-and-slowly;

It may be helpful to draw (on paper) a diagram;

1) Our Hidden machine is the one behind the firewall (behind NAT) – you know this machine or you would not be reading this. Our Hidden machine will call and create a tunnel using a known server. That server is called our Remote machine.

2) Our Remote machine is the one that will be contacted by the Hidden machine. The Remote machine is typically a (middle-man) server that has a static IP address. The static IP is the key. The Hidden machine needs to reach out and create the tunnel using a known static IP address or this does not work. The connection is built in reverse. Thus why it’s called “a reverse tunnel”.

3) Our Desktop machine is probably/also behind a firewall and will login to the Remoter server normally. Then we use the Remote Server to login to the Hidden machine that is waiting for our login.

Each machine should have different usernames (for your first go at this). Its not mandatory, but it cuts down on the confusion. Check?

You’ll need to have/generate SSH PGP/GPG keys for each user/machine. Check?

When creating your keys, DO NOT use pass words or pass phrases, just accept all defaults.

Generate your SSH GPG keys

ssh-keygen -t rsa

Now the tricky part is to get the appropriate keys placed on all the machines before hand. That is because we can’t have passwords/login prompts interfering with one machine logging into the other. Such a pause causes everything to hang…

Ordinarily, no problem. But this is a real problem concerning the Hidden machine. The Remote machine key needs to be found in /home/username/.ssh/authorized_keys of our Hidden machine. But how do we do that if the Remote machine cannot call the Hidden machine? Its called manual labor!

Assuming you have completed the creation of all key-pairs using default setup options;

1) Copy from the Hidden machine, it’s GPG public key to the Remote server;

cat .ssh/ | ssh -v -p 22 'cat >> .ssh/authorized_keys'


ssh-copy-id -i .ssh/ "-p 22"

Now comes the manual labor (messy) part;

2) Copy the Remote keys to your Desktop somehow. This is probably a few-step process. I first save the authorizes_keys into my Remote machine home directory, then Rsync them back to the Desktop machine.

sudo cp -f ~/.ssh/authorized_keys ~/

Now get the authorized_keys file into the Hidden machine’s /home/username/.ssh/authorized_keys

Others may give you more concrete methods to do this “messy” business. But that’s just normal Linux stuff beyond the scope of this post. Therefore, you will have to manage the permissions and transport of the file yourself. I use Rsync to move files and preserve permissions. In the end, just be sure your permissions are set correctly or none of this will work.

chown -R username:username /home/username/.ssh
chmod 644 -R /home/username/.ssh
chmod 700 /home/username/.ssh
chmod 600 /home/username/.ssh/authorized_keys
chmod 600 /home/username/.ssh/id_rsa

Make sure to open/unblock appropriate ports on the Remote machine. In this case ports xxx5 – xxx8. Use your own ports, just greater than 2000 to be on the safe side (or…).

on the Remote machine open ports:
xxx5 & xxx6 will be used by autossh
xxx7 & xxx8 will be used by ssh

Add Allowed users and enable listening ports
sudo vi /etc/ssh/sshd_config

port xxx8 # needs to be listening for an ssh connection
(just FYI) port xxx7 will be forwarded as you will see
AllowUsers username-of-hidden-machine-user

On Hidden machine (the default is already):
port 22 # needs to be listening for an ssh connection
AllowUsers username-of-remote-machine-user

sudo service ssh restart

Before we setup autossh to create and maintain our Persistent tunnel…

This part is only a test

…we need to introduce our two machines so they know each other in the future (known_hosts). We need to do this only once manually. So from our Hidden machine create a typical Reverse SSH Tunnel;

ssh -2R xxx7:localhost:22 -p xxx8 -fNvvv

-vvv means very-very-very verbose

which we want.

You will be asked to accept the connection.

Type “yes”

On the Remote machine you will see the connection being established using;

tail -f /var/log/auth.log

the output should look something like this
Dec 14 17:07:28 Remote_server sshd[10544]: debug1: trying public key file /home/username/.ssh/authorized_keys
Dec 14 17:07:28 Remote_server sshd[10544]: debug1: matching key found: file /home/username/.ssh/authorized_keys, line 1
Dec 14 17:07:28 Remote_server sshd[10544]: Found matching RSA key:
Dec 14 17:07:28 Remote_server sshd[10544]: debug1: ssh_rsa_verify: signature correct
Dec 14 17:07:28 Remote_server sshd[10544]: Accepted publickey for username from port 54889 ssh2
Dec 14 17:07:28 Remote_server sshd[10546]: debug1: PAM: establishing credentials
Dec 14 17:07:28 Remote_server sshd[10546]: debug1: server_input_global_request: tcpip-forward listen localhost port xxx7
Dec 14 17:07:28 Remote_server sshd[10546]: debug1: Local forwarding listening on port xxx7.
Dec 14 17:07:28 Remote_server sshd[10546]: debug1: channel 0: new [port listener]
Dec 14 17:07:28 Remote_server sshd[10546]: debug1: Local forwarding listening on :: port xxx7.

sudo watch netstat -plunt

netstat -plunt will show you the established connection (the tunnel). Here you can clearly see the port and username
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0* LISTEN 10546/sshd: username
tcp6 0 0 :::xxx7 :::* LISTEN 10546/sshd: username

End of Test

How to setup autossh to create the Reverse Tunnel
sudo apt-get install autossh
sudo vi /etc/rc.local

add this line

su localusername -c 'autossh -N -f -M xxx5 -R xxx7:localhost:22 -p xxx8' &
BEFORE exit 0

sudo chmod 755 /etc/rc.local
sudo reboot

(Hidden Machine)

Monitor the Remote machine
sudo tail -f /var/log/auth.log
sudo watch netstat -plunt

The assumption at this point > You are already logged into the Remote from your Desktop using SSH on a DIFFERENT PORT. I will not be including further instructions as that is beyond the scope. I assume you are knowledgeable enough to setup a standard SSH session between these two machines.

tail -f /var/log/auth.log will tell you what went wrong
netstat -plunt will show you the established connection (the tunnel)

If all goes well, you should see (on the Remote machine using netstat) the port and username where SSH is waiting for you to login from the Remote server to the Hidden machine:

on the Remote type

ssh -2vvv -p xxx7 username@localhost

When all is working well, you may want to

harden things by disabling password logins on SSH
sudo vi /etc/ssh/sshd_config

ChallengeResponseAuthentication no

You may also like...