Tailnet lock
Tailnet lock allows you to verify that no node is added to your tailnet without being signed by trusted nodes in your tailnet. When tailnet lock is enabled, even if Tailscale infrastructure is malicious or hacked, attackers can’t send or receive traffic on your tailnet.
What is tailnet lock?
Tailnet lock lets you control which nodes are signed and verified by trusted nodes in your tailnet, meaning you don’t need to trust the Tailscale coordination server for distributing public node keys to peer nodes in your tailnet. You can control which nodes are trusted to sign another node’s public key.
How it works
To help understand the types of keys being discussed, each node has a node key, and a tailnet lock key.
-
The node key is a public/private key pair generated on a node by a Tailscale client. The coordination server ties the node key to a specific identity. The private key remains private on the node. The public key is transmitted to the coordination server.
-
The tailnet lock key, also a public/private key pair, is introduced by the tailnet lock feature. Every node generates a tailnet lock key, even if tailnet lock is not enabled. The private component of the tailnet lock key remains private on the node. The private key remains on the node.
Without tailnet lock, when a new node is added to the tailnet, its public node key is distributed to peer nodes by the Tailscale coordination server. If Tailscale were malicious, and stealthily inserted new nodes into your network, then Tailscale could send or receive traffic to your existing nodes in plaintext.
With tailnet lock, when a new node is added to the tailnet, its public node key requires a signature from a tailnet lock key. The coordination server distributes the signed public node key to peer nodes in the tailnet. Peer nodes can then verify the signature before allowing connections. In this manner, you control which nodes are trusted to be in your tailnet, as well as which nodes are trusted to sign other nodes.
Disablement secrets
When you enable tailnet lock, you create disablement secrets. A disablement secret is required if you want to disable tailnet lock.
Disabling tailnet lock is a security-relevant operation—if the disablement procedure lacked authorization checks, a compromised coordination server could trivially disable tailnet lock (and all its protections) to attack a tailnet as if tailnet lock wasn’t running. To avoid this, use of a disablement secret is required to globally disable tailnet lock.
If you generate a disablement secret for Tailscale support, then Tailscale can disable tailnet lock if needed, but not without being detected.
Tailnet key authority
To determine which tailnet lock keys to trust, nodes implement a new subsystem, the tailnet key authority, to track and update the set of tailnet lock keys that can be used to sign node keys. You specify the initial set of trusted lock keys when you enable tailnet lock. You can add or remove keys to change the set of trusted tailnet lock keys. The coordination server publishes the set of trusted tailnet lock keys across your tailnet.
Enable tailnet lock
You need to be an Owner, Admin, or IT admin of a tailnet in order to enable tailnet lock.
Tailnet lock is not enabled by default. When tailnet lock is enabled, all existing nodes in the tailnet are signed.
-
Ensure the nodes that you want to have tailnet lock key are running Tailscale v1.34 or later. Nodes running Tailscale versions earlier than v1.34 can’t run tailnet lock so they will not verify node keys.
-
Request access in the General settings page of the admin console.
-
For the nodes whose tailnet lock keys you want to trust, get the public key on each node by running the
tailscale lock status
command:tailscale lock status
This command displays the tailnet lock public key for the current node. For example:
Tailnet lock is NOT enabled. This node's tailnet-lock key: tlpub:abcdef12
We recommend setting up tailnet lock with multiple trusted nodes. Their tailnet lock keys are used in the next step, when you call
tailscale lock init
. -
Determine the settings you want to use for your tailnet lock.
For example, decide how may disablement secrets you wish to use. We recommend you use at least two.
You can optionally choose to send an extra disablement secret that is automatically transmitted to Tailscale support, so Tailscale support could disable tailnet lock in case of an issue with how we’ve implemented it. We recommend you use the
--gen-disablement-for-support
flag in the following step, which creates and sends the extra disablement secret to Tailscale support.Then, on any node in your tailnet, run the
tailscale lock init
command to enable tailnet lock. Pass in the desired number of disablement secrets, whether you want to generate a disablement secret that is transmitted to Tailscale support, and the trusted tailnet lock keys. You must specify the tailnet lock key for the node where you are runningtailscale lock init
as one of the trusted tailnet lock keys.tailscale lock init \ --gen-disablements=3 \ --gen-disablement-for-support \ <tlpub:trusted-key1 tlpub:trusted-key2 ...>
-
Make a note of the disablement secrets that are displayed in the output from running the
tailscale lock init
command. The disablement secrets are long passwords needed to disable your tailnet lock.
For more information about disablement secrets, see tailscale lock disable
.
After tailscale lock init
completes successfully:
- All existing nodes in the tailnet are signed by the trusted tailnet lock keys.
- The set of trusted tailnet lock keys is distributed to the existing nodes.
- Nodes verify the signature of a peer’s node key before allowing a connection.
- All new node keys must be signed by an existing tailnet lock key.
There is currently a bug where initialization may fail with the following error:
error: 500 Internal Server Error: initialization failed: tka init-begin RPC: request returned (400): bootstrap tka state does not trust the initializing node
even when the tailnet lock key for the node you are running on was specified. As a workaround, logout and login again (via tailscale logout
and tailscale login
) before trying again.
Disable tailnet lock
Using a disablement secret that you stored securely when you enabled tailscale lock, run the
tailscale lock disable
command:
tailscale lock disable disablement-secret:ABC1234
Once the specified disablement secret is used, it has been distributed to all nodes in the tailnet and should be considered public.
If tailnet lock is re-enabled, for example by running the tailscale lock init
command again, new
disablement secrets will be generated.
If you encounter a significant issue with tailnet lock for your entire tailnet and can’t disable it
via tailscale lock disable
(for example, if you can’t locate your disablement secret), you could
run the tailscale lock local-disable
command on each of your nodes to make your tailnet in effect
ignore tailnet lock. For details, see
tailscale lock local-disable
.
Add a node to a locked tailnet
If you have already enabled tailnet lock and want to add an additional node, you need to sign
the node key for the node to be added. Use the tailscale lock sign
command to sign the node key.
The command to run will look like:
tailscale lock sign nodekey:1abddef1 tlpub:abcdef12
nodekey:1abddef1
is the node key for the node to be added. tlpub:abcdef12
is an optional
tailnet lock key for a trusted signing node, to use for key rotation.
You can determine the tailscale lock sign
command either using the admin console or using the
Tailscale CLI.
To determine the tailscale lock sign
command using the admin console:
- Open the Machines page in the admin console.
- Click the node that needs to be signed. A node that needs to be signed has the Locked out badge.
- Copy the
tailscale lock sign
command needed to sign the node.
Alternatively, to determine the tailscale lock sign
using the Tailscale CLI:
-
On the node that you want to add to your tailnet, run:
tailscale lock status
-
In the output of
tailnet lock status
, copy thetailscale lock sign
command needed to sign the node.
Then, on a node with a trusted tailnet lock key, run the command you copied in the previous step:
tailscale lock sign nodekey:<your-node-key> tlpub:<your-tailnet-lock-key>
Add a node using a pre-approved auth key
Signing an auth key lets you add devices to your locked tailnet using pre-approved auth keys, so that you don’t need to add the node and then sign its node key.
-
Generate a pre-approved auth key.
-
On a node with a trusted tailnet lock key, set an environment variable,
AUTH_KEY
, to the value of the auth key:export AUTH_KEY="tskey-auth-XXXXCTRL-NNNNNN"
-
Sign the auth key by running the
tailscale lock sign
command:tailscale lock sign $AUTH_KEY
-
Use the new key that is generated by the
tailscale lock sign
command to pre-approve devices on your tailnet.
Add a signing node
-
On each node that you want to add as a signing node, run
tailscale lock status
. The command displays the tailnet lock public key for the node. This key is of the form:tlpub:abcdef12
-
On a node with a trusted tailnet lock key, run the
tailscale lock add
command, passing in the tailnet lock keys that you determined in the previous step.This examples adds two signing nodes:
tailscale lock add tlpub:trusted-key1, tlpub:trusted-key2
Remove a signing node
This command needs to be run from a node with a trusted tailnet lock key.
-
If you don’t already have the tailnet lock public key for each node you want to remove as a signing node, run
tailscale lock status
. The command displays the tailnet lock public key for the node. This key is of the form:tlpub:abcdef12
-
On a node with a trusted tailnet lock key, run the
tailscale lock remove
command, passing in the tailnet lock keys that you determined in the previous step.This examples removes two signing nodes:
tailscale lock remove tlpub:trusted-key7, tlpub:trusted-key8
How tailnet lock works with other Tailscale features
Take the following into consideration for how tailnet lock works with other Tailscale features.
Device approval
If you are using tailnet lock and device approval, a node needs to be both signed and approved before it can connect to a tailnet. We recommend disabling device approval when using tailnet lock, and then make any decisions to approve the node as part of the signature flow.
Nodes pre-approved with auth keys also need to be signed when you use tailnet lock, unless you sign the auth key.
Sharing
To use tailnet lock with the sharing feature , a node shared into a tailnet with tailnet lock will need to also be signed to be accessible.
Tailscale SSH Console
You can use Tailscale SSH Console to establish an SSH session for a signed node in your tailnet, provided:
- your tailnet policy file permits network access.
- a Tailscale SSH rule permits SSH access.
Access control lists
Access control lists (ACLs) define what a particular user or device is permitted to access on your tailnet, whether tailnet lock is enabled or disabled.
Configuration audit logging
Enabling, disabling, or modifying tailnet lock configuration creates events that will appear in the configuration audit logs.
Independent of configuration audit logging, you can run the
tailscale lock log
command on a node to see recent changes to your tailnet lock.
Limitations
- During the alpha, tailnet lock can be enabled, disabled, or modified only using the Tailscale CLI.
- You need to securely store the disablement secrets yourself. If you lose disablement secrets, and you did not provide one to Tailscale support, the tailnet cannot be recovered.
- If a malicious attacker takes over a node with a tailnet lock signing key, they can gain control of your network by creating more signers, and adding more nodes and signing them. We are working on how to address network takeover.
- Tailnet lock keys are stored on the device. If the device is compromised, the key can be obtained.