Home > Linux, Security > Setting up a permanent SSH tunnel between 2 servers

Setting up a permanent SSH tunnel between 2 servers

Greeting everyone,

Today, I’ll show you how to setup an easy and permanent SSH tunnel that auto reconnect in case of failure between two linux servers.

It may happen (for your own personal reason) that you need to connect 2 remote server together, and this, with a minimum of security (Not plain text but SSL communications)

I’ve been looking on ssh/sshd for the options that allows you to setup a TCP tunnel between 2 remote hosts.

The command for doing it is pretty easy:

 pierre@linux.edu:~$ ssh -L 11223:localhost:23344 pierre@remote-server.com

This command will connect as “pierre” on “remote-server.com”, opening a local TCP port from my localhost:11223 to the remote’s server localhost:23344 (See man ssh to get more explanations)

NOTE: Using port < 1024 will need root privileges


The 1st problem, every time I hit this, it ask me for a password!

Well, SSH as the solution for it :D

This is call “key exchange”, the idea is to create a personal key to connect on the remote server

Configure ssh auto-login:

Create both of your public and private key by running:

pierre@linux.edu:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/pierre/.ssh/id_rsa):
Created directory '/home/pierre/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/pierre/.ssh/id_rsa.
Your public key has been saved in /home/pierre/.ssh/id_rsa.pub.
The key fingerprint is:
ed:3e:d7:62:48:7e:2b:f1:d5:94:e3:13:ee:7a:fa:aa pierre@phpmyadmin.linux.edu
The key's randomart image is:
+--[ RSA 2048]----+

Good, now you should 2 files, one is id_rsa.pub and it contain your public key, the other one is id_rsa and it has the private key to encrypt data to the remote server.

Public key should look like this:

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxGc51/0BL51jV5B2EFwE4vqcvvB0PKCErsRAzzWluyNZ1/J1V3HbtwYRf9H38LJgeNYWPgBVe9BGAPTklj/MJZwtWwvhHFP/V+IaHLNbr7pW/wJdIEyRAU4i8xZNkyrlhBIPc+0b1j41PWuh3B5JorxyueP1nlcWn0xm6q5BdRiiyAKc/n1pbnTNQ1MP5YbEdaAI3K3eao5JXm5m4KcR30F+KGRg6u5Sla9qWReYgK9IF7FRL9tzSOzfoLLdLUCIBEQBpHMata3GWXJwGMRJMJp4Iw2tvb6PGNvc/MlrasJNqUef8u/TLHKYrV/0F5Z3T5HO3ZyzvxTHXsahnagP8w== pierre@linux.edu

To enable auto ssh login without being prompt for a password, create the ./~ssh/authorized_keys2 and copy the public key into it.

Run ssh -L again and tadaa, you are logged without password :)

Final step, what happen when links goes down? Eg, when the server reboot or loose the connections?

Well, it disconnect.

I’ve been searching for many solutions to detect disconnection and reconnect link automatically, and probably the most light and easy software for making that is call: autossh.

Unfortunately, autossh doesn’t come precompiled with a Debian package. So I had to download and compile it from source.

Installation:

Wget http://www.harding.motd.ca/autossh/autossh-1.4b.tgz
Tar zxvf
./configure
Make

And as root, make install

Normally, there should be a binary in “/usr/local/bin/autossh”

Finally, my little script

#!/bin/sh
#
# Example script to start up tunnel with autossh.
#
# This script will tunnel 12345 from the remote host
# to 12345 on the local host.
#
ID=login_here
HOST=destination.host.com
if [ "X$SSH_AUTH_SOCK" = "X" ]; then
 eval `ssh-agent -s`
 ssh-add $HOME/.ssh/id_rsa
fi
AUTOSSH_POLL=600
AUTOSSH_PORT=20000
AUTOSSH_GATETIME=30
AUTOSSH_LOGFILE=$HOST.log
AUTOSSH_DEBUG=yes
AUTOSSH_PATH=/usr/bin/ssh
export AUTOSSH_POLL AUTOSSH_LOGFILE AUTOSSH_DEBUG AUTOSSH_PATH AUTOSSH_GATETIME AUTOSSH_PORT
autossh -2 -fN -M 20000 -L 12345:localhost:12345 ${ID}@${HOST}

Enjoy :)

Categories: Linux, Security Tags: ,
  1. Søgemaskineoptimering
    November 19th, 2010 at 21:39 | #1

    This is just great. You don’t know how long i was Googeling after this info

  2. nelson
    March 25th, 2011 at 20:35 | #2

    how do you make it auto start when system restart? thanks

  3. Jesse Kaufman
    April 19th, 2011 at 20:51 | #3

    Another quick-and-dirty way of making this happen is by using /etc/inittab … add the following to /etc/inittab:

    tunl:2345:respawn:/usr/bin/ssh -n -N -T -L localhost:3306:remotehost:3306 remoteuser@remotehost

    Make sure the ’2345′ part matches the runlevels you want it to be running on (in this case, a debian system that defaults to runlevel 2, but i left the others in for RedHat-based systems).

    after making the change, type ‘init q’ (as root) to reload the config … you should now have an “always-on” tunnel! :)

    Of course, that implies you followed all of the above about key-pair authentication ;)

    The extra options in my ssh command are probably optional (maybe some are even redundant), it’s just what i’ve been using for years:

    -n prevents reading from stdin
    -N do not execute a remote command
    -T disable pseudo-tty allocation

    Also note that in my version, I’m using an SSH tunnel to connect to a remote MySQL server, hence the 3306. I didn’t want to have to update existing code, so I used the standard MySQL port. The ‘localhost’ before the port tells it only to listen for local connections (though that’s probably redundant if you don’t have GatewayPorts enabled … if enabled, it allows you to share the tunnel with other machines, which I don’t need).

    I notice in your example, it shows the binding as “11223:localhost:23344″ … changing that to “3306:localhost:3306″ didn’t work for me and it seemed to cause a loop or something (???) … Not really sure on that, but I’m guessing it’s because I’m using the same ports for both. But, it works great specifying it as “3306:remotehost:3306″ … would be interested to know if there are any other caveats about the way I’m doing that.

    Anyway, thanks for the info and hope my info is helpful as well :)

  4. April 20th, 2011 at 01:38 | #4

    Quite a nice comment!!

  1. No trackbacks yet.
*