If you have read the previous article of this series, you should be  able to create forward and reverse tunnels with ease. In addition to the  previously shown examples I will address some more advanced options for  SSH tunnels in general.

Article seriesSSH tunnelling for fun and profit

  1. Local vs Remote
  2. Tunnel options
  3. AutoSSH
  4. SSH Config

SSH Login shell

Remember the following example:

ssh -L 5000:localhost:3306 black@justla.me

Once you have executed the above command, a tunnel is established.  However, you will also be logged in into the remote server with a SSH  session. If you simply want to do some port forwarding you will not need  or might not even want a remote login session. You can disable it via -N, which is a very common option for SSH tunnels:

ssh -N -L 5000:localhost:3306 black@justla.me

The -N option is also very useful when you want to create SSH tunnels via cron

ArgumentExplanation-NAfter you connect just hang there (you won’t get a shell prompt)
SSH man: Do not execute a remote command.
Note: Only works with SSHv2

So if you are not going to execute remote commands and will not need a  login shell, you also do not need to request a pseudo terminal in the  first place.

ssh -T -N -L 5000:localhost:3306 black@justla.me

ArgumentExplanation-TDisable pseudo-terminal allocation.
This makes it also safe for binary file transfer which might contain escape characters such as ~C.

SSH tunnel via cron

Imagine you want to have a SSH tunnel be established (or checked and  if it doesn’t run re-opened) via cron every hour. For that to work, SSH  must go into background. For that we use -f.

ssh -f -L 5000:localhost:3306 black@justla.me

ArgumentExplanation-fRequests ssh to go to background just before command execution.

But hey, if SSH is in the background anyway, we do not need a login shell (-N) and therefore also do not need a tty (-T). So the full command ready for cron would be:

ssh -f -T -N -L 5000:localhost:3306 black@justla.me

Note: Be aware that this example requires private/public key authentication as cron will not be able to enter passwords.

SSH tunnel on a non-standard port

What if the SSH server is listening on a non-standard port (not  tcp22). You can always add a port option. Let’s imagine SSH itself is  listening on port 1022:

ssh -T -N -L 5000:localhost:3306 black@justla.me -p 22

ArgumentExplanation-pPort to connect to on the remote host.

SSH tunnel with a non standard private key

Let’s assume you have many different private keys for different  servers. If not explicitly specified, SSH will look for a file called ~/.ssh/id_rsa. In this case however, your file is called ~/.ssh/id_rsa-cytopia@everythingcli. So you will also pass this information to the tunnel command.

ssh -T -N -L 5000:localhost:3306 black@justla.me -i ~/.ssh/id_rsa_black

SSH tunnel via SSH config

The most complex example from this tutorial is:

ssh -f -T -N -L 5000:localhost:3306 black@justla.me -p 22 -i ~/.ssh/id_rsa_black

We all are lazy-ass and don’t want to type the whole thing every time we need a quick tunnel. This is where ~/.ssh/config comes into play.

Adding user and host

$ vim ~/.ssh/config
 Host cli
    HostName      justla.me
    User          black

With this, we have created an alias cli for host everythingcli.org with user cytopia. Now our command can be written like this:

ssh -f -T -N -L 5000:localhost:3306 cli -p 22 -i ~/.ssh/id_rsa_black

Adding port and identity file

$ vim ~/.ssh/config
 Host cli
    HostName      justla.me
    User          black
    Port          22
    IdentityFile  ~/.ssh/id_rsa_black

Now the ssh command looks like this:

ssh -f -T -N -L 5000:localhost:3306 cli

Adding tunnel config

In the above example we have a generic configuration for the host everthingcli.org which will work for normal ssh connection as well as for establishing a  tunnel. Let’s copy all of the above block under a new alias cli-mysql-tunnel and add the tunnel specific configuration:

$ vim ~/.ssh/config
 Host cli-mysql-tunnel
    HostName      justla.me
    User          black
    Port          22
    IdentityFile  ~/.ssh/id_rsa_black
    LocalForward  5000 localhost:3306

Now we can create the tunnel in a much shorter way:

ssh -f -T -N cli-mysql-tunnel