Guides

Guide·June 26, 2026

How to connect to multiple Tailscale tailnets at the same time on macOS (2026)

A macOS walkthrough for TailMux: install, configure isolated profiles, use the documented browser PAC, SSH, and local TCP-tunnel paths, and understand the routing boundary.

View as Markdown

TailMux lets one Mac reach resources in multiple independent Tailscale tailnets through supported browser, command, SSH, and local TCP-tunnel paths. Define one profile per tailnet and TailMux selects the owning profile from the hostname suffix. It does not add a second native system-wide VPN interface or alter the official Tailscale client session.

This is the macOS-specific setup reference: browser PAC routing where supported, SSH with tailmux ssh, and a fixed loopback port for a database or RDP host through a Service Tunnel. Start with the cross-platform architecture guide if you are still choosing between switching, shared endpoints, a VM, a manual proxy, or TailMux.

Why switching is not simultaneous access#

Account switching is useful when you need one tailnet at a time: it avoids repeating authentication while changing the active account. It does not give one browser, shell, or client a concurrent path to resources in two independently configured tailnets. “Connect to multiple tailnets simultaneously” has been an open feature request (#183) for years. TailMux uses a separate profile-scoped userspace node for each configured tailnet and chooses a profile per supported hostname-based connection instead.

The workarounds, in one paragraph each#

People solve this three ways before finding a product that does it:

  • A Linux VM (OrbStack, Lima, Colima) holding the second tailnet. It works, but you're maintaining a whole guest OS and forwarding ports out of it for what is really a routing decision. Full cost breakdown — and how to migrate off the VM — in OrbStack/Lima VM vs no VM at all.
  • Fast user switching, Tailscale's official answer. Only one tailnet is ever active, and switching drops every live connection on the other. The full disambiguation is in fast user switching vs simultaneous tailnets.
  • A second daemon / userspace SOCKS5 — Linux escape hatches that mostly don't exist on macOS. Why they're fragile even where they do exist: why two tailscaled daemons fight.
TailMux skips all three: each profile runs its own embedded Tailscale node (tsnet) inside TailMux, and a loopback router on 127.0.0.1:43100 sends each request to the profile that owns its hostname suffix. Nothing touches the system routing table, and your official Tailscale app and account are never touched.
request flow
1client keeps hostname2        |3        |  HTTP_PROXY / PAC / tailmux connect4        v5TailMux router  127.0.0.1:431006        |7        |  hostname suffix match8        v9profile-owned embedded tsnet10        |11        v12selected tailnet  (direct / DERP)

Step 1 — Install and create your profiles#

Install the menu-bar app + CLI, then generate a starter config:

zsh — install & init
$brew install --cask cq-fabrication/tap/tailmux   # or download from /download$tailmux init

Open ~/.config/tailmux/config.yaml and give each tailnet a profile that owns its DNS suffix:

~/.config/tailmux/config.yaml
1profiles:2  personal:3    suffixes:4      - .home-lab.ts.net5  work:6    accept_routes: true          # if a host sits behind a subnet router7    suffixes:8      - .work.ts.net9      - .internal.example        # private names the work tailnet resolves

Validate it:

zsh — validate
$tailmux config validate
Suffix ownership is strict. Each suffix belongs to exactly one profile — overlaps are rejected at validation. That rejection is what guarantees a name on one tailnet can never fall back to the other.

Step 2 — Bring everything up and log in#

zsh — up & login
$tailmux up$tailmux profile login personal$tailmux profile login work$tailmux status

Each login opens a browser auth flow against that tailnet. Every profile is its own node with its own identity, state, and node key — logging the work profile in does nothing to personal, and neither touches the official Tailscale app.

From here on, the menu-bar icon shows every profile's state; the app window (Profiles, Tunnels, Diagnostics, Logs, Settings, License in the sidebar) is where you manage them.

Step 3 — The browser: nothing to configure#

On launch, the TailMux app points your active macOS network service at its generated PAC file. Safari — and anything that respects the system proxy — sends only your owned suffixes through TailMux and everything else direct, and the setting is cleared when you quit. Turn this off under Settings → “Configure system PAC automatically” if you'd rather wire a browser manually.

So https://nas.home-lab.ts.net and https://wiki.work.ts.net both just load, in adjacent tabs, each on its own tailnet.

Step 4 — Terminal tools and SSH#

For HTTP-speaking tools (curl, git, npm), wrap one command or the whole shell — the router picks the profile from each hostname:

zsh — per-command routing
$tailmux run -- git clone https://git.work.ts.net/team/api.git$eval "$(tailmux env)"     # same, for the whole shell session

SSH ignores proxy environment variables, so it gets its own command. tailmux ssh wraps your system ssh with the right ProxyCommand and routes through the profile that owns the host's suffix — every normal ssh flag passes straight through:

zsh — ssh, routed by suffix
$tailmux ssh admin@host.work.ts.net$tailmux ssh -L 9000:localhost:9000 host.work.ts.net

An interactive shell on the work tailnet and one on the home tailnet, in two tabs, at the same time. More patterns (persistent ~/.ssh/config setup) in the SSH docs.

Step 5 — Fixed local ports with Service Tunnels#

Some clients want a stable address, not a proxy: database GUIs, RDP, SMB. A Service Tunnel gives a TCP service a fixed 127.0.0.1:<port> routed through one profile, kept alive whenever that profile is up.

Create one in the app under Open → Tunnels:

a Service Tunnel
1Profile:  work2Target:   db.internal.example:54323Endpoint: 127.0.0.1:15432   (assigned for you, stable across restarts)

Then point the client at loopback once and forget it:

zsh — point a client at the tunnel
$psql "postgresql://app@127.0.0.1:15432/appdb"

Tunnels come in two modes: native (relayed straight through the profile's node — for anything the tailnet can reach, including hosts behind subnet routers or app connectors) and SSH-bastion (a background ssh -L through a jump host such as bastion.example.ts.net, authenticated with your ssh-agent, a private key, or a password stored in the macOS Keychain). Every tunnel shows in the menu bar with a start/stop switch and a live connection count. Full reference: Tunnels docs.

Step 6 — Verify it#

Confirm a hostname classifies to the profile you expect, and trace the actual path:

zsh — verify
$tailmux test nas.home-lab.ts.net$tailmux diag path http://nas.home-lab.ts.net:8080/ --netcheck

Two guarantees hold at all times: a name owned by one profile is never dialed through another, and a .ts.net name that no profile owns is refused rather than guessed. Your tailnets stay separate by construction, not by discipline.

The bottom line#

On macOS, use TailMux when its hostname-preserving access paths match your workload. A VM, a shared endpoint, or switching may be the better choice for other requirements. Start with getting started, review the routing limitations, then check pricing or download TailMux.

Skip the workarounds

TailMux keeps configured profiles reachable through supported hostname-preserving paths, with no cross-profile fallback. Review the routing limitations before choosing it for a workflow. The one-time license includes one year of updates.

TailMux is not affiliated with, endorsed by, or sponsored by Tailscale Inc.

FAQ

Multiple tailnets on macOS — FAQ

The questions people search before committing to a workaround.

Can you connect to two Tailscale networks at the same time?

TailMux is built for simultaneous access to resources in multiple independent Tailscale tailnets on macOS and Linux. It keeps a separate profile per tailnet and routes supported hostname-based connections to the profile that owns the suffix.

Do I need a VM (OrbStack or Lima) to use two tailnets on macOS?

No, not when the workload fits TailMux's documented browser, command, SSH, or local TCP-tunnel paths. A VM remains appropriate when you need a separate full operating environment or native system-level networking.

What is the difference between fast user switching and simultaneous tailnets?

Fast user switching changes which account or tailnet is active. TailMux keeps its configured profiles available to supported paths and selects a profile per hostname-based connection, so a workflow does not need an account switch for every destination.

Can I run two tailscaled daemons or two Tailscale instances at once?

On Linux, separate daemons, namespaces, containers, and userspace networking are possible architectures. They require explicit ownership of routes, DNS, firewall behavior, state, and lifecycle. TailMux avoids a second route-owning daemon for its supported application-layer paths.

Will running multiple tailnets break MagicDNS?

TailMux keeps profile state separate and can query DNS through a selected profile with tailmux dns query --profile. Do not treat a hostname or address as globally interchangeable across tailnets; confirm the intended profile before connecting.

Is TailMux affiliated with Tailscale?

No. TailMux is an independent CQ Fabrication tool and is not affiliated with, endorsed by, or sponsored by Tailscale Inc.