Ssh – autossh not working for two or more tunnels – or is there an alternative

sshssh-tunnel

I am trying to use a SSH server as a gateway to connect to more than one internal servers. Internal in this context means that they are not accessible directly, they got no public IP assigned to them.

So the scenario should look like this (example with 2 servers, might be more) with the gateways public IP 123.456.789.45 the internal being 10.12.40.13

+--------+                 +---------+                +----------+
| client |--> 2214/tcp --> |         | --> 22/tcp --> | Server 1 |
+--------+                 |         |                +----------+
                           | Gateway |
+--------+                 |         |                +----------+
| client |--> 2215/tcp --> |         | --> 22/tcp --> | Server 2 |
+--------+                 +---------+                +----------+

My first approach was to set them up from the gateway to the servers with something like

ssh -N -L 123.456.789.45:2214:127.0.0.1:22 tunnel-user@server1
ssh -N -L 123.456.789.45:2215:127.0.0.1:22 tunnel-user@server2

While that works I stumbled upon the problem of the tunnels not being too reliable, failing every here and there. The logical next step was trying to get autossh running. And here I got a bunch of problems. The first tunnel can be established without problems using

autossh -M 20000 -f -N -L 123.456.789.45:2214:127.0.0.1:22 tunnel-user@server1

I can get access to server1 by outside connecting to the gateway at port 2214. However I can't get the second one up and running with autossh. Headbanging a couple of hours now I decided to try it vice versa. So:

The second approach was to set them up from the servers to the gateway. Again while the variant with pure ssh works using something like this …

ssh -R 123.456.789.45:2214:127.0.0.1:22 tunnel-user@gateway # <- init from server 1
ssh -R 123.456.789.45:2215:127.0.0.1:22 tunnel-user@gateway # <- init from server 2

… using autossh fails.

autossh -M 20000 -f -R 123.456.789.45:2214:127.0.0.1:22 tunnel-user@gateway

The logfiles simply says nothing. Syslog at least comes up with

ssh exited prematurely with status 0; autossh exiting

Now does anyone know how to solve the autossh issue on either approach? Is there something similar to autossh that I can give a shot? Is there a way to maybe achieve something like a refresh on the pure ssh version mentioned above?


All involved servers are running the latest updates on Ubuntu 10.04 LTS and autossh 1.4b

Best Answer

From the autossh documentation:

autossh uses ssh to construct a loop of ssh forwardings (one from local to remote, one from remote to local), and then sends test data that it expects to get back.

-M port[:echo_port] specifies the base monitoring port to use. Without the echo port, this port and the port immediately above it ( port + 1) should be something nothing else is using. autossh will send test data on the base monitoring port, and receive it back on the port above. For example, if you specify "-M 20000", autossh will set up forwards so that it can send data on port 20000 and receive it back on 20001.

if you are using -M 20000 twice, this must fail. Use different ports for that (with one port space between them, so -M 20000 and -M 20002 would work). I recommend doing a "man autossh" and read the documentation of autossh, its also available online: http://www.manpagez.com/man/1/autossh/ . If you are using a lot of autossh tunnels, you may setup a dedicated echo service (From autossh documentation again):

Alternatively, a port for a remote echo service may be specified. This should be port 7 if you wish to use the standard inetd echo service. When an echo port is specified, only the specified monitor port is used, and it carries the monitor message in both directions. This allows the autossh to verify the connection without blocking ports for each tunnel on the remote side.

If you want to use xinetd for that, here is my echo service decleration:

service echo
{
        flags                   = REUSE
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/bin/cat
        log_on_failure          += USERID
        only_from               = 127.0.0.1
        disable                 = no
}

then you can use -M 20000:7 on all tunnels from different machines. if you have multiple tunnelns on one machine, use multiple -L or -R options or use a different port like -M 20002:7

Related Topic