tailscale/tailscale: the daemon and CLI you can read, and the interfaces you cannot
The easiest, most secure way to use WireGuard and 2FA.
At a glance
- What is it?
- The repository holds the tailscaled daemon and the tailscale CLI, and a tree that reaches into control, derp, disco and chirp, but it stops at the mobile and desktop GUI wrappers. The build rules are strict: Go 1.27, and distributed binaries are expected to carry version metadata.
- Who is it for?
- This repo is the right place to read for the daemon, the CLI and the coordination packages, and a poor place to read for pricing, for how the hosted service behaves, or for the interfaces people actually tap. Take it if you run the daemon, package it for a distribution, or want to audit the coordination code.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The repository ends where the mobile GUI begins
The iOS and Android apps are built from this repo's code, but the repo does not contain the mobile GUI code. The macOS, iOS and Windows clients add small GUI wrappers on top of the same code, and on platforms that are not open source those wrappers are themselves not open source. That leaves a precise gap for anyone auditing the product: the code that decides what a tap on the screen does is not here. Reading this tree will not tell you how a login prompt, an approval request, or a key expiry is presented or handled, so anyone trying to reproduce Tailscale's observable behavior from this source alone has to obtain those interfaces from somewhere else. The repo also splits the packaged platforms out into their own trees, with the Android app, the Synology package, the QNAP package and the Chocolatey packaging each living in a separate repository.
go install builds two binaries and leaves out version metadata
A local build is one command, and it needs the latest Go release, currently Go 1.27:
go install tailscale.com/cmd/tailscale{,d}That brace expansion produces both the `tailscale` CLI and the `tailscaled` daemon, which is fine on a machine you own and not fine for anything you distribute. The build instructions are explicit that packagers should use `build_dist.sh` instead, so that commit IDs and version info are burned into the binaries:
./build_dist.sh tailscale.com/cmd/tailscale
./build_dist.sh tailscale.com/cmd/tailscaledIf a distro's conventions preclude the script, the project asks for the equivalent in that distro's way, so bug reports contain useful version information. Skip that and the cost lands on whoever triages: a report from a home-built binary carries nothing tying it to a commit. The release naming is dense by comparison, with v1.102.5 published 2026-09-29, v1.102.4 on 2026-09-10 and v1.102.3 on 2026-08-20, and the tree carries both VERSION.txt and the pinned Go revision files.
Go 1.27 is the floor, and the Go fork is optional
`go.mod` declares `go 1.27.1`, and the module path is `tailscale.com` rather than a GitHub URL, so imports resolve through the domain and not to a repository path. The tree also pins toolchain state explicitly, in files named `go.toolchain.rev`, `go.toolchain.version`, `go.toolchain.branch` and `go.toolchain.next.rev`. Release binaries are built with a Go fork hosted at github.com/tailscale/go, and the project states that using that fork is not required to build. The Dockerfile shows why the revision is pinned: it reads `go.toolchain.rev` and builds from `alpine:3.22` rather than the official golang image, because go.mod can demand a Go version the official image has not shipped yet, which breaks the build for a day or two after every minor version bump. For readers the practical consequence is narrow and checkable: Go 1.27.1 is the floor, and a clean checkout on a slightly older toolchain will not build.
The checked-in Dockerfile is not what builds the published images
The Dockerfile opens by saying it is not used to build any of the published Tailscale container images and that it may have drifted from the mechanism actually in use. Published images come from the separate mkctr repository, and the script for that lives in `build_docker.sh`. The file is still useful for local images, and it points at make for that:
REPO=local/tailscale TAGS=v0.0.1 PLATFORM=local make publishdevimage
REPO=<your-registry>/<your-repo>/tailscale TAGS=v0.0.1 make publishdevimageThe consequence for anyone building a private image is that you are maintaining a recipe upstream has already disclaimed. Fixes to the real pipeline do not land here, so a patched local Dockerfile can drift from production with nothing in the file to flag it. Building it directly with `docker build -t tailscale/tailscale .` is reasonable for a test machine and a poor basis for anything you deploy.
The container run line asks for host networking and privileged mode
The run recipe documented in that Dockerfile needs four specific concessions: a named container, a host bind mount at /var/lib, the host's /dev/net/tun mapped in, host networking, and privileged mode.
docker run -d --name=tailscaled -v /var/lib:/var/lib -v /dev/net/tun:/dev/net/tun --network=host --privileged tailscale/tailscale tailscaledOnce it is up, the CLI reaches the daemon through exec rather than a separate entry point:
docker exec tailscaled tailscale up
docker exec tailscaled tailscale statusRead those flags as a limit rather than a default. There is no unprivileged or rootless variant documented in this repository, and rootless container engines are not mentioned at all, so an environment that forbids privileged mode or host networking has no documented path into this setup. State and the tunnel device both live on the host, so isolating the container is not something the documented command does.
FreeBSD and OpenBSD support is hedged inside the platform sentence
The supported list is not a flat statement. The README says the `tailscaled` daemon runs on Linux, Windows and macOS, and then adds that it runs on FreeBSD and OpenBSD to varying degrees. Nothing in the repository narrows that phrase. There is no per-OS feature matrix, no list of which subsystems are stubbed, and no statement of which BSD release is known to work. The consequence is concrete for anyone whose only option is a BSD host: the repo will not tell you whether the parts you need, the derp and disco packages, or the CLI, function on your version, and the only honest check is to build for that target and find out. The same hedge also makes platform bug reports harder to act on, because no file in the tree states the intended support level to compare a failure against.
make runs through a pinned tool wrapper and defaults to one platform
The quality targets do not call the `go` on your PATH. They go through a wrapper script:
./tool/go vet ./...
./tool/go mod tidy
./tool/go run ./tool/updateflakes
./tool/go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint runSo a shell-level `go vet ./...` is not the same check the project runs, and `tidy` also updates the nix flake hashes through `./tool/go run ./tool/updateflakes`. The Makefile defaults lean the same way, with `PLATFORM ?= "flyio"` annotated as linux/amd64 and an empty value required to build all platforms, `IMAGE_REPO ?= tailscale/tailscale` and `TAGS ?= "latest"`, plus `SYNO_ARCH ?= "x86_64"` and `SYNO_DSM ?= "7"` baked in. Those last two matter if your target is not x86_64, and the Synology packaging itself lives in another repository. Dependency checks are split too, with separate `depaware-min.txt` and `depaware-minbox.txt` minimum builds for `tailscaled`.
One issue tracker covers the daemon and the hosted service alike
The README funnels everything into a single tracker: issues about the code, and issues about the hosted service, both go to the same GitHub issue tracker. That is convenient and it blurs a boundary the code itself respects. The tree carries separate top-level directories for `control/`, `derp/`, `disco/` and `chirp/` next to `ipn/`, `cmd/` and `client/`, and the dependency checks treat the daemon, the CLI, `derper`, the `k8s-operator`, `stund` and `tsidp` as separate sets. A symptom that looks like local networking trouble can originate on the coordination side, and neither the README nor the file listing tells a first-time reporter which side to point at. For contributors the rules are firmer: pull requests are welcome, but bugs should be filed first, commit messages should reference the bugs, and every commit needs a Developer Certificate of Origin Signed-off-by line. `docs/commit-messages.md` holds the message style.
Editorial conclusion
This repo is the right place to read for the daemon, the CLI and the coordination packages, and a poor place to read for pricing, for how the hosted service behaves, or for the interfaces people actually tap. Take it if you run the daemon, package it for a distribution, or want to audit the coordination code. Leave it if your question is what the service does or what a plan costs. Before building, confirm your toolchain is Go 1.27.1 or newer, use build_dist.sh instead of a bare go install so version strings exist in your binaries, and settle early whether privileged containers with host networking are available in your target environment, because the documented container command offers no alternative.
Frequently asked questions
What exactly does Tailscale do?
The project describes itself as private WireGuard networks made easy and as the easiest, most secure way to use WireGuard and 2FA. What lives in this repo is the `tailscaled` daemon and the `tailscale` CLI, alongside top-level packages for control, derp, disco and chirp.
Is Tailscale a free VPN?
The code here is BSD-3-Clause licensed, and packages are served for a variety of distros and platforms at pkgs.tailscale.com. This repository does not state pricing for the hosted service, so it cannot answer that part of the question.
Is Tailscale basically a VPN?
It builds on WireGuard, and the project notes that WireGuard is a registered trademark of Jason A. Donenfeld. The repo carries the daemon and CLI but not the mobile GUI code, and it does not spell out traffic paths between nodes.
how to install tailscale on ubuntu
The project points to pkgs.tailscale.com for packages across distros and platforms rather than listing Ubuntu commands. From source it needs the latest Go release, currently Go 1.27, and the build is a single `go install` line.
how to use tailscale to access home network
No home network walkthrough is documented here. The closest documented sequence is the container one, which logs in with `tailscale up` and reports state with `tailscale status`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tailscale-tailscale)