Tailscale — VPN と SSH の接合部 制御面(鍵・身元・方針) データ面(実トラフィック)

Reachability as Authorization

通れたこと自体が、認証の完了を意味する。

従来の VPN は「入れること」と「使ってよいこと」を別の仕組みで管理してきた。トンネルに入った後は、各サーバが改めて「お前は誰だ」と訊く。Tailscale はこの二つを同じ暗号鍵の上に載せ直した。だから SSH の段階で訊くべきことが残っていない。以下はその接合部を、下の層から順に開いていく。

01 — 送信 ノード秘密鍵で封をする WireGuard の静的鍵ペア。公開鍵がそのまま、そのデバイスの身元。
02 — 受信 復号できた=送信者が確定 対応する秘密鍵の保持者以外、このパケットは作れない。追加の身元確認は原理的に不要。
03 — 選別 ACL 由来のフィルタを通す 誰と誰が話してよいかは、事前に配布された方針が両端でローカルに判定する。
04 — 到着 SSH は認証方式 none 受け取った側は既に「誰か」を知っている。よって証明を要求しない。
制御面 / データ面

分離の設計思想

まず、二つの面が分かれている

Tailscale の構造を一言で言うと、制御面(コントロールプレーン)とデータ面(データプレーン)の分離です。この区別を掴んでおくと、後の話が全部きれいに片付きます。

制御面はハブ&スポーク型で、中央のコーディネーションサーバが各デバイスの公開鍵とポリシーだけを配ります。実トラフィックはここを通りません。データ面はメッシュ型で、可能な限りデバイス同士が直接 WireGuard トンネルを張ります。

つまり中央サーバは「名簿と入館規則を配る事務局」であって、「全員が通る一本の廊下」ではない。ここが従来の VPN 集線装置との決定的な違いです。秘密鍵は各デバイスから外に出ないので、事務局は通信内容を読めません。

なぜこの分離が効くのか

従来型 VPN では、認可の判断と通信の中継が同じ箱に同居していました。だから箱が落ちれば全部止まり、箱を抜ければ内側は素通しになる。分離すると、方針の決定は中央で一元化しつつ、方針の執行は各ノードに分散できます。

データ面

WireGuard
Noise_IK

WireGuard:公開鍵がアドレスであり、身元である

WireGuard は Noise プロトコルフレームワークの Noise_IK パターンを使います。各ピアは Curve25519 の静的鍵ペアを持ち、相手の公開鍵を事前に知っていることが接続の前提です。ハンドシェイクの時点で相互認証が完了しており、「まず繋いでから認証する」という段階が存在しません。

クリプトキー・ルーティング

WireGuard の中核概念がこれです。各ピアの公開鍵に、そのピアが名乗ってよい IP アドレス範囲が紐づけられている。ある送信元 IP を持つパケットは、その IP に対応する鍵で暗号化されたセッションから届いた場合にしか受理されません。ルーティングテーブルと認可テーブルが同一物になっている、と言い換えられます。

副作用として、WireGuard は正しい鍵を持たない相手に一切応答しません。ポートスキャンに対して沈黙する。「開いているポートを見つけてから総当たり」という攻撃の入口自体が消えます。

  • static keypairデバイスの恒久的な身元。公開鍵=識別子。
  • Noise_IK handshake1-RTT(開始メッセージと応答メッセージの一往復)で鍵交換と相互認証を同時に完了。前方秘匿性あり。
  • cryptokey routing「この鍵はこの IP を名乗ってよい」という束縛。詐称が構造的に不可能。
  • rekeyセッション鍵は約2分ごとに更新。ただし身元となる静的鍵は変わらない。
制御面

Tailscale が
足したもの

素の WireGuard に、Tailscale が足したもの

