Network access controls (ACLs)

Tailscale supports network access control lists (ACLs). ACLs let you precisely define what a particular user or device is permitted to access on your Tailscale network (known as a tailnet).

ACLs are available on all plans, but certain functionality may be restricted on certain plans.

You need to be an Owner, Admin, or Network admin to edit the tailnet policy file.

Introduction

When you first create your tailnet, the ACL is in its default configuration, which allows all devices within the tailnet to communicate with one another. You can edit this rule at any point to restrict communication between devices, either through the admin console or Tailscale API. Tailscale’s ACL does not affect what a device can or cannot access on its own local network.

Tailscale will prevent communication between devices not explicitly defined by an allow rule in the ACL. This is why the default ACL configuration in a new tailnet allows all devices in the tailnet to reach one another. Otherwise, an immediate step in creating a new tailnet would be to configure access policies while adding your first devices.

Access rules can make use of groups to grant access to many users with few rules. Similarly, you can use tags to assign purpose-based identities to devices to further scale up your policies. Combined, groups and tags let you build powerful role-based access control (RBAC) policies. Depending on your definition, server tagging could also be considered a form of attribute-based access control (ABAC).

The access rules you define for your network get distributed to all the devices in your network, and enforcement of the rules happens on each device directly, without further involvement from Tailscale’s servers.

If you’d like to learn more about Tailscale’s approach to access control in general, we’ve written a detailed blog post that goes deep into the history of access control systems, and why we designed Tailscale’s access rules the way we did.

Tailscale policy syntax

Tailscale access control rules are expressed as a single “human JSON” tailnet policy file. HuJSON is a superset of JSON that allows comments and trailing commas. This makes a tailnet policy file easy to maintain while staying read/writable by both humans and machines.

For simple cases, you can edit the tailnet policy file by hand in the admin panel. Organizations with more complex needs can use the API to automatically update rules from software.

The tailnet policy file has several top-level sections relating to ACLs, which we explore in detail below:

  • acls, the access rules themselves.
  • groups, collections of users, to avoid repeating yourself in access rules.
  • hosts, human readable shorthands for IP addresses.
  • tests, which let you check the behavior of ACLs and avoid accidentally breaking an important permission.
  • tagOwners, to define which users can assign tags to a device.
  • autoApprovers, to define which users can advertise routes or exit nodes without further approval.
  • ssh, to define which users can establish a Tailscale SSH connection on which devices, and as which SSH users.
  • nodeAttrs, to define which devices can use certain features.

The tailnet policy file also contains network-wide policy settings unrelated to access control: derpMap, disableIPv4, and randomizeClientPort are documented in the Network policy options section of this article, for completeness.

An example tailnet policy file:

