In this blog post, I’ll show you how to easily create an SSH tunnel to a remote server. I have learned that one of the big knocks against SSH tunnels is the complexity of creating them, commands involved, and less documentation around this topic. For end users, it can be difficult to master SSH commands, but My SSH commands cheatsheet can help get you  get to speed with SSH.

Perception of Open Source

The Open Source community has been pretty helpful in changing people perception of Linux and its myriad of tools. On fair criticism, Linux is no longer viewed as “that thing” for Geeks, nowadays, users with little technical experience can use it and learn as they break things a little, lol!

Introduction to Mole

The tool we’ll use to create SSH tunnel on Linux is Mole. Mole is a cli application to create ssh tunnels, forwarding a local port to a remote endpoint through an ssh server.

Mole helps you access computers and services blocked by a firewall, as long as the user has ssh access to a computer with access to the target computer or service.

+----------+          +----------+          +----------+
|          |          |          |          |          |
|          |          | Firewall |          |          |
|          |          |          |          |          |
|  Local   |  tunnel  +----------+  tunnel  |          |
| Computer |--------------------------------|  Server  |
|          |          +----------+          |          |
|          |          |          |          |          |
|          |          | Firewall |          |          |
|          |          |          |          |          |
+----------+          +----------+          +----------+
                                                 |
                                                 |
                                                 | tunnel
                                                 |
                                                 |
                                            +----------+
                                            |          |
                                            |          |
                                            |          |
                                            |          |
                                            |  Remote  |
                                            | Computer |
                                            |          |
                                            |          |
                                            |          |
                                            +----------+

With Mole, you can also access a service that is listening only on a local address with the help of Port forwarding. Learn how to Create Port Forwarding on CentOS 7 with Firewalld.

Also, note that Server and Remote Computer could potentially be the same machine.

+-------------------+             +--------------------+
| Local Computer    |             | Remote / Server    |
|                   |             |                    |
|                   |             |                    |
| (172.17.0.10:     |    tunnel   |                    |
|        50001)     |-------------| (172.17.0.100:22)  |
|  tunnel client    |             |  tunnel server     |
|       |           |             |         |          |
|       | port      |             |         | port     |
|       | forward   |             |         | forward  |
|       |           |             |         |          |
| (127.0.0.1:3306)  |             | (127.0.0.1:50000)  |
|  local address    |             |         |          |
|                   |             |         | local    |
|                   |             |         | conn.    |
|                   |             |         |          |
|                   |             | (127.0.0.1:3306)   |
|                   |             |  remote address    |
|                   |             |      +----+        |
|                   |             |      | DB |        |
|                   |             |      +----+        |
+-------------------+             +--------------------+

Highlighted Features of Mole

  • Auto local address selection: find a port available and start listening to it, so the flag-local doesn’t need to be given every time you run the app.
  • Aliases: save your tunnel settings under an alias, so it can be reused later.
  • Leverage the SSH Config File: Use some options (e.g. username, identity key, and port), specified in $HOME/.ssh/config whenever possible, so there is no need to have the same SSH server configuration in multiple places.

How to install Mole on Linux / macOS

Installing Mole on Linux is through an installation script that can be downloaded with curl

curl -O https://raw.githubusercontent.com/davrodpin/mole/master/tools/install.sh

Once the script is downloaded, make it executable then install

chmod +x install.sh
./install.sh

This script will install mole under,/usr/local/bin but it needs administrator privileges in order to deploy the file. It may require you to type your sudo password.

You can confirm file location  and version using the commands:

$ which mole
/usr/local/bin/mole

$ mole --version
mole 0.2.0

To view help page, use the --help option

$ mole --help
usage:
  mole [-v] [-local [<host>]:<port>] -remote [<host>]:<port> -server [<user>@]<host>[:<port>] [-key <key_path>]
  mole -alias <alias_name> [-v] [-local [<host>]:<port>] -remote [<host>]:<port> -server [<user>@]<host>[:<port>] [-key <key_path>]
  mole -alias <alias_name> -delete
  mole -start <alias_name>
  mole -help
  mole -version
	
  -alias string
    	Create a tunnel alias
  -delete
    	delete a tunnel alias (must be used with -alias)
  -help
    	list all options available
  -key string
    	(optional) Set server authentication key file path
  -local value
    	(optional) Set local endpoint address: [<host>]:<port>
  -remote value
    	set remote endpoing address: [<host>]:<port>
  -server value
    	set server address: [<user>@]<host>[:<port>]
  -start string
    	Start a tunnel using a given alias
  -v	(optional) Increase log verbosity
  -version
    	display the mole version