素の WireGuard は「鍵の配布」と「相手の居場所の発見」を人間に丸投げします。ピアが10台あれば手作業で設定ファイルを書き、IP が変わるたびに直す。Tailscale が引き受けたのは主にこの運用部分です。

  • coordination server各ノードの公開鍵を集め、通信を許された相手にだけ配る。クライアントとの通信自体も Noise で保護される。
  • machine key / node key制御サーバとの対話用の鍵と、WireGuard の身元となる鍵を分離。node key には有効期限があり、失効させれば即座に締め出せる。
  • network map「今この tailnet に誰がいて、どの経路で届くか」の一覧。変化があれば差分が配られる。
  • ACL → packet filter中央で書いたポリシーがパケットフィルタにコンパイルされ、全ノードに配布される。判定は各ノードがローカルで行う。
  • NAT traversalSTUN 的な経路探索と UDP ホールパンチングで、NAT 越しの直接接続を試みる。
  • DERP直接繋がらない場合の中継。中継サーバは端点間の暗号を解けないので、経路が変わっても機密性は落ちない。
  • SSO / IdP 連携「この公開鍵はどの人間のものか」を外部の ID プロバイダに接続する。鍵とアイデンティティの橋渡し。

重要なのは最後の一行です。WireGuard 単体では公開鍵はただの数字で、それが誰のものかは人間の記憶の中にしかない。Tailscale は制御面を通じて、鍵と組織上のアイデンティティを恒常的に結びつけました。ここが SSH の話に直結します。

制御面 / データ面

核心

「通れること自体が認証」の正体

ここが核心部分です。これは比喩ではなく、三つの事実が重なった結果として文字通りそうなっています。

重なっている三層

① 暗号的事実:パケットが復号できたなら、送信者は対応する秘密鍵の保持者である。Noise_IK により中間者は成立しない。ここまでは WireGuard の性質。

② 身元の紐付け:その公開鍵が tailnet 上のどのユーザ/どのデバイスかは、制御面が保証している。SSO を経由しているので、組織の人事的な実体まで辿れる。

③ 認可の事前執行:ACL から生成されたフィルタが、そもそも「話しかけられる相手」を絞っている。送信側と受信側の両方で判定される。

従来モデルとの差は「順序」です。旧来の VPN は到達可能にしてから認可を問う。Tailscale は認可された相手としか到達可能にならない。だから到達可能性と認可が同一の事象になり、パケットが着いた時点で認証プロセスは既に終わっている。

従来型 VPNTailscale
境界ネットワーク境界(入ったら内側はフラット)デバイス単位(各接続が個別に認可)
認可の位置接続後、各サービスが個別に判断接続の成立条件そのもの
身元の単位アカウント/IP アドレス公開鍵+SSO アイデンティティ
失効アカウント停止(既存セッションは残りがち)node key 失効で経路ごと消える
横移動内側に入れば広く到達可能ACL で許した経路以外は存在しない
プロトコル構造

RFC 4251–4254

SSH は三層でできている

ここで SSH 側を開きます。SSH は単一のプロトコルではなく、三つの層の積み重ねです。この分解ができると、Tailscale SSH がどこを置き換えているのかが一発で見えます。

そのまま RFC 4254 接続層 シェル、コマンド実行、ポート転送、エージェント転送。一本のセッション上でチャネルを多重化する。ここは何も変わらない。
迂回される RFC 4252 ユーザ認証層 本来 publickey / password / keyboard-interactive のいずれかで「お前は誰だ」を解決する層。Tailscale SSH ではここが認証方式 none で通過する。
└→ 身元は下の層で既に確定している
一部が代替 RFC 4253 トランスポート層 鍵交換、暗号化、そしてホスト鍵によるサーバ認証。暗号化は生きているが、「このホスト鍵は本物か」の判断は制御面が保証するため、初回接続時のフィンガープリント目視確認という儀式が要らなくなる。
土台 WireGuard / Noise_IK ノード鍵による相互認証 SSH が始まる前に、双方の身元はここで確定済み。上の層が繰り返す必要のある問いが残っていない。

「SSH の暗号がなくなる」のではありません。SSH の暗号化セッションは通常どおり張られます(結果として WireGuard と二重になる)。変わったのは認証・認可の真実の在処であって、プロトコルの層構造そのものは保たれています。

制御面

Tailscale SSH
の実装

Tailscale SSH:誰が 22 番に応答しているか

tailscale up --ssh を有効にすると、tailnet インターフェース上の 22 番ポートに応答するのが sshd ではなく tailscaled になります。同じポート番号、別のデーモン、別の認証経路。物理 NIC 側の sshd はそのまま従来どおり動きます。

tailscaled は接続元のノード鍵から相手の tailnet アイデンティティを既に知っているので、SSH の認証フェーズを引き取り、追加の証明を求めません。代わりに参照するのが、ポリシーファイルの ssh セクションです。

