Tailscaleロゴ

グラントの構文リファレンス

最終検証日:
翻訳: 竹洞 陽一郎

Tailscaleのグラントは、ネットワーク層とアプリケーション層のケイパビリティを共通の構文に統合する、統一されたアクセス制御システムです。
これは、Tailscaleのアクセス制御リスト(ACL)の進化形であり、リソースアクセスに対する柔軟性ときめ細かな制御を強化しています。
グラントシステムは、アクセスを明示的に許可する必要のあるデフォルト拒否(deny-by-default)のアプローチを通じて、最小権限ゼロトラストの原則を実装しています。

このリファレンスガイドでは、tailnetポリシーファイルで定義されるグラントの構文と使い方について説明します。
基本的な構造、利用可能なセレクター、よくあるシナリオの実装例を扱います。
このドキュメントは、Tailscaleネットワーク(tailnetと呼ばれます)、タググループといった、Tailscaleの基本的な概念に読者が精通していることを前提としています。

中核となる概念

グラントは、誰がどの条件下でどのリソースにアクセスできるかを指定する、宣言的なモデルに従います。
各グラントには、少なくとも送信元(src)、宛先(dst)、そしてネットワーク層のケイパビリティip)とアプリケーション層のケイパビリティapp)のいずれか、または両方が必要です。
デバイスポスチャの要件srcPosture)とルーティングの指定via)はオプションです。

1つのsrcまたはdst配列に複数のセレクターを列挙した場合、Tailscaleのポリシーエンジンは、いずれかのセレクターに一致するすべてのエンティティの和集合を使用します。

グラントはデフォルト拒否(deny-by-default)の原則に従っており、明示的に許可された場合にのみアクセスが許可されます。
複数のグラントが1つの接続に一致する場合、Tailscaleのポリシーエンジンは、許可されたすべてのケイパビリティの和集合を適用します。
より具体的なグラントが、より一般的なグラントを上書きすることはなく、両者は加算されます。
さらに、アプリケーションケイパビリティは、デバイスがネットワークレベルのアクセス権を持つ場合にのみ適用されます。

構文

グラントの定義は、宣言的で人間が読みやすいJSON構文を使って、tailnetポリシーファイルのgrantsセクションに記述します。基本構造は次のパターンに従います。

{
  "grants": [
    {
      "src": ["<list-of-sources>"],
      "dst": ["<list-of-destinations>"],
      "ip": ["<list-of-ports-or-protocols>"],
      "app": {
        "<capability-identifier>": [
          {
            "<parameter-name>": "<parameter-value>",
            // 必要に応じて追加のパラメーター
          }
        ]
      },
      "srcPosture": ["<list-of-posture-conditions>"],
      "via": ["<list-of-routing-devices>"]
    }
    // 必要に応じて追加のグラント
  ]
}

ビジュアルポリシーエディタを使ってtailnetポリシーファイルを管理することもできます。
ビジュアルエディタの使い方については、ビジュアルエディタリファレンスを参照してください。

appを除くすべてのグラントのプロパティは(要素が1つだけであっても)配列として存在します。appは、ケイパビリティ識別子をパラメーターオブジェクトの配列にマッピングするマップです。

グラントには暗黙的なacceptアクションがあり、指定された範囲内で本質的に許可的に動作します。
ポリシーエンジンはすべてのグラントをコンパイルし、Tailscaleクライアントに配布し、クライアントはこれをローカルにキャッシュします。

送信元セレクター

送信元(src)フィールドは、接続を開始するネットワークの送信元を定義します。
これには、デバイス、ユーザー、グループ、IP範囲、その他のセレクターを指定できます。
すべてのグラント定義にはsrcフィールドが必要で、セレクターの配列を受け付けます。
さまざまな種類のセレクターを使って、tailnet内の特定のエンティティやエンティティのグループをターゲットにできます。

以下の表は、利用可能なすべての送信元セレクターとその意味、および正確なアクセスポリシーを構築するための使用パターンの例をまとめたものです。