How to Use Mole to create SSH tunnel

Let’s look at few examples on how to use Mole to create SSH tunnel

Example 1: Provide all supported options

Create a tunnel with below details:

  • On localhost port 8080 
  • With alias tunnel1
  • To Server IP 192.168.18.50:80
  • Remote ssh user is vagrant, SSH server used is 192.168.18.51:22 
  • The authentication method is Public/Private SSH keys
  • SSh Public key location ~/.ssh/test_rsa.pub
  • SSH Private Key ~/.ssh/test_rsa

You need to have copied your Public ssh key to the remote SSH server used to tunnel

$ ssh-copy-id -i ~/.ssh/test_rsa.pub [email protected]

Import remote SSH server fingerprint by doing an ssh to the server

$ ssh -i ~/.ssh/test_rsa.pub [email protected]

Now create a tunnel:

$ mole -alias tunnel1 -v -local 127.0.0.1:8080 \
-remote 192.168.18.50:80 \
-server [email protected] \
-key ~/.ssh/test_rsa

To start the tunnel, use

$ mole -start tunnel1

Sample output

$  mole -start tunnel1

DEBU[0000] cli options                                   options="[local=127.0.0.1:8080, remote=192.168.18.50:80, [email protected], key=/home/jmutai/.ssh/test_rsa, verbose=true, help=false, version=false]"
DEBU[0000] server: [name=192.168.18.51, address=192.168.18.51:22, user=vagrant, key=/home/jmutai/.ssh/test_rsa] 
DEBU[0000] tunnel: [local:127.0.0.1:8080, server:192.168.18.51:22, remote:192.168.18.50:80] 
INFO[0000] listening on local address                    local_address="127.0.0.1:8080"
DEBU[0017] new connection                                address="127.0.0.1:36908"
DEBU[0017] known_hosts file used: /root/.ssh/known_hosts 
DEBU[0019] new connection established to server          server="[name=192.168.18.51, address=192.168.18.51:22, user=vagrant, key=/home/jmutai/.ssh/test_rsa]"
DEBU[0024] new connection established to remote          remote="192.168.18.50:80" server="[name=192.168.18.51, address=192.168.18.51:22, user=vagrant, key=/home/jmutai/.ssh/test_rsa]"
DEBU[0024] new connection                                address="127.0.0.1:36910"
DEBU[0024] known_hosts file used: /root/.ssh/known_hosts 
DEBU[0026] new connection established to server          server="[name=192.168.18.51, address=192.168.18.51:22, user=vagrant, key=/home/jmutai/.ssh/test_rsa]"
DEBU[0029] new connection established to remote          remote="192.168.18.50:80" server="[name=192.168.18.51, address=192.168.18.51:22, user=vagrant, key=/home/jmutai/.ssh/test_rsa]"

Example 2: Use the ssh config file to lookup a given server host

You can add ssh configuration for remote SSH server to ~/.ssh/config, then call its name while running mole.

$ cat .ssh/config
Host rserver1
  Hostname 192.168.18.51
  User vagrant
  Port 22
  IdentityFile ~/.ssh/test_rsa

Then create a tunnel

$ mole -alias tunnel1 -v -local 127.0.0.1:8080 \
-remote  192.168.18.50:80 \
-server rserver1

You can also use :8080 instead of 127.0.0.1:8080

$ mole -alias tunnel1 -v -local :8080 \
-remote 192.168.18.50:80 \
-server rserver1

$ mole -start tunnel1

Same for remote server Port

$ mole -alias tunnel1 -v -local 127.0.0.1:8080 \
-remote :80 \
-server rserver1

Example 3: Let mole to randomly select the local endpoint

You should have noticed we specified the local port 8080 to use for tunneling traffic with option -local 127.0.0.1:8080. Mole can randomly choose unused TCP port for you.

For this, example will change to

$ mole -alias tunnel1 -remote 192.168.18.50:80 -server rserver1
$ mole -start tunnel1

A local address to access from will be printed out

INFO listening on local address local_address="127.0.0.1:36683"

Confirm that you can access a web server on a remote server using the tunnel.

To delete SSH tunnel, run:

$ mole -delete -alias tunnel1

I hope these few examples were helpful in helping you create an SSH tunnel to a remote server, which could be behind a firewall. You can contribute to this Project on Github.