SSH tunneling with Autossh

AutoSSH is a great tool for Linux administrators. SSH is a must-have – we are using it on daily basis. In many cases, it is just enough. The well-designed tool which is doing its job. From time to time, however, we need something more.

What can I use AutoSSH for?

AutoSSH is a tool to monitor and restart SSH sessions. It is checking the health of the connection and restarts SSH session if necessary. It is useful for non-reliable internet connections such as GSM or in cases when the connection parameters are changing from time to time (for example ISP is assigning new IP to the server from). We are using it to maintain reliable tunnel between our remote servers and main monitoring server.

Remote servers are located in the places where no static IPs are assigned and there is no possibility to open ports on the router. In this case, the connection has to be initiated from the remote host. We are simply creating the tunnel which is forwarding all connections to the port NNNN of monitoring host to the port 22 (SSH) of the remote host. In some cases, we are doing the same for the port 80 (HTTP) of the remote host if we want to forward web server data.

AutoSSH basic usage

AutoSSH is currently available as a package in most of the Linux distributions. You can install it using yum or apt. Once installed, it is ready to use. However, there is one important prerequisite: your SSH has to be able to connect without the password. You don’t want to enter password during each re-connection, don’t you?

The basic example of the autossh command is:

remote.host$ autossh -N -R 6000:localhost:22 user@monitoring.com

The command above should be started on the remote host. It simply creates the tunnel which is forwarding monitoring host port 6000 to the local port 22. This means that I can now run the following command on the monitoring host:

monitoring.com$ ssh remoteuser@localhost -p 6000

Please note that I’m connecting to the localhost’s port number 6000. No need to know IP of the remote server, the tunnel is already there. This also shows one important thing – there can be only one remote host connected to the single port of the monitoring server. Each additional connection has to be placed on the other port.

But I want it to start during the server boot!

Nowadays the most convenient way to run autossh on boot time is to use systemd service. Let’s create the file named autossh-tunnel.service in /etc/systemd/system/ and paste this code into it:

[Unit]
Description=AutoSSH tunnel service Remote port 6000 to local 22
After=network.target

[Service]
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh -o "ServerAliveInterval 10" -o "ServerAliveCountMax 3" -N -R 6000:localhost:22 user@monitoring.com

[Install]
WantedBy=multi-user.target

There are few important things to note – first, the environment variable. Systemd does not support & or -f option to run the service in the background. The environmental variable tells autossh not to wait for the first connection to succeed, but immediately go to background and restart even if this first connection will fail. We also added ServerAliveInterval and ServerAliveCountMax – this tells SSH to test the connection every 10 seconds and assume failure after 3 consecutive failed messages. Such configuration ensures a quick recovery after the connection failure.

Once we have the service file created, we should let systemd know that we changed something, we can start the service and we can enable it to run during the boot time:

remote.host$ systemctl daemon-reload
remote.host$ systemctl start autossh-tunnel.service
remote.host$ systemctl enable autossh-tunnel.service

We can now test our new tunnel the same way we did before.

What else can I do?

You can also create the tunnel which is working the other way. In some cases, we are using it to forward remote port 80 to the local port 8080 to forward some API calls. The only change you have to do is to change the part of the configuration. Such tunnel can be created like so:

remote.host$ autossh -N -R 8080:localhost:80 user@monitoring.com

Now, on the remote host, you can access monitoring.com HTTP by opening http://localhost:8080/ – the request will be forwarded through the tunnel to the monitoring host.

6 Replies to “SSH tunneling with Autossh”

    1. You are right, my last example was wrong, I wrote -L instead of -R. I updated the post. Thanks!

    1. It depends on what you want to achieve. In the typical situation, the Autossh process is trying to connect over and over again. You can create a kind of watchdog which will let you know when the connection is down. Can you let me know what scenario are you thinking of?

  1. Good info. Is autossh smart enough to re-resolve the IP address of (in your example) “monitoring.com” via DNS *each* time it needs to re-establish a connection to the remote SSH server? Or does autossh only resolve the IP for monitoring.com one time, at startup? I ask, because in my possible future use case the remote SSH server’s IP address might change occasionally without notice, although the DNS A-record for its IP address should always be kept up to date.

    1. Yes, it is resolving DNS on subsequent connections. The question is: for how long your system caches the DNS responses? 🙂

      I was using autossh on the DynDNS base connections with the frequently changed IP address (few times a day) and it was working.

Leave a Reply

Your email address will not be published. Required fields are marked *