送信元セレクター一覧
セレクター 説明
* tailnet内のすべての送信元、および承認済みのサブネットルートからの送信元を選択します。(承認済みサブネット上にある場合を除き)tailnet外のデバイスは含まれません。 *
group:<groupName> 特定のグループのすべてのメンバーを選択します。 group:prod
<email> メールアドレスで特定のユーザーを選択します。GitHubユーザーの場合はusername@github、Passkeyユーザーの場合はusername@passkeyを使用します。 user@example.comusername@github
tag:<tagName> 特定のタグを持つすべてのデバイスを選択します。 tag:server
autogroup:<role> 特定のロールのすべてのメンバーを選択します。指定できるロールは、adminmemberownerit-adminnetwork-adminbilling-adminauditorです。 autogroup:admin
autogroup:tagged タグ(任意のタグ)が付いたすべてのデバイスを選択します。 autogroup:tagged
autogroup:shared tailnetへの共有招待を承諾したユーザーが所有するすべてのデバイスを選択します。 autogroup:shared
<cidr>/<ip> CIDR範囲内のすべてのデバイスを選択します。 192.0.2.0/24192.0.2.5
<hostAlias> ユーザー定義のエイリアスでホストを選択します。このセレクターを使って、特定のデバイスやCIDR範囲へのアクセスを許可できます。hostAliasの定義はhostsセクションにあります。 example-host-name
ipset:<ipsetName> IPセット(名前付きのIPアドレス範囲のグループ)を選択します。 ipset:prod

宛先セレクター

宛先(dst)フィールドは、送信元がアクセスできるエンドポイントを定義します。
これには、デバイス、ユーザー、グループ、IP範囲、その他のセレクターを指定できます。
すべてのグラント定義にはdstフィールドが必要で、セレクターの配列を受け付けます。
宛先セレクターには、送信元で使用できるすべてのオプションに加えて、宛先専用の追加セレクターが含まれます。

宛先セレクター一覧
セレクター 説明
* tailnet内のすべての送信元、および承認済みのサブネットルートからの送信元を選択します。(承認済みサブネット上にある場合を除き)tailnet外のデバイスは含まれません。 *
group:<groupName> 特定のグループのすべてのメンバーを選択します。 group:analytics
<email> メールアドレスで特定のユーザーを選択します。GitHubユーザーの場合はusername@github、Passkeyユーザーの場合はusername@passkeyを使用します。 name@example.comusername@githubusername@passkey
tag:<tagName> 特定のタグを持つすべてのデバイスを選択します。 tag:tailsql
svc:<serviceName> 特定のTailscale Serviceを選択します。 svc:web-server
autogroup:<role> 特定のロールのすべてのメンバーを選択します。指定できるロールは、adminmemberownerit-adminnetwork-adminbilling-adminauditorです。 autogroup:admin
autogroup:tagged タグ(任意のタグ)が付いたすべてのデバイスを選択します。 autogroup:tagged
autogroup:internet autogroup:internetは、Exit Nodeを使ったインターネットへのアクセスを許可するための特別なオートグループセレクターです。 autogroup:internet
autogroup:self ユーザー自身のデバイスを選択します。autogroup:selfは特別なオートグループセレクターで、srcセレクターのautogroup:<role>group:<name>、または個々のユーザーと組み合わせることで、ユーザー自身のデバイスから、そのユーザー自身の他のデバイスへのアクセスを許可できます。 autogroup:self
<cidr>/<ip> CIDR範囲内のすべてのデバイスを選択します。 192.0.2.0/24192.0.2.5
<hostAlias> ユーザー定義のエイリアスでホストを選択します。このセレクターを使って、特定のデバイスやCIDR範囲へのアクセスを許可できます。hostAliasの定義はhostsセクションにあります。 example-host-name
ipset:<ipsetName> IPセット(名前付きのIPアドレス範囲のグループ)を選択します。 ipset:prod

