Nov 212011
 

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.

Enhanced by Zemanta

Popular Posts:

Flattr this!

  14 Responses to “Permanent SSH Tunnels with autossh”

  1. 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.

  2. 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

  3. 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’

  4. If you don’t include -o ExitOnForwardFailure=yes as an option when autossh reconnects after an interruption you’ll get Warning: 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.

  5. 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

  6. 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?

  7. 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.

  8. Typo: ssh-kegen should be ssh-keygen

  9. 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

  10. 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!!

  11. 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

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*