Route tailssh's forwarding through the per-connection ssh-monitor, so on unix forwarded sockets are dialed and bound by children with the authenticated local user's credentials, never by root tailscaled. - unix -L, direct-streamlocal: the lexical allowlist check stays in tailscaled as coarse policy. The allowlist is home, /tmp, and /run/user/<uid>. Relative and abstract paths are rejected. The dial then runs as the user through the monitor. The EvalSymlinks re-validation is dropped, and the kernel's DAC is the boundary. The allowlist is capped. A home directory that cleans to "/" or is empty would prefix-match every absolute path, and such an entry is dropped instead. Paths at or beyond the sun_path capacity reject lexically rather than dying at bind or dial with a generic EINVAL. - unix -R, streamlocal-forward: the listener is created by a user-cred child with umask-at-bind 0600 and unlink-if-owned. Closing it does not unlink the socket, and the stale file on cancel is accepted. - TCP -R, tcpip-forward: a tailssh-owned handler replaces gliderssh's ForwardedTCPHandler. The bind goes through the monitor's listen op with the local user's credentials, so privileged ports fail by kernel construction for non-root-mapped users. Root-mapped users are allowed, as in OpenSSH. Bind addresses are loopback-only unless TS_SSH_FORWARD_GATEWAY_PORTS is set, the equivalent of sshd's GatewayPorts. - agent forwarding: the socket and its containing directory are created by a user-cred child, a 0600 socket in a 0700 user-owned directory, instead of a root-run MkdirTemp, Chmod, and Chown sequence. Session-end cleanup is unchanged. The monitor is spawned lazily on the first forwarding or agent need, from the tailscaled binary, and closed when the SSH connection ends. closeFwdMonitor latches a closed flag under the fwd lock, so a caller racing the teardown is refused by fwdMonitor, or reads the current state without spawning through fwdMonitorIfAny, instead of respawning a monitor nobody ever closes. plan9 keeps today's behavior through a build-tagged seam, fwdmonitor.go and fwdplan9.go. There is no monitor on plan9. Unix forwarding is rejected there, and reverse TCP forwarding keeps the gliderssh handler with the mayReversePortForwardTo gate. Tests cover conn-level callbacks against a real monitor and real one-shot fwd children: allowlist rejections, user-owned 0600 sockets, a foreign sticky-dir socket not unlinked, loopback, gateway-ports, and privileged-port TCP binds, agent directory hygiene and cleanup, and TS_SSH_DISABLE_FORWARDING coverage, plus refused respawn after teardown. The unix-fwd root-dial regressions cover a static in-allowlist symlink to a root-owned 0600 canary, which must fail permission denied as the bound user, and a dir-swap race, which must never serve the protected canary. Updates tailscale/corp#50380 Signed-off-by: James Tucker <james@tailscale.com>
Tailscale
Private WireGuard® networks made easy
Overview
This repository contains the majority of Tailscale's open source code.
Notably, it includes the tailscaled daemon and
the tailscale CLI tool. The tailscaled daemon runs on Linux, Windows,
macOS, and to varying degrees
on FreeBSD and OpenBSD. The Tailscale iOS and Android apps use this repo's
code, but this repo doesn't contain the mobile GUI code.
Other Tailscale repos of note:
- the Android app is at https://github.com/tailscale/tailscale-android
- the Synology package is at https://github.com/tailscale/tailscale-synology
- the QNAP package is at https://github.com/tailscale/tailscale-qpkg
- the Chocolatey packaging is at https://github.com/tailscale/tailscale-chocolatey
For background on which parts of Tailscale are open source and why, see https://tailscale.com/opensource/.
Using
We serve packages for a variety of distros and platforms at https://pkgs.tailscale.com.
Other clients
The macOS, iOS, and Windows clients use the code in this repository but additionally include small GUI wrappers. The GUI wrappers on non-open source platforms are themselves not open source.
Building
We always require the latest Go release, currently Go 1.27. (While we build releases with our Go fork, its use is not required.)
go install tailscale.com/cmd/tailscale{,d}
If you're packaging Tailscale for distribution, use build_dist.sh
instead, to burn commit IDs and version info into the binaries:
./build_dist.sh tailscale.com/cmd/tailscale
./build_dist.sh tailscale.com/cmd/tailscaled
If your distro has conventions that preclude the use of
build_dist.sh, please do the equivalent of what it does in your
distro's way, so that bug reports contain useful version information.
Bugs
Please file any issues about this code or the hosted service on the issue tracker.
Contributing
PRs welcome! But please file bugs. Commit messages should reference bugs.
We require Developer Certificate of
Origin
Signed-off-by lines in commits.
See commit-messages.md (or skim git log) for our commit message style.
About Us
Tailscale is primarily developed by the people at https://github.com/orgs/tailscale/people. For other contributors, see:
- https://github.com/tailscale/tailscale/graphs/contributors
- https://github.com/tailscale/tailscale-android/graphs/contributors
Legal
WireGuard is a registered trademark of Jason A. Donenfeld.