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.

Tailnet lock is currently in alpha. To try it, follow the steps below to enable it for your network using Tailscale v1.34 or later.
This feature is currently an invite only feature. To request access, visit the Feature Previews page in the admin console and click Join Tailnet Lock waitlist.

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 can 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.

  1. 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.

  2. Request access in the Feature Previews page of the admin console.

  3. 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.

  4. 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 running tailscale 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, ...>
    
  5. 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.

The disablement secrets are displayed only when you initialize tailnet lock. Make note of them and secure them in a safe place.

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:

  1. Open the Machines page in the admin console.
  2. Click the node that needs to be signed. A node that needs to be signed has the Locked out badge.
  3. Copy the tailscale lock sign command needed to sign the node.

Alternatively, to determine the tailscale lock sign using the Tailscale CLI:

  1. On the node that you want to add to your tailnet, run:

    tailscale lock status
    
  2. In the output of tailnet lock status, copy the tailscale 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 signing node

  1. 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

  2. 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.

  1. 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

  2. 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 authorization

If you are using tailnet lock and device authorization, a node needs to be both signed and approved before it can connect to a tailnet. We recommend disabling device authorization when using tailnet lock, and then make any decisions to authorize the node as part of the signature flow.

Nodes pre-authorized with auth keys also need to be signed when you use tailnet lock.

Sharing

In alpha, tailnet lock does not work with the sharing feature. To use tailnet lock with sharing, a node shared into a tailnet with tailnet lock will need to also be signed to be accessible. This is currently not possible.

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.
  • Tailnet lock does not work with shared nodes.
  • Tailscale SSH Console does not work with tailnet lock.
  • 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.

Last updated

WireGuard is a registered
trademark of Jason A. Donenfeld.

© 2023 Tailscale Inc.

Privacy & Terms