Important notices
Before you add a new report, we ask you kindly to acknowledge the following:
Is your feature request related to a problem? Please describe.
The os-tailscale plugin (currently version 1.2) manages exactly one tailscaled daemon, one state directory, and one tailscale0 interface. This makes it impossible, via the plugin UI, to join OPNsense to more than one Tailscale/Headscale control plane simultaneously.
This is a significant functional gap relative to the other VPN plugins that ship with OPNsense:
- WireGuard (
os-wireguard): supports multiple instances natively via GUI
- OpenVPN (core): supports multiple clients/servers natively via GUI
- IPsec (core): supports multiple connections natively
Real-world use cases that hit this wall:
- Consultants / MSPs who need to reach multiple client environments, each with their own Tailscale or self-hosted Headscale control server.
- Users separating work and personal tailnets where merging under one control server is not possible because one side (employer, client) is administered externally.
- Multi-tenant routing where OPNsense should act as the gateway/router for LAN clients into several independent tailnets at once — exactly what is already possible today with multiple WireGuard peers or OpenVPN clients.
The only current workaround is to SSH into OPNsense and hand-write additional rc.d scripts (tailscaled_work, tailscaled_client, etc.) with custom -state, -socket, -tun, and -port flags, then manually register each instance via CLI (tailscale --socket=... up --login-server=... --auth-key=...) and manually assign the resulting tailscale1, tailscale2 tun devices as OPNsense interfaces. This has significant drawbacks:
- No UI, no status display, no log integration for instances beyond the first
- Not idempotent across plugin updates
- Invisible to OPNsense backup/restore
- Each interface assignment, per-instance firewall rule set, and outbound NAT rule must be created and maintained manually
- Fragile across OPNsense major upgrades and
os-tailscale plugin updates
- Not discoverable — most users will simply conclude OPNsense cannot do what other VPN plugins already do
Describe the solution you'd like
Extend os-tailscale so that the data model supports N named instances rather than a single global configuration, modeled after how os-wireguard represents multiple peer/server configurations.
For each instance the plugin should manage:
- Identity: user-provided name (e.g.
personal, work, client-acme)
- Daemon parameters:
- Unique
--state directory (e.g. /var/db/tailscale-<name>/)
- Unique
--socket path (e.g. /var/run/tailscale-<name>.sock)
- Unique
--tun device name (e.g. tailscale0, tailscale1, ...)
- Unique
--port (starting from 41641 and incrementing, or user-configurable)
- Control plane:
--login-server URL (or default to hosted Tailscale), per-instance auth key
- Runtime preferences: accept-routes, advertise-routes, exit-node flags, tags, hostname — all existing plugin settings, scoped per instance
- Service management: one rc.d script per instance, started/stopped independently by
configd
- Interface integration: each
tailscale<N> tun device assignable as a distinct OPNsense interface with its own firewall rules, outbound NAT, and status page
Proposed UI layout (mirrors os-wireguard):
VPN → Tailscale
├── Overview ← list of configured instances with status
├── Instances
│ ├── [+ Add instance]
│ ├── personal ← click to edit settings / authentication / advanced
│ ├── work
│ └── client-acme
└── Diagnostics / Log File ← per-instance selector
Implementation notes:
The underlying daemon already supports this. tailscaled accepts -state, -socket, -tun, and -port flags precisely to enable multiple instances on the same host (see upstream workaround in tailscale/tailscale#5721). The tailscale CLI honours --socket=<path> for targeting a specific daemon. The core work is therefore in the plugin:
- Convert the singleton data model (XML schema) to a keyed list of instances
- Generate one rc.d script per instance from a single template
- Wire each instance into
configd for start/stop/status/reload
- Expose each
tailscale<N> tun device to the interface assignments dropdown
- Update the
tailscale CLI wrapper calls in the plugin to always pass --socket=... explicitly
- Migration path: existing single-instance installs become a single default instance with no behavior change
Describe alternatives you've considered
-
Sidecar VM or container (e.g. Alpine Linux VM beside OPNsense, running one tailscaled per tailnet and acting as subnet router back into a dedicated OPNsense transit VLAN). Works, but requires a hypervisor, extra machine management, and is harder to integrate into OPNsense's unified firewall/interface model than a native plugin instance.
-
FreeBSD jails on the OPNsense host. Better isolation but not a first-class OPNsense feature, and user-hostile compared to a plugin UI.
-
Manual rc.d scripts as described above. Works but defeats the purpose of having a plugin at all for instances beyond the first.
-
Community fork of os-tailscale adding this capability as a separate plugin. Feasible but fragments the ecosystem and creates ongoing duplicate-maintenance burden — upstream support would be the right home.
-
Single Headscale with users/tags/ACLs to logically separate environments. Only viable when the user controls all environments, which is not the case for client/employer tailnets.
Additional context
Existing demand:
Precedent within OPNsense: os-wireguard, core OpenVPN, and core IPsec all support multiple instances. There is no principled reason for Tailscale to be the only VPN technology in OPNsense limited to a single control plane per firewall.
Related existing issues in this repository that would benefit from the refactor:
Secondary but related gap (optional / follow-up):
[Tailscale KB 1299](https://tailscale.com/kb/1299/opnsense-unbound) acknowledges that tailscaled DNS settings are not integrated with OPNsense's Unbound resolver, forcing manual Domain Override configuration per tailnet. A multi-instance plugin would be a natural place to also surface per-instance DNS integration (auto-writing Unbound Domain Overrides for each instance's base domain pointing at 100.100.100.100 or the instance's configured DNS). Out of scope for this FR but worth anticipating in the design.
Environment of the requester:
- OPNsense: 25.x
- os-tailscale: 1.2
- Use case: single OPNsense firewall needing to terminate three independent tailnets concurrently (personal Headscale, client development Headscale, work Tailscale), with LAN clients routed through the appropriate tunnel per-destination via outbound NAT on each
tailscale<N> interface.
Disclosure:
Assisted by Antropic Claude Opus 4.7
Important notices
Before you add a new report, we ask you kindly to acknowledge the following:
Is your feature request related to a problem? Please describe.
The
os-tailscaleplugin (currently version 1.2) manages exactly onetailscaleddaemon, one state directory, and onetailscale0interface. This makes it impossible, via the plugin UI, to join OPNsense to more than one Tailscale/Headscale control plane simultaneously.This is a significant functional gap relative to the other VPN plugins that ship with OPNsense:
os-wireguard): supports multiple instances natively via GUIReal-world use cases that hit this wall:
The only current workaround is to SSH into OPNsense and hand-write additional rc.d scripts (
tailscaled_work,tailscaled_client, etc.) with custom-state,-socket,-tun, and-portflags, then manually register each instance via CLI (tailscale --socket=... up --login-server=... --auth-key=...) and manually assign the resultingtailscale1,tailscale2tun devices as OPNsense interfaces. This has significant drawbacks:os-tailscaleplugin updatesDescribe the solution you'd like
Extend
os-tailscaleso that the data model supports N named instances rather than a single global configuration, modeled after howos-wireguardrepresents multiple peer/server configurations.For each instance the plugin should manage:
personal,work,client-acme)--statedirectory (e.g./var/db/tailscale-<name>/)--socketpath (e.g./var/run/tailscale-<name>.sock)--tundevice name (e.g.tailscale0,tailscale1, ...)--port(starting from 41641 and incrementing, or user-configurable)--login-serverURL (or default to hosted Tailscale), per-instance auth keyconfigdtailscale<N>tun device assignable as a distinct OPNsense interface with its own firewall rules, outbound NAT, and status pageProposed UI layout (mirrors
os-wireguard):Implementation notes:
The underlying daemon already supports this.
tailscaledaccepts-state,-socket,-tun, and-portflags precisely to enable multiple instances on the same host (see upstream workaround intailscale/tailscale#5721). ThetailscaleCLI honours--socket=<path>for targeting a specific daemon. The core work is therefore in the plugin:configdfor start/stop/status/reloadtailscale<N>tun device to the interface assignments dropdowntailscaleCLI wrapper calls in the plugin to always pass--socket=...explicitlyDescribe alternatives you've considered
Sidecar VM or container (e.g. Alpine Linux VM beside OPNsense, running one
tailscaledper tailnet and acting as subnet router back into a dedicated OPNsense transit VLAN). Works, but requires a hypervisor, extra machine management, and is harder to integrate into OPNsense's unified firewall/interface model than a native plugin instance.FreeBSD jails on the OPNsense host. Better isolation but not a first-class OPNsense feature, and user-hostile compared to a plugin UI.
Manual rc.d scripts as described above. Works but defeats the purpose of having a plugin at all for instances beyond the first.
Community fork of
os-tailscaleadding this capability as a separate plugin. Feasible but fragments the ecosystem and creates ongoing duplicate-maintenance burden — upstream support would be the right home.Single Headscale with users/tags/ACLs to logically separate environments. Only viable when the user controls all environments, which is not the case for client/employer tailnets.
Additional context
Existing demand:
[tailscale/tailscale#5721](https://github.com/tailscale/tailscale/issues/5721)— "FR: Connect to multiple tailnets simultaneously", with documented CLI workaround.[tailscale/tailscale#16430](https://github.com/tailscale/tailscale/issues/16430)(July 2025) — "Support multiple simultaneous Tailscale connections (official + headscale)", explicitly calls out consultant / multi-client / self-hosted-plus-official use cases.Precedent within OPNsense:
os-wireguard, core OpenVPN, and core IPsec all support multiple instances. There is no principled reason for Tailscale to be the only VPN technology in OPNsense limited to a single control plane per firewall.Related existing issues in this repository that would benefit from the refactor:
os-tailscaleis combined with rawpkg install tailscale; clearer plugin ownership of the daemon lifecycle would reduce footgun cases.Secondary but related gap (optional / follow-up):
[Tailscale KB 1299](https://tailscale.com/kb/1299/opnsense-unbound) acknowledges that
tailscaledDNS settings are not integrated with OPNsense's Unbound resolver, forcing manual Domain Override configuration per tailnet. A multi-instance plugin would be a natural place to also surface per-instance DNS integration (auto-writing Unbound Domain Overrides for each instance's base domain pointing at100.100.100.100or the instance's configured DNS). Out of scope for this FR but worth anticipating in the design.Environment of the requester:
tailscale<N>interface.Disclosure:
Assisted by Antropic Claude Opus 4.7