mole mascot
single binary · MIT · v0.1.0

mole

Hit localhost:3000 as if it were always running — even when the real service lives on another machine.

bash — mole
$ curl -fsSL https://raw.githubusercontent.com/Luqueee/mole/main/scripts/install.sh | sh
installed mole v0.1.0 → /usr/local/bin/mole
$ mole init
? SSH remote: dev
wrote ~/.config/mole/config.yaml
? Start mole in the background? [Y/n] y
mole running — forwarding 3 ports
localhost:3000 workstation:3000
localhost:5173 workstation:5173
localhost:8080 workstation:8080
 

Linux · macOS · Windows · *BSD

clients
browser curl whatever
one SSH connection
localhost:3000 workstation:3000
localhost:5173 workstation:5173
localhost:8080 workstation:8080
mole
remote host
workstation:3000 workstation:5173 workstation:8080

mole runs here, on your laptop — ssh-agent or ~/.ssh/id_*

Features

Everything mole handles for you

From auto-discovered dev servers to periodic health checks — mole removes the busywork of port forwarding.

One connection
A single SSH client multiplexes every forwarded port.
Smart auto-discover
Enumerates the remote's real TCP listeners (ss/netstat) and forwards them — any port, not a fixed list. Re-scans every 15s, so servers you start after launch get picked up.
SSH config aliases
A remote like dev is resolved through ~/.ssh/config (ssh -G): HostName, User, Port, IdentityFile, Include, Match — all honoured.
Exclude list
System/reserved ports (22, 25, 53, 111, 631) are skipped by default; fully configurable.
Auto-reconnect
Transparent reconnect on tunnel drop, with periodic health checks.
Native auth
ssh-agent first (Unix socket / Windows named pipe), then ~/.ssh/id_* keys.
Background daemon
mole up -d detaches; mole down stops it; mole status and mole logs introspect it.
Beautiful logs
mole logs renders the daemon log with colour level badges, a green FORWARD badge, and (×N) collapsing of repeats.
How it works

Under the hood

Four goroutines, one SSH client, no port list to maintain.

01

Connect

Open one SSH client connection to the remote. ssh-agent or ~/.ssh/id_* keys; aliases resolved via ssh -G.

02

Discover

Enumerate the remote's TCP listeners (ss/netstat) every 15 s, or fall back to probing discover_ports. Skip exclude_ports.

03

Forward

For each port, bind 127.0.0.1:<port> locally; on a local connection, dial 127.0.0.1:<port> through the tunnel and bridge bytes both ways.

04

Heal

A watchdog reconnects the SSH session if it dies; re-discovery picks up new servers; UNFWD prunes dead ones.

Logs

Colourised, structured, skimmable

Every line gets a colour-graded level badge, a dimmed timestamp, and repeated events collapse to a single line with a (×N) counter.

mole logs
INFO 14:32:01 starting mole, version 0.1.0
INFO 14:32:01 connected to dev (workstation:22) via ssh-agent
INFO 14:32:02 auto-discover: 3 remote ports found
FORWARD localhost:3000 → workstation:3000
FORWARD localhost:5173 → workstation:5173
FORWARD localhost:8080 → workstation:8080
INFO 14:32:08 re-discover: 4 remote ports found
FORWARD localhost:9090 → workstation:9090
UNFWD localhost:8080 pruned (remote closed)
INFO 14:32:14 ssh tunnel healthy
INFO 14:32:20 forwarded connection on :3000 (×12)

mole logs renders the daemon's structured log with coloured level badges, a distinct green FORWARD badge when a port starts forwarding and a burnt-orange UNFWD badge when a dead remote port is pruned, dimmed timestamps, and (×N) collapsing of repeated lines.

Quickstart

Running in three commands

Three commands. Under a minute from curl to forwarded ports.

1 install
$ curl -fsSL https://raw.githubusercontent.com/Luqueee/mole/main/scripts/install.sh | sh
2 configure + start (interactive; accepts an ssh config alias as the remote)
$ mole init
3 later…
$ mole status      # what's forwarded right now
mole logs -f     # pretty, colourised, live
mole down        # stop the background daemon

mole init writes the config, then offers to start mole in the background for you. From there it keeps the tunnel up and forwards new servers as they appear.

Commands

The full CLI surface

Eight commands cover the full lifecycle. mole help lists them all.

Command What it does
mole up Start the forwarder in the foreground (add -d to background it).
mole down Stop a backgrounded mole (started with up -d).
mole status Query the local admin API for live stats + forwarded ports.
mole logs Show the daemon log, colourised; -f to follow.
mole init Generate a mole.yaml interactively (or scripted).
mole update Update mole in place to the latest release (re-runs the installer).
mole version · mole help The obvious.
Platforms

Runs on your machine

Same source, same commands, every desktop OS.

Linux

glibc & musl

curl -fsSL https://raw.githubusercontent.com/Luqueee/mole/main/scripts/install.sh | sh
macOS

Intel & Apple Silicon

curl -fsSL https://raw.githubusercontent.com/Luqueee/mole/main/scripts/install.sh | sh
Windows

PowerShell 5+

irm https://raw.githubusercontent.com/Luqueee/mole/main/scripts/install.ps1 | iex
FreeBSD

Unix-like

curl -fsSL https://raw.githubusercontent.com/Luqueee/mole/main/scripts/install.sh | sh
FAQ

Common questions

If yours isn't here, the README and the GitHub Issues have the rest.

How is mole different from `ssh -L`?

A single SSH client multiplexes every forwarded port. mole auto-discovers what's listening on the remote, so you don't keep a port list. It transparently reconnects when the tunnel drops, and `mole logs` gives you colourised, structured output.

Does it work with my existing `~/.ssh/config`?

Yes. Pass an alias as the remote (e.g. `mole up --remote dev`) and mole resolves it via `ssh -G` — HostName, User, Port, IdentityFile, Include and Match are all honoured.

Where does the binary run — on my laptop or the remote?

On your laptop. The remote only needs sshd. The mole daemon opens the SSH connection, enumerates listeners over the encrypted channel, and binds the forwarded ports on 127.0.0.1 locally.

What if the SSH connection drops?

A watchdog goroutine reconnects the tunnel. Re-discovery picks up any new servers that came up while the connection was down, and a UNFWD badge prunes ports that closed on the remote.