Skip to content

Tailscale

Tailscale ⧉ is a managed VPN solution built on top of the WireGuard ⧉ protocol. We use it to allow a number of our instances in different networks to communicate with each other.

While it would be possible to manage WireGuard servers and clients directly, Tailscale takes a lot of work off our hands, particularly by allowing new clients to seamlessly join the VPN and cleaning up clients that have been inactive for a while.

In accordance with official Tailscale lingo, we refer to instances running Tailscale as Tailscale nodes and the created VPN as our tailnet.

Our Tailnet

Currently our main use for Tailscale is connecting instances outside of our GCP VPC and instances within it. This works as follows:

One or more dedicated *tailscale-subnet-router* instances in our VPC run Tailscale and advertise routes to instances in said VPC. One would be sufficient, but we may run multiple subnet-routers for high availability. All of them advertise the same routes, allowing Tailscale to fail over between them.

Instances outside the VPC may also run Tailscale. They will automatically become aware of the routes advertised by the subnet-router Tailscale nodes and send all packets headed for VPC-internal IP addresses via the tailscale0 interface created by Tailscale. These eventually make their way to one of the subnet-router machines which is configured to forward them to the target machine.

Tailscale subnet-routers SNAT routed packets by default, so return traffic works seamlessly.

The Access Control List

Due to the way Tailscale operates (at least by default), all of our deployment environments are part of the same tailnet. To prevent stray traffic between them we use Tailscale's access control list (ACL) feature.

The ACL is configured via Terraform (/infra/terraform/tailscale). An excerpt of the generated ACL file ⧉ may look as follows:

{
    "action": "accept",
    "dst":    ["10.0.0.0/20:*"],
    "src":    ["tag:external-production"]
}

This means that all Tailscale nodes tagged with external-production (tags are supplied when first starting Tailscale on an instance) are allowed to send traffic to 10.0.0.0/20.

Human and CI Runner Access

Other than automatically provisioned instances, human users as well as GitHub CI runners can also connect to our tailnet.

For both, who is eligible is controlled by Terraform. For human users the source of truth here is /people; all users in the tailscale group can connect to our tailnet. group:people* ACL rules control what they can access. GitHub CI runners use federated identities to authenticate with Tailscale, i.e. no secret credentials are required. tag:ci* rules control what they can access.