No switching
One embedded Tailscale node per profile. No signing in and out, no switching.
tailmix replaces your Tailscale client to let you connect to multiple tailnets simultaneously.
curl -fsSL https://tailmix.net/install.sh | sudo sh
Command line · macOS · Linux with systemd · Open source
Disconnect the Tailscale client before installing.
One embedded Tailscale node per profile. No signing in and out, no switching.
Bind subnets to a profile and pick one exit node across all of them.
MagicDNS from every profile, plus custom suffixes and search domains.
Install, run tailmix ts login --shields-up, and open the login link it prints. That tailnet gets a profile named default.
# install curl -fsSL https://tailmix.net/install.sh | sudo sh # log in to your first tailnet sudo tailmix ts login --shields-up # check tailmix status
Give it a profile name and log in. With more than one profile, choose one with -p.
sudo tailmix profiles add work sudo tailmix ts -p work login --shields-up
Add a tailnet’s MagicDNS suffix as a search domain so ssh mybox works. list shows each tailnet’s suffix.
tailmix dns search list sudo tailmix dns search add tailnet.ts.net
For each destination, tailmix checks these in order and uses the first match.
Nothing is accepted until you ask. Accept everything a tailnet advertises, or pin a single prefix to one tailnet. A pinned prefix beats accept-all, and if two tailnets advertise the same prefix, tailmix waits for you to pin one.
# see what each tailnet advertises tailmix routes list --available # accept all of work’s routes sudo tailmix routes set -p work --accept-all=true # send 10.20.0.0/16 through lab sudo tailmix routes bind -p lab 10.20.0.0/16
Pick one exit node from any tailnet. It carries your default traffic and answers DNS for names no other route covers. Peers and subnet routes keep using their own tailnets.
# list exit nodes across tailnets tailmix exit-node list # use home’s gateway for everything else sudo tailmix exit-node set -p home gateway # go back to your normal internet sudo tailmix exit-node clear
Two tailnets can hand out the same 100.x address. tailmix gives every node and Service its own local address and rewrites packets as they enter and leave each tailnet.
Your app sends from 192.168.58.1 to 192.168.58.8. tailmix rewrites it to come from 100.64.0.1, your address in the work tailnet, and go to 100.64.0.42, then hands it to its embedded tsnet node for work. A packet to 192.168.58.9 instead goes to 100.64.0.42 in the home tailnet, from 100.64.0.7, through the home tsnet node. Replies are rewritten back.
| Tailnet | Node | Tailnet IP | Tailmix IP |
|---|---|---|---|
| work | you | 100.64.0.1 | 192.168.58.1 |
| work | printer | 100.64.0.42 | 192.168.58.8 |
| home | you | 100.64.0.7 | 192.168.58.1 |
| home | nas | 100.64.0.42 | 192.168.58.9 |
Each node keeps its Tailnet IP inside its tailnet. On your host it gets a unique Tailmix IP, so overlapping addresses don't clash. You have one Tailmix IP, whichever tailnet you're talking to.
| Step | From | To |
|---|---|---|
| Your app sends | your app192.168.58.1 | printer192.168.58.8 |
| tailmix hands to work | your app100.64.0.1 | printer100.64.0.42 |
| printer replies | printer100.64.0.42 | your app100.64.0.1 |
| Your app receives | printer192.168.58.8 | your app192.168.58.1 |
192.168.58.1 is your host’s local address. Its own addresses in the tailnets are 100.64.0.1 (work) and 100.64.0.7 (home). Addresses are examples. IPv6 works the same way, using fd6d:6e65:7400::/56.
ssh printer just works.A client. It runs on your Mac or Linux machine and signs in to your tailnets like the Tailscale client does. There’s nothing to host.
Yes, on that machine. tailmix runs its own background service, tailmixd, which runs one built-in Tailscale node per tailnet. Disconnect the Tailscale client first; the two compete for routes and DNS.
No, it’s command line only. tailmix ts -p work … runs any Tailscale CLI command against one tailnet.
Run this on your Mac for the profile you want to accept SSH connections through. That tailnet’s network and SSH policies control who can log in.
sudo tailmix ts -p work set --ssh --shields-up=false
Our quick start enables shields-up. Turning it off allows inbound connections on that profile, not just SSH, subject to the tailnet’s policy.
Each tailnet’s policy applies exactly as it would to a regular Tailscale client. Each profile is its own device in its tailnet, and Tailmix IPs are rewritten before packets leave, so policy only sees tailnet IPs and identities. tailmix never forwards traffic from one tailnet into another.
--shields-up?Depending on a tailnet’s policy, its devices may be able to connect to services on your machine, like SSH or a dev server. With several tailnets, that can include tailnets other people manage. Shields-up blocks those incoming connections for one tailnet. Your own outbound connections to other tailnets still work as per tailnet policy.
No. Each profile joins its tailnet as a normal device, so ACLs, device approval, and admin settings work as usual.
Installs from install.sh check for new releases daily, verify checksums, and restart the service. tailmix update status shows where it stands.
No. tailmix is an independent open-source project, not affiliated with or endorsed by Tailscale Inc.