これらのセレクターを使って、正確な宛先の範囲を定義できます。
例えば、tag:databaseを使ってデータベースへのアクセスを許可したり、tag:prodtag:devで本番環境と開発環境の両方へのアクセスを許可したり、autogroup:internetExit Node経由のインターネットへのアクセスを許可したりできます。

グラント内のCIDRセレクターは、どのトラフィックを許可するかを制御するものであり、クライアントのルーティングテーブルにどのルートを注入するかを制御するものではありません。
192.168.0.0/16を許可するグラントを設定しても、その範囲へのルートが注入されるわけではありません。
ルートは、サブネットルーターがそれをアドバタイズし、管理者が承認した時に注入されます。
詳しくは、ルート注入のリファレンスを参照してください。

ネットワーク層のケイパビリティ

ipフィールドは、ポートやプロトコルといった、ネットワーク層のケイパビリティを定義します。
このフィールド、またはappフィールド、あるいはその両方を含める必要があります。
省略した場合、他のルールで許可されていない限り、送信元はネットワーク層のアクセス権を持ちません。
指定した場合、許可するポートとプロトコルを指定するセレクターの配列を受け付けます。
ネットワーク層のケイパビリティは、送信元と宛先の間で許可する通信チャネルを決定することで、アクセス制御の基盤を形成します。
以下の表は、利用可能なネットワーク層のケイパビリティセレクターとその説明を示しており、広範なすべてのプロトコルへのアクセスから、プロトコルとポートを正確に絞り込んだ組み合わせまでのオプションを提供します。

ネットワーク層のケイパビリティセレクター
セレクター 説明
* 宛先のすべてのポートへのアクセスを許可します(TCP、UDP、ICMPアクセスを含意します)。 *
<port> 宛先の特定のポートへのアクセスを許可します(TCP、UDP、ICMPアクセスを含意します)。単一のポート(443)またはポート範囲(80-443)を指定できます。 44380-443
<proto>:* 指定したプロトコル(proto)のすべてのポートへのアクセスを宛先に許可します。ICMPのようにポートを持たないプロトコルで特に有用です。例えば、icmp:*sctp:*です。 icmp:*sctp:*
<proto>:<port> 宛先で特定のプロトコルとポートの組み合わせへのアクセスを許可します。単一のポート(tcp:443)またはポート範囲(tcp:80-443)を指定できます。 tcp:443tcp:80-443

プロトコルを指定する際は、IANA IPプロトコル番号(1〜255)、または名前付きエイリアスのいずれかを使用できます。
以下の表は、一般的なプロトコル名と対応するIANA番号のマッピングであり、ネットワークケイパビリティを定義する際に、数値コードの代わりに人間が読みやすいプロトコル識別子を使用できるようにします。
これにより、正しく適用するために必要な技術的な正確さを保ちながら、グラント定義の読みやすさと保守性が向上します。

プロトコル名とIANA番号の対応
プロトコル 名前付きエイリアス IANA番号
Internet Group Management(IGMP)igmp2
IPv4 encapsulationipv4ip-in-ip4
Transmission Control(TCP)tcp6
Exterior Gateway Protocol(EGP)egp8
Any private interior gatewayigp9
User Datagram(UDP)udp17
Generic Routing Encapsulation(GRE)gre47
Encap Security Payload(ESP)esp50
Authentication Header(AH)ah51
Stream Control Transmission Protocol(SCTP)sctp132

アプリケーション層のケイパビリティ

appフィールドはオプションのフィールドで、付与するアプリケーション層のケイパビリティを定義する、文字列からオブジェクトの配列へのマップです。
文字列は付与するアプリケーションケイパビリティの文字列であり、オブジェクトはそれらのケイパビリティのパラメーターです。

個々のアプリケーション(golinkなど)は、<domainName>/<capabilityName>という形式で、ケイパビリティの名前を定義します。

