Autossh Reverse Tunnel

Autossh is a daemon that monitors ssh sessions to make sure they're up and operational, restarting them as needed. When that session is a reverse tunnel, where a ssh client opens a port back to itself so you can login in, you get a service that looks a lot like teamviewer or other remote access software without all the overhead.

This bypasses all the hurdles of client side NAT and firewalls with the only requirement being an open ssh server for the clients to reach.

Server

This is easy - simply install openssh-server, create a new user account and allow public connections so that user can login remotely. You may want to create an individual accounts for each client, but we'll do this example with just one account named 'remote'. Remote systems will use this local account on your server to connect.

sudo apt install openssh-server
# Modify the ufw command for your network and router as appropriate
sudo ufw allow from 192.168.1.0/24 to any app openssh
sudo adduser remote    

Client

For this to work as a service, you need to setup a ssh-key with a blank password.  In this example the service runs as root so that's the account you'll need to create a key with. (Yes, this is ringing warning bells. Consider investing time in a creating an autossh account if you're worried about the autossh binary being cracked).  We'll also configure this as an upstart job, in keeping with the new way of managing services.

Setup SSH Key and Test Creating a Tunnel

# You need an ssh server to accept connections
sudo apt-get install openssh-server

# Generate a key for root that autossh will use (Take the defaults and use an empty passphrase)
sudo -i
ssh-keygen 

# Copy your public key to the server
ssh-copy-id remote@some.public.host

# Test that you can login and accept the key
ssh remote@some.public.host
exit

# Test creating a reverse tunnel. If you're warned that 6666 isn't free, look for another port
ssh -N -R 6666:localhost:22 -o ServerAliveInterval=240 -o ServerAliveCountMax=2 remote@some.public.host
Ctrl-C

Install and configure autossh

sudo apt-get install autossh
sudo vim /lib/systemd/system/autossh.service

[Unit]
Description=autossh
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=autossh
EnvironmentFile=/etc/default/autossh
ExecStart=
ExecStart=/usr/bin/autossh $SSH_OPTIONS
Restart=always
RestartSec=60

[Install]
WantedBy=multi-user.target

sudo ln -s /lib/systemd/system/autossh.service /etc/systemd/system/autossh.service

sudo vim /etc/default/autossh

AUTOSSH_POLL=60
AUTOSSH_FIRST_POLL=30
AUTOSSH_GATETIME=0
AUTOSSH_PORT=22000
SSH_OPTIONS="-N -R 2222:localhost:22 remote@some.host.org -i /home/remoteUser/.ssh/id_rsa"






Using The Reverse Tunnel

If all went well, you'll notice a new port opened on your server; 6666. You can ssh to your server, then ssh to that port and it will connect you to the client, like so.

ssh allen@some.public.host
ssh localhost -p 6666

Notes

I've tried using the SSH client's ability to detect a broken tunnel and exit by employing the -M 0 and ServerAlive options. In practice, it fails to notice a broken session. I am testing with and without KeepAlives in. As this reduces the requirements for ports and echo service on the server, and is available in modern SSH versions. The details are in the man page for autossh

After you have it working, you may want to block the client from getting a shell on your server. Doing so beforehand will stop you from using the ssh-copy-id command, though you could always append keys by hand. Simply change the shell to the 'nologin' shell

sudo vipw

remote:x:1001:1001:,,,:/home/remote:/usr/sbin/nologin


Sources

https://www.async.fi/2013/07/autossh-with-ubuntu-upstart/
http://www.harding.motd.ca/autossh/README
https://patrickmn.com/blog/how-to-keep-alive-ssh-sessions/
https://raymii.org/s/tutorials/Autossh_persistent_tunnels.html
http://www.ubuntugeek.com/automatically-restart-ssh-sessions-and-tunnels-using-autossh.html
http://askubuntu.com/questions/315027/why-dont-custom-upstart-job-names-tab-complete-in-the-service-command
Comments