Transparent proxy over SSH — route some or all of your machine's TCP and DNS
traffic through any host you can ssh to. No VPN server, no root on the
remote side, no client configuration in your apps.
goshuttle is a Go rewrite of sshuttle, built for long-running, high-throughput tunnels:
- Fast. Compiled Go with a zero-allocation mux hot path and per-channel flow control — designed to be significantly higher performance than the Python-based sshuttle.
- Single static binary. No Python or other runtime needed on either end. The client cross-compiles the server half and uploads it over SSH automatically.
- Correct TCP. Streams application bytes over SSH instead of nesting TCP packets inside TCP, so congestion control behaves the way it should.
- Client: macOS or Linux, with
sudoaccess (firewall rules are managed viapfon macOS andiptables/nftableson Linux), and a Go toolchain if you build from source or use the auto-upload mode. - Server: any Linux, macOS, or BSD host you can SSH into. An unprivileged account is fine — the server side never needs root.
git clone https://github.com/jdtx0/goshuttle
cd goshuttle
make build # builds ./bin/goshuttle
make install-system # optional: installs to /usr/local/bin (sudo)Route a subnet through a bastion host:
goshuttle --remote user@bastion.example.com 10.0.0.0/8Route everything, including DNS:
goshuttle --remote user@bastion.example.com --dns 0.0.0.0/0That's it. On first run goshuttle detects the remote OS/arch, builds a
matching server binary, and uploads it to ~/goshuttle on the remote host
(it asks first; pass --yes to skip the prompt). Subsequent runs reuse the
uploaded binary after a hash check.
| Flag | Description |
|---|---|
--remote user@host |
SSH target (required) |
--dns |
intercept DNS and resolve it remotely |
--exclude SUBNET |
don't route this subnet; repeatable |
--subnet-file FILE |
read subnets from a file |
--remote-mode MODE |
homedir (default), go (ephemeral /tmp upload, self-deletes), or preinstalled |
--remote-path PATH |
path to a preinstalled remote binary |
--ssh-cmd CMD |
alternate ssh command |
Subnets accept optional port ranges (10.0.0.0/8:443, 0/0:80-443) and
- prefixes for exclusion. See docs-go/usage.md for the
full flag reference and docs-go/platforms.md for
platform details.
- Firewall rules (
pfon macOS,iptables/nftableson Linux) redirect matching outbound TCP/DNS traffic into a local loopback listener. - The client recovers each connection's original destination, then carries the byte stream through a framed multiplexer over SSH stdio.
- The server half — running as your normal SSH user — dials the real destination from the remote side and bridges the bytes back.
Because only application byte streams cross the SSH link (never raw packets), there is no TCP-over-TCP meltdown, and a slow connection backpressures its own sender without affecting other flows.
| Platform | Client | Server |
|---|---|---|
| macOS | ✅ supported (pf) |
✅ |
| Linux | ✅ supported (nat/nft/tproxy) |
✅ |
| FreeBSD / OpenBSD / NetBSD | — | ✅ |
The Linux client is covered by unit tests, privileged firewall integration tests, and the Docker E2E suite, but has not yet seen extended real-world use — please report issues.
Only one goshuttle instance can manage pf on a machine at a time.
-
The local listeners bind to loopback only; the remote server runs over SSH stdio with no listening ports. SSH provides all authentication and encryption.
-
The remote server runs as your unprivileged SSH user and never invokes
sudo. On shared bastions, consider restricting the key inauthorized_keys:command="goshuttle server",no-pty,no-port-forwarding,no-X11-forwarding user-key... -
Firewall redirection applies to all matching traffic on the client machine, regardless of which user generated it. See the usage docs if you need per-UID scoping.
-
Without
--dns, hostname lookups still go to your normal resolver and are visible to your local network.
make check # vet + race-enabled unit tests
make bench # mux throughput benchmark
make e2e # full client → bastion → destination topology in Docker
make linux-fw-test # privileged Linux firewall backend tests in DockerThe E2E suite blocks direct egress, tunnels a Linux client through a bastion container, and verifies concurrent SSH sessions, hash-checked 50 MiB transfers, and parallel iperf3 throughput.
LGPL-2.1, inherited from sshuttle, of which this project is a derivative.