個々のアプリケーションは、各ケイパビリティのパラメーターも定義します。
Tailscaleのポリシーエンジンは、これらのパラメーターを不透明なJSONオブジェクトとして扱います。
ポリシーエンジンはパラメーターをコンパイルしてTailscaleクライアントに送信しますが、そのフィールドが有効なJSONであることのみを確認します。
特定のスキーマに対してパラメーターを検証することはありません。
クライアントは、これらのパラメーターを使って、ローカルで認可の判断を行えます。

"app": {
  "<domainName>/<capabilityName>": [
    {
      "<parameterName>": "<parameterValue>",
      // アプリケーションが定義する追加のパラメーター
    }
  ]
}

(Tailscale自身のアプリケーションである場合を除き)Tailscaleは、アプリケーションケイパビリティやそのパラメーターの作成、命名、検証には関与しません。
すべてのケイパビリティとパラメーターを文書化することは、アプリケーション開発者の責任です。

アプリケーションケイパビリティは、アプリケーション内で許可する操作をきめ細かく制御します。
例えば、次のようにして、すべてのTailSQLデータソースへのアクセスを許可できます。

"app": {
  "tailscale.com/cap/tailsql": [
    {
      "dataSrc": ["*"]
    }
  ]
}

次のようにして、golinkに管理者権限を付与できます。

"app": {
  "tailscale.com/cap/golink": [
    {
      "admin": true
    }
  ]
}

または、次のようにしてKubernetesのなりすまし(impersonation)ケイパビリティを付与できます。

"app": {
  "tailscale.com/cap/kubernetes": [
    {
      "impersonate": {
        "groups": ["system:masters"]
      }
    }
  ]
}

デバイスポスチャの要件

srcPostureフィールドは、ネットワークの送信元(src)をさらに制限するために使用できる、デバイスポスチャ条件の配列です。
例えば、srcPostureを使って、特定のバージョンのTailscaleクライアントを実行しているデバイスのみに、アクセスを制限できます。

デバイスポスチャの要件は、特定のセキュリティ基準や構成基準を満たすデバイスのみが接続を確立できるようにするのに役立ちます。
例えば、アクセスに特定のmacOSバージョンを要求したり、複数のデバイス条件を要求したりできます。

ルーティングの指定

viaフィールドは、送信元(src)から宛先(dst)へのルーティング方法をTailscaleがどのように行うかを指定できるようにすることで、グラントにルーティングの認識をもたらします。
via構文を使うと、送信元が特定の宛先を使用する際にアクセスできる、Exit Node、サブネットルーター、またはアプリコネクタを定義できます。
例えば、エンジニアリングチームのグループからGitHubアプリコネクタへ向かうトラフィックが、特定のExit Nodeを必ず経由するようにグラントを作成できます。

viaフィールドは、送信元から宛先へのトラフィックがどのようにルーティングされる必要があるかを指定します。
このフィールドはオプションで、Exit Node、サブネットルーター、アプリコネクタなど、ルーティングを行うデバイスを識別するタグの配列を受け付けます。

グラントでviaフィールドを使うと、次のようなことができます。

任意のExit Node、サブネットルーター、またはアプリコネクタを経由して、任意のデバイスグループがリソースにアクセスできるようにするグラントを作成する場合は、viaフィールドを省略する(または[]nullに設定する)ことができます。

viaフィールドには、以下の制約があります。

エラー処理とトラブルシューティング

Tailscaleのポリシーエンジンはグラントをコンパイルし、Tailscaleクライアントに配布し、クライアントはこれをローカルにキャッシュします。
エラーは、ポリシーのコンパイル、配布、または適用の際に発生する可能性があります。

よくあるエラーには、無効なセレクター(存在しないグループ、タグ、IPセットの使用)、到達不能なホスト(存在しない宛先へのアクセス許可)、プロトコルの不一致(存在しない、または形式が誤ったプロトコル識別子の指定)、アプリケーションケイパビリティの不一致(対象のアプリケーションでサポートされていないケイパビリティの参照)などがあります。
可能な場合、ポリシーエンジンは問題を検出するとエラーメッセージを表示します。

トラブルシューティングについて詳しくは、グラントのトラブルシューティングを参照してください。