// tailnet policy (HuJSON)
{
  "ssh": [
    {
      // 通常のオペレーション用
      "action": "accept",
      "src":    ["autogroup:member"],
      "dst":    ["tag:infra"],
      "users":  ["autogroup:nonroot", "ubuntu"]
    },
    {
      // root は SSO 再認証を要求する
      "action":      "check",
      "checkPeriod": "12h",
      "src":         ["autogroup:member"],
      "dst":         ["tag:infra"],
      "users":       ["root"]
    }
  ]
}
  • src / dst接続元と接続先。ユーザ、グループ、タグで指定する。ホスト名ではなくタグで書くのが運用上の定石。
  • userstailnet アイデンティティを、接続先ローカルの Unix ユーザへ写像する。ここが ID 体系の接合点。
  • action: check接続前に IdP での再認証を要求する。checkPeriod の間は有効。root 昇格など高リスク経路に効く。
  • recorderセッションを記録するノードのタグ。キーストロークと出力を丸ごと残せる。監査・事故調査向け。
  • port 22暗黙で固定。変更できない。
既定は拒否

ssh セクションに明示的なルールがなければ、誰も SSH できません。「書き忘れたら開いてしまう」ではなく「書かなければ閉じている」側に倒れています。

用語整理

最も
混同される点

紛らわしい二つを分ける

議論が噛み合わなくなる原因の大半がここです。名前が似ていますが、まったく別の話です。

SSH over TailscaleTailscale SSH
意味tailnet の IP に向けて普通に ssh する--ssh で有効化する機能
22番の応答従来どおり sshdtailscaled
ユーザ認証従来どおり SSH 公開鍵tailnet アイデンティティ(鍵不要)
authorized_keys維持が必要不要
得られるもの経路の秘匿と到達性経路+鍵管理の廃止+中央集権的な認可

前者でも「インターネットに 22 番を晒さない」という主要な利益は既に得られます。後者はそこから一歩進んで、鍵の配布と失効という運用問題そのものを消す提案です。段階的に移行できるので、まず前者だけで運用してから後者を検討する、という順序は合理的です。

前提の点検

何を
信頼しているか

この設計が何を信頼しているか

「通れること=認証」が成立するということは、裏返せば信頼の重心がデバイスと制御面に移ったということです。以下は誇張なく認識しておくべき前提です。

  • 制御サーバへの信頼 公開鍵の配布元が汚染されれば、偽ノードを tailnet に紛れ込ませられる余地が理屈上あります。これに対する緩和策が tailnet lock で、既存の信頼済みノードの署名がなければ新規ノードを受け入れない構成にできます。自前でホストする選択肢(Headscale 等)もありますが、運用責任は自分に来ます。
  • デバイスが単一障害点になる SSH 鍵とパスフレーズの二要素が消えた分、ノート PC を物理的に奪われた場合の被害範囲が広い。だから check mode(SSO 再認証)とデバイス側のディスク暗号化・画面ロックが、以前より重要になります。
  • 制御面の停止と既存接続 コーディネーションサーバが落ちても、既に確立している接続と配布済みのポリシーは動き続けます。止まるのは新規ピアの発見とポリシー更新です。とはいえ「調整役が落ちても暫くは走れる」という性質に依存しすぎないこと。
  • Unix 側の権限管理は消えない Tailscale が解決するのは「誰がログインしてよいか」まで。ログイン後の sudo 権限やファイル所有は依然 OS 側の問題です。users の写像設計を雑にすると、中央 ACL が厳密でもサーバ内で意味がなくなります。
  • 監査の粒度は上がる これは利点側。従来は「どの鍵でログインしたか」までしか残らず、鍵と人間の対応は台帳頼みでした。アイデンティティ基盤に接続されたことで「誰が、いつ、どのマシンに、どの Unix ユーザとして」が構造的に記録されます。
まとめると

Tailscale がやったのは、暗号プリミティブの発明ではありません。既に鍵で相互認証しているのだから、その上でもう一度認証をやり直す理由がないという、層の重複の除去です。SSH 鍵という30年物の運用負債が消えたのは、その除去の副産物として出てきた。

逆に言えば、この設計の説得力は「下の層の認証が本当に信頼できるか」に全面的に乗っています。WireGuard の暗号的健全性と、制御面の運営主体への信頼。検討すべき論点は結局この二点に収束します。

関連する教材