Skip to the content.

Mole is a cli application to create ssh tunnels focused on resiliency and user experience.

$ mole start local --remote :3306 --server my-database-server
INFO[0000] tunnel channel is waiting for connection      destination="127.0.0.1:3306" source="127.0.0.1:32863"

Highlighted Features

Table of Contents

Use Cases

…or why on Earth would I need something like this?

Access a computer or service behind a firewall

Mole can help you to access and/or expose services outside the perimeter network that are blocked by a firewall or unreachable, as long as the user has ssh access to a computer (known as Jump Server) with access to the target computer or service.

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

Access a service that is listening on a non-routable network

+----------------------------------------------+         +--------------------+
| Local Computer                               |         | Jump Server        |
|                                              |         |                    |
|                                              | tunnel  |                    |
|                           (172.17.0.10:5001)-+---------+---> ssh server     |
|                               mole           |         | (172.17.0.100:22)  |
|                                / \           |         |      |             |
|                                 |            |         |      |             |
|                                 | forward    |         |      |             |
|   mysql \                       |            |         |      |             |
|     --host=127.0.0.1 ----> source address    |         |      | forward     |
|     --port=3306           (127.0.0.1:3306)   |         |      |             |
|     mydb                                     |         |      |             |
+----------------------------------------------+         +------+-------------+
                                                                |
                                                                |
                                                                |
                                                        +-------+-------------+
                                                        |       |    Database |
                                                        |       |      Server |
                                                        |      \ /            |
                                                        | destination address |
                                                        |  (192.168.1.1:3306) |
                                                        |                     |
                                                        +---------------------+
$ mole start local \
  --source 127.0.0.1:3306 \
  --destination 192.168.1.1:3306 \
  --server user@172.17.0.100

Expose a service to someone outside your network

+---------------------+         +----------------------+
|  Computer #1        |         |   Jump Server        |
|                     |         |                      |
|                     |  tunnel |                      |
|       mole  <-------+---------+-- (172.17.0.100:22)  |
|  (172.17.0.10:5001) |         |      ssh server      |
|        |            |         |       / \            |
|        | forward    |         |        |             |
|        |            |         |        | forward     |
|       \ /           |         |        |             |
|     web server      |         |   (192.168.1.1:8080) |
|  (127.0.0.1:8080)   |         |     source address   |
| destination address |         |               / \    |
|                     |         |                |     |
+---------------------+         |                |     |
                                |                |     |
                                +----------------+-----+
                                                 |
                                                 | connect
                                                 |
                                +----------------+-----+
                                | Computer #2    |     |
                                |                |     |
                                |                |     |
                                | $ curl \       |     |
                                |   192.168.1.1:8080   |
                                |                      |
                                +----------------------+
$ mole start remote \
  --source 192.168.1.1:8080 \
  --destination 127.0.0.1:8080 \
  --server user@172.17.0.100

Installation

Linux and Mac