{
  "acls": [
    // dave@tailscale.com can access everything on host vega (defined below)
    {
      "action": "accept",
      "src": ["dave@tailscale.com"],
      "dst": ["vega:*"],
    },
    // The security group can access all HTTPS servers, and everything on
    // the corp network.
    {
      "action": "accept",
      "src": ["group:security"],
      "dst": [
        "*:443",
        "corp-network:*"
      ],
    },
    // The employees group can access web apps over HTTP.
    {
      "action": "accept",
      "src": ["group:employees"],
      "proto": "tcp",
      "dst": ["tag:webapps:80"],
    },
    // Only allow IP protocol 16 (CHAOS) to security
    {
      "action": "accept",
      "src": ["group:employees"],
      "proto": "16",
      "dst": ["group:security:*"],
    },
    // Both dave@tailscale.com and the security group can access lab devices.
    {
      "action": "accept",
      "src": ["dave@tailscale.com", "group:security"],
      "dst": ["tag:lab:*"],
    },
    // All lab devices can talk to each other, but nothing else.
    {
      "action": "accept",
      "src": ["tag:lab"],
      "dst": ["tag:lab:*"],
    },
    // Devices authenticated as the same user can talk to each other on port 22.
    {
      "action": "accept",
      "src": ["*"],
      "dst": ["autogroup:self:22"],
    },
  ],
  // Readable shorthands for devices and networks.
  "hosts": {
    "vega": "100.3.4.5",
    "corp-network": "10.0.0.0/8",
    "critical-corp-server": "10.0.0.1",
  },
  // Role-based groups of users.
  "groups": {
    "group:security": [
      "laura@tailscale.com",
      "daniel@tailscale.com",
    ],
    "group:employees": [
      "dave@tailscale.com",
      "laura@tailscale.com",
      "daniel@tailscale.com",
      "alice@tailscale.com",
      "bob@tailscale.com",
    ],
  },
  "tests": [
    // Security can always access HTTPS on vega, but not HTTP.
    {
      "src": "group:security",
      "accept": ["vega:443"],
      "deny": ["vega:80"],
    },
    // dave@tailscale.com can SSH into vega and the lab.
    {
      "src": "dave@tailscale.com",
      "accept": ["vega:22", "tag:lab:22"],
    },
    // Lab devices can never access a critical corp service.
    {
      "src": "tag:lab",
      "deny": ["critical-corp-server:80"],
    },
  ],
  "tagOwners": {
    "tag:lab": ["dave@tailscale.com"],
    "tag:security": ["group:security"],
    "tag:webapps": ["dave@tailscale.com"]
  },
  "autoApprovers": {
    // Alice can create subnet routers advertising routes in 10.0.0.0/24 that are auto-approved
    "routes": {
      "10.0.0.0/24": ["alice@tailscale.com"],
    },
    // A device tagged security can advertise exit nodes that are auto-approved
    "exitNode": ["tag:security"],
  },
  "ssh": [
    {
      // All users can SSH to their own devices, as non-root
      "action": "accept",
      "src": ["autogroup:member"],
      "dst": ["autogroup:self"],
      "users": ["autogroup:nonroot"]
    }
  ],
  "derpMap": {
    "regions": {
      "900": {
        "regionID": 900,
        "hostName": "custom-derp.example.com",
      },
    },
  },
  "disableIPv4": false,
  "randomizeClientPort": false,
}

Previewing changes

When editing the tailnet policy file in the admin console, you can preview the permissions granted to your users.

To do so, open the Preview rules tab and select a user from the dropdown. A list of destinations (one per line) accessible to the specified user is shown, as well the line number that defines that rule. It also includes any other users/groups that can access that destination due to that rule.

Another way to increase confidence in your changes is to define some ACL tests, to check that your changes don’t accidentally remove access to an important system, or accidentally open up access wider than you intended.

ACL rules

The acls section of the tailnet policy file is a list of access rules for your network. Each rule is a HuJSON object that grants access from a set of sources to a set of destinations.

All rules eventually boil down to allowing traffic from a particular source IP address to a destination IP address and port. While you can write rules that reference IP addresses directly, it’s more common to use higher-level specifiers like usernames and groups, which Tailscale automatically translates to the right low-level rules.

Each access rule looks like this:

{
  "action": "accept",
  "src": [ list-of-sources... ],
  "proto": "protocol", // optional
  "dst": [ list-of-destinations... ],
}
Previously we used users and ports, instead of src and dst, respectively. While both sets of terms are currently supported, we are using src and dst going forward.

Tailscale access rules are “default deny”, so the only possible action is accept, to allow traffic that would otherwise be denied.

The src field specifies a list of sources to which the rule applies. Each element in the list can be one of the following:

Type Example Meaning
Any * No restriction on the source
User shreya@example.com All devices currently signed in as the given user
Group (ref) group:example Same as listing every user in the group explicitly
Tailscale IP 100.101.102.103 Only the device that owns the given Tailscale IP. IPv6 addresses must follow the format [1:2:3::4]:80.
Subnet CIDR Range (ref) 192.168.1.0/24 Any IP within the given subnet
Hosts (ref) my-host Looks up the Tailscale IP or CIDR in the hosts section
Tags (ref) tag:production All devices currently tagged with the given tag
Autogroups (ref) autogroup:member Devices of users, destinations, or usernames with the same properties or roles

The proto field is optional, and specifies the protocol to which the rule applies. (If no protocol is specified, then the ACL rule applies to all TCP and UDP traffic.)

A proto field can only be included in an ACL rule for Tailscale version v1.18.2 or later. Older clients will fail closed, blocking traffic for ACL rules with protocols, unless it is otherwise allowed.

If traffic is allowed for a given pair of IPs, then ICMP will also be allowed.

