Tailnet Lock
最終検証日:
翻訳: 竹洞 陽一郎
Tailnet Lockは、PersonalプランおよびEnterpriseプランで利用できます。
Tailnet Lockは、tailnetに参加しようとするノードに対して、既にtailnet内にある信頼されたノードによる署名を必須にする機能です。
これにより、仮にTailscaleのインフラストラクチャが侵害されたとしても、署名なしにデータをやり取りすることはできません。
Tailnet Lockとは
通常、ノードの公開鍵の配布はTailscaleのコーディネーションサーバーが担います。
Tailnet Lockでは、信頼されたノードが他のノードに署名し、検証します。そのため、公開鍵の配布についてコーディネーションサーバーに依存しなくなります。
これは、Tailscaleのコントロールプレーンが攻撃経路になり得るという懸念に対応するものです。
Tailnet Lockは、TOFU(Trust on First Use、初回使用時の信頼)モデルを採用しています。
利用者は最初にTailscaleのコントロールプレーンを信頼し、その後、信頼の基点を自社のネットワーク内へ移します。
Headscaleのような自前のコントロールプレーンを運用する選択肢もありますが、SaaSが持つ可用性の保証や運用負荷の軽減という利点を失います。
Tailnet Lockは、SaaSの利点を保ったまま、信頼の基点を内側へ移せる点が特徴です。
仕組み
Tailnet Lockを使わない場合、コーディネーションサーバーがノードの公開鍵をピアへ配布します。
仮にTailscaleが悪意を持って動作した場合、ノードを注入して平文の通信を傍受できてしまいます。
Tailnet Lockを使うと、新しいノードのキーにはTailnet Lockキーによる署名が必要になり、ピアは接続を許可する前に署名を検証します。
- ノードキー(node key)
- Tailscaleクライアントが生成する公開鍵・秘密鍵のペアです。秘密鍵はノード内に留まり、公開鍵がコーディネーションサーバーへ送られます。特定のアイデンティティに紐付きます。
- Tailnet Lockキー(TLK)
- Tailnet Lockの有効・無効に関わらず、すべてのノードで生成される公開鍵・秘密鍵のペアです。秘密鍵は生成したノードに保管され、信頼された公開TLKはtailnetキーオーソリティ(TKA)に保管されます。
主な構成要素は次の2つです。
- 署名ノード: 新しいノードをtailnetへ署名して迎え入れる権限を持つノードです。
- tailnetキーオーソリティ(TKA): tailnet内で信頼されたTLKを保持する仕組みです。ノードをピア一覧に追加する前にノードキーの署名を検証し、信頼するTLKの変更に対する署名も検証します。暗号学的な連鎖として実装されており、際限なく成長し得ます。
無効化シークレット
無効化シークレット(disablement secret)は、Tailnet Lockを有効にする際に生成される長いパスワードです。
Tailnet Lockを無効にするには、このシークレットが必要です。認可の確認がなければ、侵害されたコーディネーションサーバーが保護を容易に解除できてしまうためです。
- 無効化シークレットが表示されるのは、初期化時の一度だけです。
- パスワードマネージャーや物理的な金庫など、安全な場所に保管してください。
- 実装上の問題が生じた場合や、シークレットを紛失した場合に備えて、Tailscaleのサポートへ渡す無効化シークレットを生成しておくこともできます。
無効化シークレットを紛失し、かつTailscaleのサポートへも渡していない場合、そのtailnetは復旧できません。
tailnetキーオーソリティ
tailnetキーオーソリティは、ノードキーへの署名に使える、信頼されたTailnet Lockキーを追跡・更新するサブシステムです。
有効化の際に、最初に信頼するロックキーを指定します。キーは後から追加・削除できます。
コーディネーションサーバーは、信頼されたキーの集合をtailnet全体へ配布します。
Tailnet Lockを有効にする
- Owner、Admin、またはIT adminのロールが必要です。
- ロックの対象とするすべてのノードで、Tailscale v1.46.1以降を実行している必要があります。
- Tailnet Lockは既定では有効になっていません。
- 有効化には
tailscale lock initコマンドを使います。管理コンソールから、実行すべきコマンドを生成できます。
- 管理コンソールのDevice managementページを開きます。管理コンソールと署名ノードのクライアントが、同じtailnetにログインしていることを確認してください。
- 「Enable Tailnet Lock」を選択します。
- 「Add signing nodes」のセクションで「Add signing node」を選択します。
- TLKを信頼する署名ノードを、2台以上選択します。
- 必要に応じて、「Send disablement secret to Tailscale support」を有効にします。追加の無効化シークレットが作成され、Tailscaleのサポートへ自動的に送信されます。
- 「Run command from signing node」のセクションで、
tailscale lock initコマンドをコピーします。 - 選択した署名ノードのターミナルで、そのコマンドを実行します。
コマンドを実行すると、10個の無効化シークレットが表示されます。
無効化に必要なのは1個ですが、10個すべてが生成されます。
表示されるのは初期化時のみです。安全に保管してください。
初期化が完了すると、次の状態になります。
- 既存のすべてのノードが、信頼されたTLKで署名されます。
- 信頼するTLKの集合が、既存のノードへ配布されます。
- 各ノードは、接続前にピアのノードキーの署名を検証します。
- 以降、新しいノードキーはすべて、既存のTLKによる署名が必要になります。
各ノードでtailscale lock statusを実行し、Tailnet Lockの状態が正しく反映されていること、初期状態が侵害されていないことを確認してください。
すべてのノードが、指定した署名ノードのTLKと一致する同じ署名キーを報告するはずです。
Tailnet Lockを無効にする
この操作には、Owner、Admin、またはIT adminのロールが必要です。
- 管理コンソールのDevice managementページを開きます。
- 「Disable Tailnet Lock」を選択します。
- 保管しておいた無効化シークレットを入力します。
- 「Disable Tailnet Lock」を選択します。
使用した無効化シークレットは、Tailscaleのコーディネーションサーバーがtailnet内のすべてのノードへ配布するため、公開されたものとして扱ってください。
Tailnet Lockを再度有効にすると、新しい無効化シークレットが生成されます。
無効化シークレットを紛失した、または使用できない場合の緊急措置として、各ノードでtailscale lock local-disableを実行し、そのノードでTailnet Lockを無視させる方法があります。
ロックされたtailnetにノードを追加する
署名を行う前に、管理コンソールのMachinesページから対象ノードの情報を取得します。
クライアントアプリで署名する
この方法に対応しているのは、macOS、Windows、iOSです(Androidは対応作業中です)。
- 管理コンソールのMachinesページを開きます。
- 署名が必要なノードを選択します。「Locked out」のバッジ、または
property:locked-outでの絞り込みで見つけられます。 - 「Sign machine」を選択します。
- デスクトップ(macOS・Windows)では、署名ノード上で操作している場合は「Sign this node」を選択します。そうでない場合は「Copy signing URL」でURLをコピーし、署名ノードへ渡します。
- モバイル(iOS)では、署名ノードでQRコードを読み取るか、署名URLをコピーして署名ノードで開きます(QRコードは現時点でiOSのみ対応です)。
CLIで署名する
この方法に対応しているのは、Linux、macOS、Windowsです。
- 対象のノードで
tailscale lock statusを実行します。 - 出力に表示される
tailscale lock signコマンドをコピーします。 - 信頼されたTLKを持つノードで、次の形式のコマンドを実行します。
tailscale lock sign nodekey:<node-key> tlpub:<tailnet-lock-key>
tlpub:の指定は、キーのローテーションを行う場合を除いて省略できます。
実行例です。
tailscale lock sign nodekey:1abddef1 tlpub:abcdef12
署名済みのノードキーが期限切れになっても、改めて署名し直す必要はありません。
ユーザーが再認証すると、そのノードのTLKによって署名が自動的にローテーションされます。
事前署名した認証キーでノードを追加する
事前署名した認証キーを使うと、個別の署名手順なしに、ロックされたtailnetへデバイスを追加できます。
- 事前承認済みの認証キーを生成します。
- 信頼されたTLKを持つノードで、環境変数にキーを設定します。
export AUTH_KEY="tskey-auth-<XXXXCTRL-NNNNNN>"
- 認証キーに署名します。
tailscale lock sign $AUTH_KEY
tailscale lock signが出力した新しいキーを使って、デバイスを事前承認します。
ノードのTailnet Lock公開鍵を確認する
Tailnet Lockの公開鍵はtlpub:abcdef12の形式で、ノードのTailscale公開鍵(nodekey:abcdef12)とは異なります。
CLI(Linux・macOS・Windows)の場合:
tailscale lock status
管理コンソールの場合:
- Machinesページを開きます。
- 対象のノードを選択します。
- Machine Detailsのセクションで「Tailnet Lock key」を確認します。表示されない場合、Tailnet Lockは有効になっていません。
- 「Copy」でクリップボードにコピーします。
クライアントアプリ(macOS・iOS)の場合:
- Tailscaleクライアントのメニューから「Settings」を選択します。
- 「Settings」タブを開きます。
- Tailnet Lockのセクションで「Manage」を選択します。
- 開いたダイアログのTailnet Lock Keyのセクションに公開鍵が表示されるので、「Copy」を選択します。
署名ノードを追加する
- 追加したいノードのTLK公開鍵を確認します。
- 信頼されたTLKを持つノードで、次のコマンドを実行します。キーは空白区切りで複数指定できます。
tailscale lock add tlpub:trusted-key1 tlpub:trusted-key2
署名ノードを削除する
この操作は、信頼されたTLKを持つノードから実行する必要があります。
tailscale lock remove tlpub:trusted-key7 tlpub:trusted-key8
ノードAでtailscale lock removeを実行して署名ノードBを削除すると、既定では、Bが署名していたすべてのノードがAのキーで自動的に署名し直されます。
この動作は--re-sign=falseフラグで無効にできます。
侵害された署名ノードのキーを取り消す
侵害されたキーにはtailscale lock revoke-keysを使います。侵害されていないキーの削除にはtailscale lock removeを使います。
取り消されたキーは、以降Tailnet Lockに使用できません。そのキーで署名されていたノードは認可を失い、新たな署名が必要になります。
- 侵害されていない署名ノードで、次のコマンドを実行します。出力には、次に実行すべき
--cosign付きのコマンドが含まれます。
tailscale lock revoke-keys tlpub:compromised-key1 tlpub:compromised-key2
- 他の信頼された署名ノードで、出力された
--cosignのコマンドを実行します。実行するたびに、新しい--cosignコマンドが出力されます。--cosignの実行回数が、取り消すキーの数を上回るまで繰り返します(3個のキーを取り消す場合は4回)。 - 最後に、出力された
--cosignを--finishに置き換えて実行します。
tailscale lock revoke-keys --finish <hex-data>
既定では、TailscaleがTailnet Lockのログのフォーク地点を判断します。
署名ノードの過半数がキーを取り消せると合意した場合、tailnetは取り消されたキーではなく、信頼できるキーを含むフォークを採用します。
署名ノードの過半数が侵害された場合は、Tailnet Lockを一度無効にしてから、改めて有効にしてください。
他のTailscale機能との関係
共有
ロックされたtailnetへ共有されたノードは、署名されるまで利用できません。
共有の招待を受け入れる側の利用者も、共有されたノードへアクセスする前に、自身のノードがロックされたtailnetで署名されている必要があります。
Tailscale SSH Console
署名済みのノードに対しては、tailnetポリシーファイルでネットワークアクセスが許可され、かつTailscale SSHのルールでSSHアクセスが許可されていれば、SSH Consoleを使ってセッションを開始できます。
構成監査ログ
Tailnet Lockの有効化、無効化、設定変更は、構成監査ログにイベントとして記録されます。
また、ノード上でtailscale lock logを実行すると、tailnetにおける最近のTailnet Lockの変更を確認できます。
Tailnet Lockの状態の保存先
- macOS、Windows、iOS、Android、tvOSでは、状態ディレクトリが自動的に設定されます。
tailscaledデーモンでは、--statedirまたは--stateフラグで指定します。- 公式のdeb・rpm・tar.gzパッケージをsystemdで利用する場合、
--stateフラグは自動的に設定されます。 - DockerやKubernetesでは、
TS_STATE_DIR環境変数で指定します。
状態ディレクトリが指定されていない場合、TailscaleはTailnet Lockのデータをメモリ上に保持するため、起動のたびにコントロールプレーンから状態を取得し直す必要があります。
この起動時の依存関係をなくすため、状態ディレクトリを設定することを強く推奨します。
制限事項
- 無効化シークレットは利用者自身で安全に保管する必要があります。紛失し、Tailscaleのサポートへも渡していない場合、tailnetは復旧できません。
- 署名ノードは、1つのtailnetにつき最大20台です。
- TLKのローテーションは、年に1回までです(TKAが際限なく肥大化するのを防ぐためです)。
- Tailnet Lockとデバイス承認は同時に有効にできません。
- TLKはデバイス上に保管されるため、デバイスが侵害されるとキーも露出します。
- Androidは署名ノードにできません(対応作業中です)。