A terminal user interface (TUI) for managing SSH tunnels. Tunnel9 provides a simple, efficient way to manage multiple SSH port forwarding configurations with real-time monitoring of throughput and latency.
Many thanks to How to Create An SSH Tunnel in Go by Elliot Chance and A Visual Guide to SSH Tunnels: Local and Remote Port Forwarding by Ivan Velichko.
brew install sio2boss/tap/tunnel9bash -c "$(curl -fsSL https://raw.githubusercontent.com/sio2boss/tunnel9/main/tools/install.sh)"- Download the latest release from the releases page
- Extract the archive:
tar xzf tunnel9-*.tar.gz - Copy the binary to your local bin directory:
mkdir -p ~/.local/bin mv tunnel9 ~/.local/bin/ chmod +x ~/.local/bin/tunnel9
- Ensure
~/.local/binis in your PATH. Add this to your~/.bashrcor~/.zshrc:export PATH="$HOME/.local/bin:$PATH"
- Restart your shell or source your rc file:
source ~/.bashrc # or source ~/.zshrc
- Simple terminal-based UI for managing SSH tunnels
- Real-time monitoring of tunnel performance (throughput and latency)
- Support for bastion/jump host configurations
- Tag-based organization and filtering
- Column-based sorting and organization
- Go (backend)
- Bubble Tea (TUI framework)
- SSH integration
golang.org/x/crypto/ssh(SSH client)ssh_config(SSH config parsing)
- docopt (CLI argument parsing)
- YAML for configuration (
gopkg.in/yaml.v3)
- Navigation
↑/↓- Move selectionEnter- Toggle tunnel on/off</>- Change sort column
- Management
n- Create new tunnele- Edit selected tunneld- Delete selected tunnel
- Display
t- Select tags to filter?- Toggle helpq- Quit application
[✓]- Tunnel Active[x]- Tunnel Stopped[!]- Connection Error[~]- Connecting...
Tunnels are configured using YAML format:
tunnels:
- host: "db.example.com"
alias: "prod-db" # optional
user: "dbuser"
local_port: 5432
remote_port: 5432
tag: "production" # optional
bastion: # optional
host: "jump.prod"
user: "jumpuser"Searches for configuration in the following order:
- Command line flag
--config - ./.tunnel9.yaml
- ~/.local/state/tunnel9/config.yaml <- default
Basic development workflow:
go mod tidy
make
Install locally:
make install
FYI: Right now we have a patched version of ssh_config...
Additional tools:
brew install vhs
brew install ttyd --HEAD
go get -u gotest.tools/gotestsum
Rebuild gif linked in top of README.md:
make vhs
- Update version number in main.go and tools/install.sh
- Run
make homebrew(builds releases and updates homebrew formula) - Upload
./releaseartifacts to GitHub Release - Update the homebrew tap repository with the new formula from
homebrew/tunnel9.rb
graph TD
A[Start] --> D{Bastion Host?}
D -->|Yes| E[Connect to Bastion]
E --> F[Connect to Remote Host]
D -->|No| F
F -->|Status: Connecting| G[SSH Connection Attempt]
G -->|SSH Connection Established| H[Status: Active]
H --> I[Establish Remote Connection]
I --> J[Forward Data]
J --> K[Update Metrics]
K --> L{Connection Dropped?}
L -->|Yes| M[Reconnect]
L -->|No| J
M -->|Status: Connecting| F