proto can be specified as either an IANA IP protocol number 1-255 (e.g., "16") or one of the following named aliases (e.g., "sctp"):

Protocol proto IANA protocol number
Internet Group Management (IGMP) igmp 2
IPv4 encapsulation ipv4, ip-in-ip 4
Transmission Control (TCP) tcp 6
Exterior Gateway Protocol (EGP) egp 8
Any private interior gateway igp 9
User Datagram (UDP) udp 17
Generic Routing Encapsulation (GRE) gre 47
Encap Security Payload (ESP) esp 50
Authentication Header (AH) ah 51
Stream Control Transmission Protocol (SCTP) sctp 132

Only TCP, UDP, and SCTP traffic support specifying ports. For all other protocols, the port specified needs to be *.

The dst field specifies a list of destination devices and ports to which the rule applies. Each element in the list is of the form host:ports. host is one of the following:

Type Example Meaning
Any * No restriction on the destination
User shreya@example.com Any device currently signed in as the given user
Group (ref) group:example Same as listing every user in the group explicitly
Tailscale IP 100.101.102.103 Only the device that owns the given Tailscale IP
Hosts (ref) my-host Looks up the Tailscale IP in the hosts section
Subnet CIDR Range (ref) 192.168.1.0/24 Any IP within the given subnet
Tags (ref) tag:production Any device currently tagged with the given tag
Internet access (ref) autogroup:internet Access to the internet through exit nodes
Own devices autogroup:self Access to devices where the same user is authenticated on both the src and the dst. This does not include devices the user has ACL tags.
Tailnet devices autogroup:member Access to devices on the tailnet where the user is a direct member (not a shared user) of the tailnet
Admin devices autogroup:admin Access to devices where the user is an Admin
Network admin devices autogroup:network-admin Access to devices where the user is a Network admin
IT admin devices autogroup:it-admin Access to devices where the user is an IT admin
Billing admin devices autogroup:billing-admin Access to devices where the user is a Billing admin
Auditor devices autogroup:auditor Access to devices where the user is an Auditor
Owner devices autogroup:owner Access to devices where the user is the tailnet Owner

ports is one of the following:

Type Example
Any *
Single 22
Multiple 80,443
Range 1000-2000

Users

Users are available for the Free, Premium, and Enterprise plans.

Users can be specified in both the source (src) and destination (dst) fields of an access rule. Users must be referenced using the full email address they use to sign into Tailscale.

If you sign into your network with GitHub, use the form username@github. For example, the GitHub user alice should be written as alice@github.

Referencing an external user in an access rule does not implicitly grant them access to your Tailscale network. However, if you’ve shared a device with someone outside your Tailscale network, you can use their Tailscale login email in ACLs to further restrict what they can access on the shared device.

Groups

Groups are available for the Free, Premium, and Enterprise plans.

The groups section lets you define a shorthand for a group of users, which you can then use in ACL rules instead of listing users out explicitly. Any change you make to the membership of a group is automatically propagated to all the rules that reference that group.

A groups definition looks like this:

"groups": {
  "group:engineering": [
    "dave@example.com",
    "laura@example.com",
  ],
  "group:sales": [
    "brad@example.com",
    "alice@example.com",
  ],
},

Every group name must start with the prefix group:. Each member of a group is specified by their full email address, as explained in the users section above. To avoid the risk of obfuscating group membership, groups cannot contain other groups.

You can edit only groups that are defined in ACLs. That is, while you can use groups that are synced from a System for Cross-domain Identity Management (SCIM) integration or tailnet autogroups, you cannot edit them.

You can add or remove a user’s group membership by editing the tailnet policy file, as shown in the example groups definition above, and directly from the Users page of the admin console.

Editing a user’s group membership from the Users page

You need to be an Owner, Admin, or Network admin to edit a user’s group membership from the Users page, same as for editing ACLs in general.

  1. Open the Users page in the admin console.
  2. Find the user by name.
  3. Click the ellipsis icon menu and then click Edit group membership.
  4. In the Edit group membership dialog:
    1. To add a group, click Add to a group and select the group to add.
    2. To remove a group, click the X next to the group to delete.
  5. When you are done editing the groups for the user, click Save.

Autogroups