bash <(curl -fsSL https://raw.githubusercontent.com/davrodpin/mole/master/tools/install.sh)

or if you prefer install it through Homebrew

brew tap davrodpin/homebrew-mole && brew install mole

or you can also install using MacPorts

sudo port selfupdate && sudo port install mole

Windows

Usage

mole --help
Tool to manage ssh tunnels focused on resiliency and user experience.

Usage:
  mole [command]

Available Commands:
  add         Adds an alias for a ssh tunneling configuration
  delete      Deletes an alias for a ssh tunneling configuration
  help        Help about any command
  show        Shows configuration details about ssh tunnel aliases
  start       Starts a ssh tunnel
  stop        Stops a ssh tunnel
  version     Prints the version for mole

Flags:
  -h, --help   help for mole

Use "mole [command] --help" for more information about a command.

Examples

Basics

$ mole start local \
    --verbose \
    --source 127.0.0.1:8080 \
    --destination 172.17.0.100:80 \
    --server user@example.com:22 \
    --key ~/.ssh/id_rsa
INFO[0000] tunnel channel is waiting for connection      destination="172.17.0.100:80" source="127.0.0.1:8080"

Use the ssh config file to lookup a given server host

$ cat $HOME/.ssh/config
Host example
  User mole
  Hostname 127.0.0.1
  Port 22122
  IdentityFile test-env/ssh-server/keys/key
$ mole start local \
   --verbose \
   --source 127.0.0.1:8080 \
   --destination 172.17.0.100:80 \
   --server example
INFO[0000] tunnel channel is waiting for connection      destination="172.17.0.100:80" source="127.0.0.1:8080"

Let mole to randomly select the source endpoint

$ mole start local \
    --destination 172.17.0.100:80 \
    --server example
INFO[0000] tunnel channel is waiting for connection      destination="172.17.0.100:80" source="127.0.0.1:40525"

Bind the local address to 127.0.0.1 by specifying only the source port

$ mole start local \
    --source :8080 \
    --destination 172.17.0.100:80 \
    --server example
INFO[0000] tunnel channel is waiting for connection      destination="172.17.0.100:80" source="127.0.0.1:8080"

Connect to a remote service that is running on 127.0.0.1 by specifying only the destination port

$ mole start local \
    --source 127.0.0.1:8080 \
    --destination :80 \
    --server example
INFO[0000] tunnel channel is waiting for connection      destination="127.0.0.1:80" source="127.0.0.1:8080"

Create an alias, so there is no need to remember the tunnel settings afterwards

$ mole add alias local example \
    --source :8080 \
    --destination 172.17.0.100:80 \
    --server user@example.com:22
$ mole start alias example
INFO[0000] tunnel channel is waiting for connection      destination="172.17.0.100:80" source="127.0.0.1:8080"

Start mole in background

$ mole add alias local example \
    --source :8080 \
    --destination 172.17.0.100:80 \
    --server user@example.com:22
$ mole start alias example --detach
INFO[0000] execute "mole stop example" if you like to stop it at any time

Leveraging LocalForward from SSH configuration file

$ cat ~/.ssh/config
Host example
  User mole
  Hostname 127.0.0.1
  Port 22122
  LocalForward 21112 192.168.33.11:80
  IdentityFile test-env/ssh-server/keys/key
$ mole start local --server example 
INFO[0000] tunnel channel is waiting for connection      destination="192.168.33.11:80" source="127.0.0.1:21112"

Leveraging RemoteForward from SSH configuration file

$ cat ~/.ssh/config
Host example
  User mole
  Hostname 127.0.0.1
  Port 22122
  LocalForward 192.168.33.11:9090 172.0.0.1:8080
  IdentityFile test-env/ssh-server/keys/key
$ mole start remote --server example
INFO[0000] tunnel channel is waiting for connection      destination="192.168.33.11:8080" source="127.0.0.1:9090"

Create multiple tunnels using a single ssh connection

$ mole start local \
    --source :9090 \
    --source :9091 \
    --destination 192.168.33.11:80 \
    --destination 192.168.33.11:8080 \
    --server example
INFO[0000] tunnel channel is waiting for connection      destination="192.168.33.11:8080" source="127.0.0.1:9091"
INFO[0000] tunnel channel is waiting for connection      destination="192.168.33.11:80" source="127.0.0.1:9090"

Show logs of any detached mole instance

$ mole start local \
    --detach \
    --source :9090 \
    --source :9091 \
    --destination 192.168.33.11:80 \
    --destination 192.168.33.11:8080 \
    --server example
INFO[0000] instance identifier is afb046da
INFO[0000] execute "mole stop afb046da" if you like to stop it at any time
$ mole show logs --follow afb046da
time="2021-09-17T13:57:10-07:00" level=info msg="instance identifier is 1879de9f"
time="2021-09-17T13:57:10-07:00" level=debug msg="generating an empty config struct"
time="2021-09-17T13:57:10-07:00" level=debug msg="server: [name=127.0.0.01, address=127.0.0.01:22122, user=mole]"
time="2021-09-17T13:57:10-07:00" level=debug msg="tunnel: [channels:[[source=127.0.0.1:9888, destination=192.168.33.11:80]], server:127.0.0.01:22122]"
time="2021-09-17T13:57:10-07:00" level=debug msg="connection to the ssh server is established" server="[name=127.0.0.01, address=127.0.0.01:22122, user=mole]"
time="2021-09-17T13:57:10-07:00" level=info msg="tunnel channel is waiting for connection" destination="192.168.33.11:80" source="127.0.0.1:9888"
time="2021-09-17T13:57:10-07:00" level=debug msg="start sending keep alive packets"

Show the running configuration of all/any mole instance

$ mole start local \
    --detach \
    --rpc \
    --source :9090 \
    --source :9091 \
    --destination 192.168.33.11:80 \
    --destination 192.168.33.11:8080 \
    --server example
INFO[0000] instance identifier is 2b3d05be
INFO[0000] execute "mole stop 2b3d05be" if you like to stop it at any time
$ mole show instances 2b3d05be
id = "2b3d05be"
tunnel-type = "local"
verbose = false
insecure = false
detach = true
key = "$HOME/.ssh/id_rsa"
keep-alive-interval = 0
connection-retries = 3
wait-and-retry = 3000000000
ssh-agent = ""
timeout = 3000000000
ssh-config = "$HOME/.ssh/config"
rpc = true
rpc-address = "127.0.0.1:49923"

[[source]]
  user = ""
  host = "127.0.0.1"
  port = "9090"

[[source]]
  user = ""
  host = "127.0.0.1"
  port = "9092"

[[destination]]
  user = ""
  host = "192.168.33.11"
  port = "80"

[[destination]]
  user = ""
  host = "192.168.33.11"
  port = "8080"

[server]
  user = ""
  host = "example"
  port = "22"