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.