Article by Truelite.it already published on their useful wiki (in Italian)
There are many occasions where you need to create connections to machines and services that are protected by firewalls because it is appropriate to adequately protect them, but for which the creation of a VPN becomes an excessive burden.
For this reason, the ability to port forwarding via SSH is very useful for creating an encrypted tunnel from one machine to another, allowing you to enable only local access (such as a MySQL only listens locally) safely, with the only the problem that in case of problems, the SSH connection (and its tunnels) could fall.
To solve this possible problem and allow you to create permanent tunnels autossh
come to your help, a simple program that allows you to run an instance of ssh
keeps it under control, and restarting the same istance once that the connection is dropped up to a maximum number of times controlled by the environment variable AUTOSSH_MAXSTART
or indefinitely if the value of this is negative (the default).
The program detects whether the instance of ssh
that it has launched terminates for a signal or a connection error and in this case it re-run it, but if you end of ssh
comes with a signal of SIGKILL
autossh interprets it as a explicit termination, and stops itself. Similarly,is interpreted a termination signal to autossh
itself, which in this case stop itself and his instance of ssh
.
The command takes a primary option, -M
that allows you to specify a monitoring port for the connection (ie to verify that the instance of ssh
is up and running using the port indicated and the next to send the message that should go back). With version 2 of the ssh
Protocol it supports an internal control of the connection, which is more reliable, therefore we suggest using the appropriate control options (which we will see later) and always indicate a null value (ie -M 0
), which disables this kind of monitoring.
The rest of the program’s behavior is controlled by a number of other environment variables to the meaning of which check the manual page (the default values are suitable for ordinary use, they can be modified in case of problems or to enable diagnostic).
The use of autossh
allow you to create an arbitrary number of tunnels in a very safe way, if you do not need to listen on reserved ports (<1024), you can run the program with an unprivileged user , which in our case will be precisely autossh
.Create that user on both ends of the tunnel with:
useradd -m -s /bin/false autossh |
please note as the user has disabled the shell and has not set a password, which will make it impossible to use the user for access to the system (which we do not need since it is only used to create the tunnel) .
The decision to not set the password for the authentication requires the use of keys, which is anyway the best choice and if possible to use exclusively. For this to the start of the tunnel connection you have to create the key for the user, that if you want the tunnel to start automatically at startup, will be without a passphrase, for this you must run the following commands:
root@hain:~# su -s /bin/bash autossh autossh@mail:/root$ ssh-kegen Generating public/private rsa key pair. Enter file in which to save the key (/home/autossh/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/autossh/.ssh/id_rsa. Your public key has been saved in /home/autossh/.ssh/id_rsa.pub. The key fingerprint is: b6:b7:d5:1e:fd:b0:62:57:b5:77:4c:33:82:78:f7:06 autossh@dodds The key's randomart image is: +--[ RSA 2048]----+ | | | | | . . | | . o E oo| | S . . +o=| | . . . ==| | . . . =.+| | . oo..+.| | .. oo .| +-----------------+
(you must use su
with the first command to impersonate the user autossh
as this has not a shell or a valid password).
Once this is done you should take care to copy the public key on the machine/s and/or destination and install it in the user’s home of autossh
in the file .ssh /authorized_keys
; check that this file belongs to the user autossh
.
Once this is done you can create a tunnel just by running the opportune command on ssh
through autossh
. Since you only want to bring up the tunnel you need to use the option -N
to tell ssh
to not run any commands, the option -f to put it in the background, and these options are also important:
-o "ServerAliveInterval 60" -o "ServerAliveCountMax 3"
that activate the monitoring of the existence with the internal connection of ssh
, the tunnel can then be activated with the usual options -L
or -R
depending on the direction of the tunnel.
So for example if you want to create a tunnel to connect to a remote MySQL database on a machine that is accessible via SSH, once created the users, as described, it will be sufficient to run the command:
su -s /bin/sh autossh -c 'autossh -M 0 -q -f -N -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -L 3306:localhost:3306 autossh@remotemachine' |
and at least the first time you have to accept the validity of the key fingerprint.
To enable the tunnel permanently at boot the easiest thing to do is to put the command in /etc/rc.local
or similar files that are run at your system startup.
Popular Posts:
- None Found
You may want to have a look at this startup script for autossh: http://surniaulula.com/2012/12/10/autossh-startup-script-for-multiple-tunnels/. You can create multiple tunnel connections, and start/stop each one independently. 😉
js.
Hello jean,
Thanks a lot for your info and your init script.
I’m not sure why but the “-q” switch you include does not appear to work on CentOS 6.4. And even though it “fails to work as expected”, unfortunately the command still appears in ps afwwwx | grep 8888 and doesn’t output any errors I could see explaining the failure reason.
The following command definitely does work:
su -s /bin/sh autossh -c ‘autossh -M 0 -f -gNC -o “ServerAliveInterval 60” -o “ServerAliveCountMax 3” -oPort=8888 -L1522:localhost:1521 -L11000:localhost:10082 -L11001:localhost:80 -L11002:localhost:443 -L5903:localhost:5901 autossh@remoteservername’
I hope this is of use to someone
Ricki
To enable the tunnel permanently at boot the easiest thing to do is to put the command in /etc/rc.local or similar files that are run at your system startup.
Need to specify the full path of autossh command
su -s /bin/sh autossh -c ‘/usr/local/bin/autossh -M 0 -q -f -N -o “ServerAliveInterval 60” -o “ServerAliveCountMax 3” -L 3306:localhost:3306 autossh@remotemachine’
If you don’t include
-o ExitOnForwardFailure=yes
as an option when autossh reconnects after an interruption you’ll getWarning: remote port forwarding failed for listen port #####
.This is because the host you’re connecting too may not realize the previous connection has died, and is still occupying the port. While the new autossh connection will succeed, it wont open a tunnel and autossh wont restart since it thinks the connection is okay.
Hi,
Thank you so much for this great tutorial, I was trying to figure out a way to do it since yesterday.
I did as written above and I can’t connect to autossh@localmachine but only to root@localmachine.
I created a user as described :”useradd -m -s /bin/false autossh”
I created the RSA key.
And when I tried to copy the key to the local machine with: “ssh-copy-id autossh@localmachine” I had to enter a password even though I didn’t set one.
The only way for me to get it working was by transferring the key to root@localmachine. Then I was able to enter the password and now it worked.
I’m wondering if it is safe to make the remote device connect to the root ?
Best regards,
Johann
Would have been nice to tell us what autossh is, and where to get it? I’m guessing it’s a shell script from some random place?
http://www.harding.motd.ca/autossh/
If you use ubuntu/debian or mint you already have it on your standard repositories
I ran into issues using this method.. after a lot of hunting, testing, and research (I’m no expert on Linux) it turned out that my autossh user on the “local” server was locked out. If you check /var/log/auth.log you should see a series of errors for that account if this affects you. Since I am using unsigned keys to establish the tunnel, I didn’t want to authenticate to my account in case the key gets compromised.
the user was set to /bin/false in /etc/shadow, so it couldn’t log in and apparently couldn’t establish the tunnel. I unlocked the user
passwd -u autossh
(if I remember right), and set a 24 random character password to the account since I never need to log into it using the password (and can’t according the shadow file.I hope this helps someone else from the headaches that I just went through.
Typo: ssh-kegen should be ssh-keygen
[…] Permanent SSH Tunnels with autossh […]
the command was running but no connection was being made, I had to
replace things like these -o “ServerAliveCountMax 3 with –o “ServerAliveCountMax=3”
the “=” sign was critical, everything works fine now.
my final command
autossh -M 0 -q -f -gNC -o “ServerAliveCountMax=3” -o “ServerAliveInterval=10” -o “ExitOnForwardFailure=yes” -R xxxx:localhost:22 auto ssh@remotehost
just in case it helps anyone who might be struggling
Ravi’s last comment above (#10) was huge…. huge….. help, and absolutely spot on. I had been struggling with frustrating timeouts on large multi-hundred-MB git pulls for weeks…. and his point about “=” sign being critical in the -o options is 100% correct.
I put those in my autossh command, and presto — no timeouts, the git pull runs, and everything works.
Ravi — thank you!!
Ravi’s last comment above (#10) was a really huge…. huge….. help, and absolutely spot on. I had been struggling with frustrating timeouts on large multi-hundred-MB git pulls for weeks…. and his point about “=” sign being critical in the -o options is 100% correct.
I put those in my autossh command, and presto — no timeouts, the git pull runs, and everything works.
Ravi — thank you!!
-Ian