Autogroups are available for all plans.

An autogroup is a special group that automatically includes users, destinations, or usernames with the same properties, which you can then use in access rules.

Where allowed Autogroup Meaning Availability by plan
As a dst autogroup:internet Used to allow access for any user through any exit node in your tailnet. You cannot restrict access to only some exit nodes. Available on all plans
autogroup:self Used to allow access for any user that is authenticated as the same user as the source. Does not apply to tags.
As a src or dst, tagOwner, or autoApprover autogroup:owner Used to allow access for the tailnet Owner. Available on all plans
autogroup:admin Used to allow access for any user who has the role of Admin.
autogroup:member Used to allow access for any user who is a direct member (including all invited users) of the tailnet. Users from shared nodes are not included.
autogroup:tagged Used to allow access for any node which is tagged.
autogroup:auditor Used to allow access for any user who has the role of Auditor. Available on the Free, Premium, and Enterprise plans
autogroup:billing-admin Used to allow access for any user who has the role of Billing admin.
autogroup:it-admin Used to allow access for any user who has the role of IT admin.
autogroup:network-admin Used to allow access for any user who has the role of Network admin.
As a src autogroup:shared Used to allow access for any user who accepted a sharing invitation to your network. This lets you write rules without knowing sharee email addresses in advance. Available on all plans
As an SSH user autogroup:nonroot Used to allow Tailscale SSH access to any user that is not root. Available on the Free, Premium, and Enterprise plans
autogroup:self only applies to user-owned nodes, not also tagged nodes. You cannot use autogroup:self with autogroup:tagged.
Previously we used autogroup:members instead of autogroup:member. While both are currently supported, we are using autogroup:member going forward. You cannot use both autogroup:member and autogroup:members in the same tailnet policy file.

