A SOCKS5 proxy manager for personal Tailscale users.
Connect to multiple Tailnets simultaneously and route traffic automatically via a PAC file.
Tailscale only lets you be connected to one Tailnet at a time. If you need to access resources on two different Tailnets simultaneously — for example, reaching web services on your personal Tailnet while your work machine is already connected to a work Tailnet — you'd normally have to disconnect from one and reconnect to the other every time.
Tailhopper lets you stay connected to multiple Tailnets at once, without touching your primary Tailscale connection.
- Single web dashboard to manage your additional Tailnets
- Works alongside your existing Tailscale connection — your primary Tailnet is unaffected
- Automatic proxy routing via PAC file — no per-request configuration needed
- Manual per Tailnet SOCKS5 proxy option for apps that don't support PAC or for non-HTTP traffic
- Runs as a background service on macOS (auto-starts at login, auto-restarts on crash)
Tailhopper connects to each Tailnet using tsnet and starts a dedicated local SOCKS5 proxy for each one. Traffic can reach those proxies in two ways:
PAC file (recommended for browsers) — Tailhopper serves a PAC file that maps each Tailnet's MagicDNS suffix to the corresponding SOCKS5 proxy. Configure your browser or OS to use the PAC file once, and every request is automatically sent to the right proxy based on the destination hostname — with no manual switching needed, even when accessing multiple Tailnets in the same browser session.
Direct SOCKS5 (per Tailnet) — Each Tailnet's proxy can also be configured directly in any app that supports SOCKS5. This is useful for non-HTTP traffic (SSH, database clients, etc.) or apps that don't respect the systems PAC setting. Because each proxy represents exactly one Tailnet, an app configured to use a specific proxy can only reach that one Tailnet at a time — unlike the PAC approach, there is no automatic multi-Tailnet routing.
- Requires proxy-aware apps. Only applications that respect PAC or SOCKS5 proxy settings will route traffic through Tailhopper. Apps that bypass system proxy settings or manage their own networking will not.
- PAC routing only works with MagicDNS names. The PAC file routes based on MagicDNS hostnames only. Accessing Tailnet machines by IP address is not supported via PAC — use the manual SOCKS5 proxy for that Tailnet directly instead.
- Tailnets without MagicDNS enabled are not supported.
Once running, open the dashboard at http://localhost:8888.
From there you can:
- Add Tailnets and authenticate them via the Tailscale
- Temporarily enable/disable individual Tailnets
- Configure your browser or OS to use the PAC file for automatic proxy routing — see the in-app How to configure PAC section for OS- and browser-specific instructions
- Alternatively, configure a SOCKS5 proxy manually per-app using the host and port shown on each connected Tailnet's card (useful for non-HTTP traffic or apps that don't respect system wide PAC settings)
Install with Homebrew (recommended):
brew install jcambass/homebrew-tap/tailhopper
brew services start tailhopperTo view stop and uninstall instructions after the initial install:
brew info tailhopperDownload the binary from Releases and run it directly. To run as a background service, create your own launchd user agent.
curl -fsSL https://raw.githubusercontent.com/jcambass/tailhopper/main/linux/install.sh | bashInstall a specific version:
VERSION=v0.1.0 curl -fsSL https://raw.githubusercontent.com/jcambass/tailhopper/main/linux/install.sh | bashUse a custom dashboard port:
HTTP_PORT=9999 curl -fsSL https://raw.githubusercontent.com/jcambass/tailhopper/main/linux/install.sh | bashView logs:
journalctl --user -fu tailhopperStop:
systemctl --user disable --now tailhopperUninstall:
systemctl --user disable --now tailhopper
rm ~/.local/bin/tailhopper ~/.config/systemd/user/tailhopper.service
systemctl --user daemon-reloadTo also remove state files:
rm -rf ~/.local/share/tailhopperDownload the binary from Releases and run it directly. To run as a background service, create your own systemd user service.
Download the binary from Releases and run it. To run as a background service, use your preferred Go service wrapper or task scheduler.
Requires Go 1.22+.
git clone https://github.com/jcambass/tailhopper.git
cd tailhopper
go build -o tailhopper ./cmd/tailhopper
./tailhopperTailhopper is configured via environment variables:
| Variable | Default | Description |
|---|---|---|
HTTP_PORT |
8888 |
Dashboard and PAC file port |
LOG_LEVEL |
INFO |
Log verbosity (DEBUG, INFO, WARN, ERROR) |
Tailhopper stores state in its working directory:
tailhopper.jsontailnets/(per-tailnet runtime/state data)
Common working directories:
- Homebrew service (macOS):
$(brew --prefix)/var/tailhopper - Linux installer (systemd user service):
~/.local/share/tailhopper - Manual runs: current working directory
Tailhopper outputs structured logs in logfmt format to stderr. For colored output, pipe through hl:
./tailhopper 2>&1 | hlThis section is for maintainers.
Releases are automated via GoReleaser. When you push a v* tag, GitHub Actions automatically:
- Builds cross-platform binaries (macOS, Linux, Windows)
- Creates a GitHub Release with artifacts
- Updates
Formula/tailhopper.rbinjcambass/homebrew-tap(urlandsha256) viamislav/bump-homebrew-formula-action
git tag v0.1.0
git push origin v0.1.0The workflow requires a TAP_PR_WRITER secret with the following permissions on jcambass/homebrew-tap:
- Contents: Read and write (needed to create branches / push commits).
- Pull requests: Read and write (needed to open/manage PRs)
You can also run just the Homebrew update from the GitHub Actions UI using:
mode = homebrewtag-name = v0.1.0
This is useful if the release already exists and you need to re-run the tap PR creation.
Run a full local snapshot release (no publish):
go run github.com/goreleaser/goreleaser/v2@latest release --clean --snapshot --skip=publishValidate config only:
go run github.com/goreleaser/goreleaser/v2@latest checkHomebrew formula changes live in jcambass/homebrew-tap.
Make sure to update the url and sha256 in Formula/tailhopper.rb to point to the new release artifact before testing.
git clone https://github.com/jcambass/homebrew-tap.git
cd homebrew-tap
brew install --build-from-source --verbose --debug ./Formula/tailhopper.rb