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
- Auto address selection: find a port available and start listening to it, so the
--source
flag doesn’t need to be given every time you run the app. - Create multiple tunnels using a single ssh connection: multiple tunnels can be established using a single connection to a ssh server by specifying different
--destination
flags. - Aliases: save your tunnel settings under an alias, so it can be reused later.
- Leverage the SSH Config File: use some options (e.g. user name, 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.
- Resiliency! Then tunnel will never go down if you don’t want to:
- Idle clients do not get disconnected from the ssh server since Mole keeps sending synthetic packets acting as a keep alive mechanism.
- Auto reconnection to the ssh server if the it is dropped by any reason.
- Embedded rpc server to retrieve runtime information about one or more instances running on the system.
Table of Contents
- Use Cases
- Installation
- Usage
- Examples
- Basics
- Use the ssh config file to lookup a given server host
- Let mole to randomly select the source endpoint
- Connect to a remote service that is running on 127.0.0.1 by specifying only the destination port
- Create an alias, so there is no need to remember the tunnel settings afterwards
- Start mole in background
- Leveraging LocalForward from SSH configuration file
- Leveraging RemoteForward from SSH configuration file
- Create multiple tunnels using a single ssh connection
- Show logs of any detached mole instance
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
- Download Mole for Windows from here
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"