Here’s an example ssh rule that allows all users to have Tailscale SSH access to their own devices, as non-root:

  "ssh": [
    {
      // All users can SSH to their own devices, as non-root
      "action": "accept",
      "src": ["autogroup:member"],
      "dst": ["autogroup:self"],
      "users": ["autogroup:nonroot"]
    }

Important note about autogroup:nonroot

In the default ACL, the ssh rule uses autogroup:self for the dst field and autogroup:nonroot in the users field. If you change the dst field from autogroup:self to some other destination, such as an ACL tag, also consider replacing autogroup:nonroot in the users field. If you don't remove autogroup:nonroot from the users field, then anyone permitted by the src setting will be able to SSH in as any nonroot user on the dst device.

Hosts

Hosts are available for all plans.

The hosts section lets you define a human-friendly name for an IP address or CIDR range, to make access rules more readable.

A hosts definition looks like this:

"hosts": {
  "example-host-1": "100.100.100.100",
  "example-network-1": "100.100.101.100/24",
},

The human-friendly name cannot include the character @.

Tests

ACL tests are available for all plans.

The tests section lets you write assertions about your access rules, which are checked whenever the tailnet policy file is changed. Failing assertions cause the new tailnet policy file to be rejected, with an error detailing which test assertion wasn’t met.

Just like writing tests for software, ACL tests let you ensure that an important permission isn’t accidentally revoked later on, or that a critical system in your network isn’t exposed more than expected.

A tests definition looks like this:

"tests": [
  {
    "src": "dave@example.com",
    "accept": ["example-host-1:22", "vega:80"],
    "deny": ["1.2.3.4:443"],
  },
],

The src field specifies the user identity being tested, which can be a user’s email address, a group, an ACL tag, or a host that maps to an IP address. The test case will be run from the perspective of a device signed in as that user, with that group membership, with that tag, or as that host, respectively.

The accept and deny fields specify destinations that the ACL rules should accept or deny, respectively.

Previously we used allow, instead of accept, in ACL tests. While both terms are currently supported, we are using accept going forward.

Each destination in the list is of the form host:port, where port is a single numeric port and host is one of the following:

Type Example Meaning
Tailscale IP 100.101.102.103 The Tailscale IP of the device. IPv6 addresses must follow the format [1:2:3::4]:80.
Hosts (ref) my-host Looks up the Tailscale IP in the hosts section
User shreya@example.com The Tailscale IP of a device currently signed in as the given user
Group group:security@example.com The Tailscale IP of a device currently signed in as a representative member of the given group
Tags (ref) tag:production The Tailscale IP of a device currently tagged with the given tag

Protocols cannot yet be included in ACL tests.

Sources in src and destinations in accept and deny must refer to specific entities and do not support * wildcards. For example, an accept destination cannot be tags:*.

Tag Owners

ACL tags are available for all plans.

The tagOwners section of the tailnet policy file defines the tags that can be applied to devices, and the list of users who are allowed to assign each tag.

Tags are a substitute for a human identity on a device. That is, rather than a device being authenticated as a particular user, the device’s identity on the Tailscale network is the set of tags assigned to it. You can learn more in our article on server role accounts with ACL tags.

A tagOwners definition looks like this:

"tagOwners": {
  "tag:webserver": [
    "group:engineering",
  ],
  "tag:secure-server": [
    "group:security-admins",
    "president@example.com",
  ],
  "tag:corp": [
    "autogroup:member",
  ],
}

Every tag name must start with the prefix tag:. A tag owner can be a user’s full login email address (as defined in the users section above), a group name, or an autogroup.

A shorthand notation, [], is available for autogroup:admin. That is, the following are equivalent:

"tag:monitoring": [
  "autogroup:admin",
],
"tag:monitoring": [
  "[]",
],

autogroup:admin and autogroup:network-admin can assign any tags, so [] implicitly means that only autogroup:admin and autogroup:network-admin are allowed.

Auto Approvers for routes and exit nodes

Auto Approvers are available for all plans.
Auto Approvers are currently in beta.

The autoApprovers section of the tailnet policy file defines the list of users who can perform certain actions without requiring further approval from the admin console. This includes advertising a specified set of routes as a subnet router or advertising an exit node. For routes, this also permits the auto approvers to advertise a subnet of the specified routes.

An Owner, Admin, or Network admin can still disable the route or exit node from the admin console. To avoid the same route being advertised and auto-approved again, consider modifying autoApprovers.

If the device is re-authenticated by a different user who cannot advertise the route or exit node, or the user who advertised it is suspended or deleted, the route or exit node is no longer advertised. To avoid this, consider making an ACL tag an auto approver.

An autoApprovers definition looks like this:

"autoApprovers": {
  "routes": {
    "10.0.0.0/24": ["group:engineering", "alice@example.com", "tag:foo"],
  },
  "exitNode": ["tag:bar"],
}

The auto approver of a route or exit node can be a user’s full login email address (as defined in the users section above), a group name, an autogroup or a tag.

Tailscale SSH

Tailscale SSH is available for the Free, Premium, and Enterprise plans.
Tailscale SSH is currently in beta.

The ssh section of the tailnet policy file defines the lists of users and devices that can use Tailscale SSH, and as which SSH users. For a connection to be permitted, the tailnet policy file must contain rules permitting both network access and SSH access:

  1. An access rule to allow connections from the source to the destination on port 22.
  2. An SSH access rule to allow connections from the source to the destination and the given SSH users. This is used for Tailscale SSH, to distribute keys for authenticating SSH connections.

An ssh definition looks like this:

{
  "action": "check", // "accept" or "check"
  "src": [ list-of-sources... ],
  "dst": [ list-of-destinations... ],
  "users": [ list-of-ssh-users... ],
  "checkPeriod": "20h", // optional, only for check actions. default 12h
},

The action field specifies whether to accept the connection or to perform additional checks on it.

The src field is the source where a connection originates from. This can be a user, group, autogroup, or tag.

The dst field is the destination where the connection goes. This can be a user, tag, or autogroup. Note that unlike ACLs, a port cannot be specified. Only port 22 is allowed, and does not need to be specified as it is used by default.

The users field is the set of allowed usernames on the host. An SSH rule can also specify autogroup:nonroot to allow any user that is not root. If no user is specified, Tailscale will use the local host’s user. That is, if you are logged in as alice locally, then SSH to another device, Tailscale SSH will try to log in as user alice. Like other SSH clients, Tailscale will only use user accounts that already exist on the host, not create new accounts.

Optionally, for check mode only, the checkPeriod field is the time period for which to allow a connection before requiring a check. This can be specified in minutes or hours, with a minimum of one minute and a maximum of 168 hours (one week). If not specified, this is 12 hours.

SSH access rules are evaluated considering the most restrictive policies first:

  • Check policies
  • Accept policies

For example, if you have an access rule allowing the user alice@example.com to access a resource with an accept rule, and a rule allowing group:devops which alice@example.com belongs to, to access a resource with a check rule, then the check rule applies.

New tailnets or existing tailnets that have not modified their ACLs have a default SSH policy allowing users to access their own devices using check mode.

The only kinds of connections that are allowed are:

  • From a user to their own devices, as any user including root.
  • From a user to a tagged device, as any user including root.
  • From a tagged device to another tagged device, for any tags. Note that an SSH access rule from a tagged device cannot be in check mode.
  • From a user to a device that has been shared with them, as long as the destination host has Tailscale configured with SSH and the destination’s ACL allows the user to connect over SSH.

That is, the broadest policy allowed would be:

{
  "acls": [
    {
      "action": "accept",
      "src": ["*"],
      "dst": ["*:*"]
    }
  ],
  "ssh": [
    {
      "action": "accept",
      "src": ["autogroup:member"],
      "dst": ["autogroup:self"],
      "users": ["root", "autogroup:nonroot"]
    },
    {
      "action": "accept",
      "src": ["autogroup:member"],
      "dst": ["tag:prod"],
      "users": ["root", "autogroup:nonroot"]
    },
    {
      "action": "accept",
      "src": ["tag:logging"],
      "dst": ["tag:prod"],
      "users": ["root", "autogroup:nonroot"]
    },
  ]
}

To allow a user to only SSH to their own devices, as non-root:

{
  "acls": [
    {
      "action": "accept",
      "src": ["*"],
      "dst": ["*:*"]
    }
  ],
  "ssh": [
    {
      "action": "accept",
      "src": ["autogroup:member"],
      "dst": ["autogroup:self"],
      "users": ["autogroup:nonroot"]
    }
  ]
}

To allow group:sre to access devices in the production environment tagged tag:prod:


{
  "groups": {
    "group:sre": ["alice@example.com", "bob@example.com"]
  },
  "acls": [
    {
      "action": "accept",
      "src": ["group:sre"],
      "dst": ["tag:prod:*"]
    },
  ],
  "ssh": [
    {
      "action": "accept",
      "src": ["group:sre"],
      "dst": ["tag:prod"],
      "users": ["ubuntu", "root"],
    },
  ]
  "tagOwners": {
    // users in group:sre can apply the tag tag:prod
    "tag:prod": ["group:sre"]
  }
}

Node attributes

Node attributes are currently in alpha.

The nodeAttrs section of the tailnet policy file defines additional attributes that apply to certain devices in your tailnet. You can use this to set different NextDNS configurations for different devices in your tailnet.

A nodeAttrs definition looks like this:

"nodeAttrs": [
    {
        "target": ["my-kid@my-home.com", "tag:server"],
        "attr": [
            "nextdns:abc123",
            "nextdns:no-device-info",
        ],
    },
],

The target field specifies which nodes the attributes apply to. This can be a tag (tag:server), user (alice@example.com), group (group:kids), or *.

The attr field specifies which attributes apply to those nodes. For this example, the attributes are:

  • nextdns:abc123, for a NextDNS configuration abc123. If this is used, the attribute overrides the global NextDNS configuration.
  • nextdns:no-device-info, to disable sending device metadata to NextDNS.

This example allows members of the tailnet to use Tailscale Funnel on their nodes:

"nodeAttrs": [
    {
         "target": ["autogroup:members"],
         "attr":   ["funnel"],
     },
],

Network policy options

Network policy options are available for all plans.

In addition to access rules, the tailnet policy file includes a few network-wide policy settings for specialized purposes. Most networks should never need to specify these.

The derpMap section lets you add custom DERP servers to your network, which your devices will use as needed to relay traffic. You can also use this section to disable the use of Tailscale-provided DERP servers, for example to meet corporate compliance requirements. The derpMap section is detailed in the article on running custom DERP servers.

The disableIPv4 field, if set to true, stops assigning Tailscale IPv4 addresses to your devices. All devices in your network will receive exclusively IPv6 Tailscale addresses, and devices that do not support IPv6 (e.g. systems that have IPv6 disabled in the operating system) will be unreachable. This option is intended for users who have a pre-existing conflicting use of the 100.64.0.0/10 carrier-grade NAT address range.

The OneCGNATRoute field controls the routes that Tailscale clients will generate.

Tailscale clients can have either:

  • One large 100.64/10 route to avoid churn in the routing table as nodes go online and offline. (The churn is disruptive to Chromium-based browsers on macOS.)
  • Fine-grained /32 routes.

The possible values for OneCGNATRoute are:

  • An empty string or not provided: Use default heuristics for each platform.
    • On macOS (for Tailscale v1.28 or later), Tailscale will prefer to add one large 100.64/10 route. Tailscale will not do this if there are other interfaces that also route IP addresses in that range.
    • On other platforms, Tailscale will add fine-grained /32 routes for each node.
  • "mac-always": macOS clients will always add one 100.64/10 route.
  • "mac-never": macOS clients will always add fine-grained /32 routes.

The randomizeClientPort field, if set to true, makes devices prefer a random port for WireGuard traffic over the default static port 41641. This option is intended as a workaround for some buggy firewall devices, and should only be enabled after consulting with Tailscale (contact support).

Subnet routers and exit nodes

ACLs can only allow connections, not reject them. ACLs don’t limit discovery of routes. So, you can restrict access to a node separately from access to a subnet that node routes to, if it’s a subnet router; or public IP, if it’s an exit node.

To restrict access to a subnet, ensure that no ACL allows access to those routes. You can enforce this with a test, which will fail if any rule accidentally allows access, like so:

"tests": [
   {
     "src": "not-allowed@example.com",
     "accept": ["100.101.102.103:22"], // allow access to the tailscale IP
     "deny": ["192.168.0.7:22"], // does not allow access to the subnet
   }
],

To restrict access to all exit nodes, only grant access to autogroup:internet to those who you wish to use exit nodes. You can enforce this with a test, which will fail if any rule accidentally allows access to a public IP, like so:

"tests": [
   {
     "src": "not-allowed@example.com",
     "accept": ["100.101.102.103:22"], // allow access to the tailscale IP
     "deny": ["8.8.8.8:22"], // does not allow access to a public IP
   }
],

Right now, there is no way to restrict use of specific exit nodes using ACLs. Subscribe to this GitHub issue for updates.

Taildrop precedence

Taildrop permits you to share files between devices that you are logged in to, even if ACLs are used to restrict access to the devices.

Debugging ACLs

To debug whether ACLs block communication between nodes, use tailscale ping. There are two types of ping checks that tailscale ping can do: TSMP and ICMP.

TSMP pings check whether two nodes can establish a network connection, but stops before the ACL check. Use tailscale ping --tsmp to send a TSMP ping.

ICMP pings check the end-to-end connectivity between nodes, including ACLs. Use tailscale ping --icmp or regular ping to send an ICMP ping.

If TSMP ping succeeds but ICMP ping fails, connections between nodes are likely blocked by ACLs. If TSMP ping fails, nodes cannot establish a network connection, even though ACLs may allow connections. If both TSMP and ICMP pings succeed but connections still fail, check the port numbers in your ACLs and services you are trying to connect to.

In addition to manual testing, built-in ACL tests ensure that specific connections are allowed and prevent ACL changes from accidentally breaking these connections.

ACL availability by plan

Restrictions Restricted use of ACLs Full use of ACLs
Availability Available on all plans Available on the Free, Premium, and Enterprise plans
Access rules for...
  • Any
  • Tailscale IP
  • Subnet CIDR Range
  • Autogroups
  • Tags
  • Hosts
  • Any
  • Tailscale IP
  • Subnet CIDR Range
  • Autogroups
  • Groups
  • Users
  • Tags
  • Hosts
Access rules specifying...
  • Ports
  • Protocols
  • Ports
  • Protocols
ACL sections for...
  • acl
  • hosts
  • tests
  • tagOwners
  • autoApprovers
  • nodeAttrs
  • acl
  • groups
  • hosts
  • tests
  • tagOwners
  • autoApprovers
  • ssh for Tailscale SSH
  • nodeAttrs for Tailscale Funnel

Last updated