Skip to content

Instantly share code, notes, and snippets.

@Seas0
Last active June 6, 2025 08:18
Show Gist options
  • Save Seas0/f6e9501fcccd2ca7eacdb22441986cc3 to your computer and use it in GitHub Desktop.
Save Seas0/f6e9501fcccd2ca7eacdb22441986cc3 to your computer and use it in GitHub Desktop.
Multiple Tailnets Guide

Running multiple tailscaled instances with netfilter integration disabled


This guide explains how to spawn multiple instances of tailscaled on a single system using a systemd.service(5) template and, optionally, customized configurations. By setting "netfilterMode": "off" in all configurations (or by manually configuring them using tailscale up --netfilter-mode off), you can connect to multiple Tailnets simultaneously without resorting to SOCKS proxy–based userspace networking, while preserving functionalities like Magic DNS integration with systemd-resolved (i.e. you can simutaneously have direct access to other machines in BOTH tailnets via their hostnames).

DISCLAIMER: This method completely disables Tailscale’s automatic (iptables/nftables) netfilter firewall rule creation and management. As firewall rules from an earlier tailscaled instance would be wiped out by a new one, potentially locking you out.
Thus, features that rely on kernel firewall integration (such as Exit-Node functionality, which depends on NAT masquerading, and MSS clamping to PMTU, which is implemented by a custom firewall rule mangling the TCP options in the packet header) may not work correctly. Additionally, IP conflicts can occur, potentially disrupting in-kernel IP routing. So use this method with caution.

Note: This hack also completely breaks Tailscale IPv6 address handling, as the table based routes for IPv6 are added as whole CIDR blocks rather than per host (as in the IPv4 scenario). You can validate this by using following commands

# Linux rule based routing
sudo ip rule show
sudo ip -6 rule show
# Tailscale only use route table 52
sudo ip route show table 52
sudo ip -6 route show table 52

Prerequisites

  • A Linux system using systemd.

  • A working installation of Tailscale.

  • Basic knowledge of systemd unit files and configuration editing.


Systemd Service Template for tailscaled

Create a template unit file that will be used to launch multiple tailscaled instances. Save the following content as /etc/systemd/system/[email protected]:

# Systemd Template Service Unit for tailscaled
# should be placed at /etc/systemd/system/[email protected]
[Unit]
Description=Tailscale node agent instance #%i
Documentation=https://tailscale.com/kb/
Wants=network-pre.target
After=network-pre.target NetworkManager.service systemd-resolved.service

[Service]
EnvironmentFile=/etc/tailscale.d/tailscale%i.env
ExecStart=/usr/sbin/tailscaled --config=/etc/tailscale.d/tailscale%i.json --state=/var/lib/tailscale%i/tailscaled.state --socket=/run/tailscale%i/tailscaled.sock --tun tailscale%i --port=${PORT} $FLAGS
ExecStopPost=/usr/sbin/tailscaled --cleanup --config=/etc/tailscale.d/tailscale%i.json --state=/var/lib/tailscale%i/tailscaled.state --socket=/run/tailscale%i/tailscaled.sock --tun tailscale%i

Restart=on-failure

RuntimeDirectory=tailscale%i
RuntimeDirectoryMode=0755
StateDirectory=tailscale%i
StateDirectoryMode=0700
CacheDirectory=tailscale%i
CacheDirectoryMode=0750
Type=notify

[Install]
WantedBy=multi-user.target

This template uses %i as an instance identifier, allowing you to run multiple, independent tailscaled instances. It also utilizes the optional Declarative Configuration (as the --config=/etc/tailscale.d/tailscale%i.json in ExecStart and ExecStop properties, find details in following sections) for easier configration process. But if you find this confusing or preventing your specific use case, just remove the configuration flags and config the instance manually with tailscale after starting the new instance.


Declarative Configuration for tailscaled

The declarative configuration for tailscaled is currently in its alpha0 stage and may change over time. Below is an extract of the configuration template (from ConfigVAlpha):

{
  "version": "alpha0",
  "locked": false,
  "serverURL": "https://controlplane.tailscale.com",
  "authKey": null,
  "enabled": true,
  "operatorUser": null,
  "hostname": null,
  "acceptDNS": true,
  "acceptRoutes": null,
  "allowLANWhileUsingExitNode": false,
  "advertiseRoutes": [],
  "disableSNAT": false,
  "netfilterMode": "off",
  "postureChecking": false,
  "runSSHServer": null,
  "runWebClient": null,
  "shieldsUp": false,
  "autoUpdate": {
    "check": true,
    "apply": false
  },
  "serveConfigTemp": null
}

Ensure that "netfilterMode": "off" is set in every instance configuration if you want to disable firewall rule management for simultaneous multiple instance spawning.


Creating a New tailscaled Instance (e.g., tailscaled1)

Follow these steps to create and start a new tailscaled instance:

  1. Create the systemd Service Template: Save the unit file provided above as /etc/systemd/system/[email protected].

  2. Prepare the Configuration Directory: Create a dedicated directory for instance configurations:

sudo mkdir -p /etc/tailscale.d
  1. Add Instance Configuration: Create a declaritive configuration file for the new instance at /etc/tailscale.d/tailscale1.json and modify it as needed.

  2. Set Up Environment Variables: Copy the default environment variable file from /etc/default/tailscaled to /etc/tailscale.d/tailscale1.env, then adjust its content (at a minimum, change the listening port):

sudo cp /etc/default/tailscaled /etc/tailscale.d/tailscale1.env
sudo nano /etc/tailscale.d/tailscale1.env
  1. Enable and Start the Instance: Enable and start the new instance with the following command:
sudo systemctl enable --now [email protected]
  1. (Optional) Migrate the State Directory: If you need to migrate an existing state, modify the state storages /var/lib/tailscale/tailscaled.state and /var/lib/tailscale1/tailscaled.state (with all the involved instances stopped), then restart the service:
sudo systemctl stop tailscaled.service [email protected]
sudo nano /var/lib/tailscale/tailscaled.state
sudo nano /var/lib/tailscale1/tailscaled.state
sudo systemctl start tailscaled.service [email protected]
# Be careful: these state file contains sensitive values like node private key, so don't disclose their contents!

Once the new instance is running, you can manage it with the tailscale command by specifying the corresponding socket:

tailscale --socket /run/tailscale1/tailscaled.sock <command>

Conclusion

This tutorial demonstrated how to run multiple tailscaled instances simultaneously by using a systemd service template and custom JSON configurations with "netfilterMode": "off". This setup allows you to connect to multiple Tailnets concurrently while keeping Magic DNS functionality intact via systemd-resolved. However, keep in mind the limitations regarding firewall management and IP routing.

Happy networking!


Feel free to contribute improvements or raise issues if you encounter any problems with this setup.

This guide is originally written by myself, then polished by GPT, and checked by me again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment