SSH Tunnel is a native macOS menu bar app for opening, monitoring, and
closing SSH tunnels from the SSH config you already use. It wraps the same
ssh -M master-socket workflow you would run in Terminal, then adds health
checks, reconnects, quick forwards, diagnostics, and process lifecycle handling
so tunnels do not drift out of sync.
The full documentation is the single source of truth and lives at https://christestet.github.io/ssh-tunnel/. This README is a short overview; each topic below links to the page that covers it in depth.
| Topic | Page |
|---|---|
| Install & Gatekeeper override | Install |
| Define hosts & forwards | Configure SSH |
| Full feature list | Features |
| Menu, port pills, action bar | Using the App |
| Every Settings field | Settings |
| On-the-fly forwards | Quick Forwards |
| Health checks, reconnects, port conflicts | Health Checks & Reconnects |
| Staying out of Terminal's way | Terminal Coexistence |
| Update notifications | Updates |
Exact ssh commands |
SSH Command Mapping |
| Logs & diagnostics | Debugging & Logs |
| Build from source | Build & Test |
| Versioning & releases | Release Process |
| Troubleshooting | FAQ & Troubleshooting |
The site is built from the docs/ folder with
Astro Starlight and deployed to GitHub Pages on
every push to main. See docs/README.md to run it locally.
- Native SwiftUI menu bar app with no Dock icon.
- Reads tunnel hosts and
LocalForwardentries from~/.ssh/configthroughssh -G. - Starts, stops, checks, and reconnects tunnels without keeping Terminal windows open.
- Supports multiple tunnels, per-tunnel Start at Login, quick forwards, labels, and clickable localhost port pills.
- Self-healing: scheduled health checks, TCP port probes, and automatic reconnects with exponential backoff.
- Detects local port conflicts before starting, reports the blocking process,
and offers a session-only remap of a busy config
LocalForwardport onto a free local port. - Uses a namespaced default control path,
~/.ssh/control-sshtunnelapp-%C, to avoid colliding with interactive SSH sessions. - Builds from SwiftPM or the included Makefile. No checked-in Xcode project is required.
See the full Features page for the complete list.
| Requirement | Version |
|---|---|
| macOS | 26.0 or newer, tested on macOS 26.5 Tahoe |
| Swift tools | Swift 6.3 (only to build from source) |
| Build tools | Xcode Command Line Tools (only to build from source) |
| SSH | A working host alias in ~/.ssh/config |
Download the latest DMG from
GitHub Releases, mount it,
and drag SSHTunnel.app to Applications.
Release DMGs are ad-hoc signed, not notarized, so macOS Gatekeeper quarantines the download. The Install guide walks through the one-time Open Anyway override (and the
xattrfallback) for opening the build on macOS 26 (Tahoe).
To build and install locally instead:
xcode-select --install # once, if the command line tools are missing
make install # build and copy SSHTunnel.app to /ApplicationsLocally built apps are not quarantined and open normally. For all build targets see Build & Test.
-
Define a host with one or more
LocalForwardentries in~/.ssh/config:Host my-proxy HostName proxy.example.com User sshproxy IdentityFile ~/.ssh/id_ed25519 ExitOnForwardFailure yes LocalForward 1443 internal-api.example.com:443 LocalForward 8080 internal-db.example.com:5432
-
Open Settings…, add a tunnel, and set Host Alias to
my-proxy. -
Toggle Active in the menu bar to connect. Forwarded ports appear as clickable localhost port pills.
The full walkthrough, including labels, quick forwards, and port-conflict remapping, is in Configure SSH.
Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request.
In short: use Conventional Commit style for PR titles and commits, add tests
before Swift implementation changes (TDD), run swift test or make test, and
do not bump versions manually unless the change is explicitly a release/version
maintenance change. Releases are handled automatically — see
Release Process.
SSH Tunnel is released under the MIT License.
