____ _____ _____
/ ___||_ _|_ _ _ _|_ _|
\___ \ | | | | | | '_ \| |
___) | | | | |_| | | | | |
|____/ |_| \__,_|_| |_|_|
Stupid Tunnel Tricks
Stupid Tunnel Tricks — a terminal user interface for defining, configuring, and managing SSH tunnel connections, Kubernetes port-forwards, and sshuttle VPN sessions.
stunt.mp4
stunt allows you to define tunnels with SSH, Kubernetes and sshuttle that persist when you close the app. While it is running, stunt monitors and maintains active tunnel connections.
- SSH local/remote
- Kubernetes port-forwarding
- sshuttle
Download the latest release for your platform from the releases page, or install via a package manager:
brew tap keathmilligan/tap
brew install keathmilligan/tap/stuntStay up-to-date with brew upgrade stunt.
See the macOS Install Guide for other ways to install on macOS.
In an elevated powershell session, run:
winget install stuntSee the Windows Install Guide for other ways to install on Windows.
curl -fsSL https://packages.keathmilligan.net/stunt/install.sh | shThis will install stunt into ~/.local/bin.
See the Linux Install Guide for other ways to install on Linux.
stunt| Key | Action |
|---|---|
n |
New entry |
e |
Edit selected entry |
d |
Delete selected entry |
Enter |
Connect / disconnect selected entry |
j / k or arrow keys |
Navigate list |
q / Ctrl+C |
Quit |
| Key | Action |
|---|---|
Tab / Down |
Next field |
Shift+Tab / Up |
Previous field |
← / → (or Space) |
Change a selection field (e.g. Resource Type: Pod / Service / Deployment) |
Ctrl+A |
Add a new forward / port binding |
Ctrl+D |
Delete selected forward / port binding |
Ctrl+T |
Cycle SSH forward type (Local / Remote / Dynamic) while editing a forward |
Enter |
Confirm field / save entry |
Esc |
Cancel / go back |
Resource Type is a selection field, not free text. Use
←/→(orSpace) to choose between Pod, Service, and Deployment.
Configuration is stored at:
| Platform | Path |
|---|---|
| Linux | ~/.local/share/stunt/tunnels.toml |
| macOS | ~/Library/Application Support/stunt/tunnels.toml |
| Windows | %APPDATA%\stunt\tunnels.toml |
[[entries]]
type = "ssh"
name = "prod-db"
host = "bastion.example.com"
port = 22 # optional, default 22
user = "deploy" # optional
identity_file = "~/.ssh/id_ed25519" # optional
auto_restart = true # optional, default false
[[entries.forwards]]
type = "local"
bind_port = 5432
remote_host = "db.internal"
remote_port = 5432
[[entries.forwards]]
type = "dynamic"
bind_port = 1080A Kubernetes entry wraps kubectl port-forward. Each entry targets a single
resource (<resource_type>/<resource_name>) and may declare multiple port
bindings — they are all forwarded by a single kubectl port-forward
invocation, exactly like passing several <local>:<remote> arguments on the
command line.
[[entries]]
type = "k8s"
name = "api-debug"
context = "prod" # optional, uses current context if omitted
namespace = "default" # optional
resource_type = "deployment"
resource_name = "api-server"
auto_restart = false
[[entries.forwards]]
local_port = 8080
remote_port = 80Supported resource_type values: pod, service, deployment.
The command:
kubectl -n my-platform port-forward \
svc/my-platform-server-tls 18443:8443 19443:9443is expressed as a single entry with two port bindings:
[[entries]]
type = "k8s"
name = "platform-server"
namespace = "my-platform"
resource_type = "service" # svc/ → "service"
resource_name = "my-platform-server-tls"
auto_restart = false
[[entries.forwards]]
local_port = 18443
remote_port = 8443
[[entries.forwards]]
local_port = 19443
remote_port = 9443In the TUI, create a Kubernetes entry, set Resource Type to service
(using ← / →), enter the resource name and namespace, then add each port
binding with Ctrl+A. All bindings run under one kubectl process; the entry
is considered "connected" once the first local listener is reachable.
Note:
svcis shorthand forservice. stunt uses the fullservice/pod/deploymentforms.
[[entries]]
type = "sshuttle"
name = "corp-vpn"
host = "bastion.example.com"
subnets = ["10.0.0.0/8", "192.168.0.0/16"]
port = 22 # optional, uses sshuttle default if omitted
user = "alice" # optional
identity_file = "~/.ssh/id_ed25519" # optional
auto_restart = true # optional, default falseMIT