前提と範囲
この記事は、Tailscaleやheadscaleを運用している管理者向けに、Tailwormの研究報告への対応で必要になる設定の棚卸しと、作業後の完了チェックをまとめたものです。
内容は、2026-10-26 10:23 JST時点で公開情報をWeb上で再確認した結果に基づいています。筆者は報告された内容を自分で再現・検証していません。各項目の確認状況は、「研究報告」「ベンダーの認識」「修正コード」「製品への配信」に分けて記載しています。
Tailwormは、Erica Windisch氏によるTailscale/headscaleの研究報告で、11件の指摘を含みます(Tailworm)。研究で対象になったheadscaleは0.29.5です。
前提として、次の点を押さえておいてください。
- 11件すべてが確定した脆弱性ではなく、11件のCVEが付けられたわけでもありません。
- 外部の誰でもすべての端末に侵入できると実証された内容ではありません。
- 主なSSH関連の問題は、許可済みの接続か、侵害済みの端末が起点です。自分の端末だけで構成したtailnetでも、1台が侵害されれば起点になり得ます。
- ベンダーはUnix権限と転送に関する問題を認識し、調査中としています。全員へのSSH無効化は推奨していません。不要な転送を止めるよう求める案内は確認済みです(r/Tailscaleのスレッド)。
- Tailscale SaaSそのものが侵害されたという報告とは別物です。
- 実際の被害の有無は、今回の調査では確認していません。
OSや導入方法(パッケージ、コンテナ、systemd、launchdなど)がわからない状態で一律のコマンドを示すと誤った操作につながるため、この記事では変更コマンドを示しません。棚卸しの観点と判断の基準を示します。
用語
- 組み込みのTailscale SSH:tailscaledがSSH接続を受け付ける機能です。端末側でRunSSHが有効な場合に動作します。
- 通常のOpenSSH over Tailscale:sshd(OpenSSH)をTailscaleの経路越しに使う方法です。SSH関連の主な指摘は組み込みのTailscale SSHを対象にしています。
- 転送(forwarding):SSH接続を通して、別の通信を中継する機能です。
- Unix socket:同じマシンの中でプログラム同士がやり取りするための窓口です。
- LocalAPI:tailscaledの管理用socketです。
- DERP:端末同士が直接つながらないときに通信を中継するサーバーです。
- Tailnet Lock:新しい端末のnode keyに、信頼された鍵による署名があるかを検証する仕組みです。
- HTTP/2:1本の接続の中で、複数のやり取りを同時に進める通信方式です。
図1:SSH policyで接続を許可することと、接続後に端末上で行われる処理の権限は別の問題です。T3/T2系の指摘は、この2つのずれに関わります。この図は主にSSH関連の指摘を説明するもので、11項目すべてを同じように説明するものではありません。
棚卸しの観点
バージョン
- 各端末のTailscaleクライアントのバージョンを把握します。確認時点の安定版は1.104.2です(リリース一覧)。
- headscaleのバージョンを把握します。0.29.6を、すべての指摘が修正された根拠とすることはできません。
RunSSH
- 組み込みのTailscale SSHが有効になっている端末を洗い出します。
- 通常のOpenSSHだけを使っている端末とは分けて記録します。
SSH policy
- tailnetのポリシーのSSHに関する設定で、誰が、どの端末に、どのユーザーとして接続できるかを確認します。
- 広すぎる許可(全員から全端末へ、など)や、使われていない許可がないかを確認します。
- check modeを使っているかを記録します。ただし、check modeは権限の問題を根本から解決するものではありません。
転送
- 業務でSSHの転送が必要な端末と、不要な端末を分けます。
- 不要な端末では、tailscaledサービスの実行環境にTS_SSH_DISABLE_FORWARDING=1を設定し、サービスを再起動する必要があります。シェルでexportするだけでは効きません。具体的な設定場所はOSや導入方法ごとに公式の案内を確認してください。
- 転送の停止は一部の緩和策にすぎません。
Serve
- Serveの設定と転送先を一覧にします。転送先にLocalAPIや他の特権的なsocketが含まれていないかを確認します。
- 公開先ごとの権限設定と、権限情報のヘッダーを信頼するアプリがあるかを記録します。
- TS_SERVE_ALLOW_ALL_INTERFACESが設定されていないかを確認します。
Funnel
- Funnelを使っている端末と公開先を一覧にします。
- テスト用の設定や不要な公開が残っていないかを確認します。
headscale
- 登録窓口が公開されているか、リクエスト数の制限があるか、メモリの監視があるかを確認します。
DERP
- 使っているDERPサーバーが、公式のものか独自運用のものかを記録します。
- 信頼できない中継サーバーが設定に含まれていないかを確認します。
11項目と対応
1. T3:一般ユーザーの転送がroot権限で行われる
- 概要:一般ユーザーとしてログインしても、転送の処理がroot権限で行われ、Unix socketに接続できるおそれがあります。管理用サービスを操作される懸念があります。
- 成立条件:RunSSHが有効であること、SSH policyで接続が許可されている(または許可済みの端末が侵害されている)こと、転送が有効であることです。
- 確認状況:ラボでの研究報告、ベンダーの説明、修正案のいずれもが、問題がこの方向にあることを裏付けています。
- 対応:不要な転送を止め、SSH policyを必要最小限にします。
2. T2:逆向きの転送によるsocketのなりすまし
- 概要:逆方向のsocket転送で既存のsocketを置き換え、本来の窓口になりすますおそれがあります。
- 成立条件:組み込みのTailscale SSHへの接続が許可されていて、逆向きの転送が使えることです。
- 確認状況:研究報告と修正案の内容は一致しています。ただし、どの環境でもroot権限を取れると保証されたわけではありません。
- 対応:転送を制限します。鍵の漏洩が疑われる場合は調査します。
3. T2/T3 RACE:確認と利用の間の競合状態
- 概要:パスの安全を確認してから実際に使うまでの間に、対象を差し替えられる問題です。
- 成立条件:SSH接続が許可されていて、転送が使えること、対象パスを書き換えられること、そして差し替えのタイミングを合わせられることです。
- 確認状況:ラボでは、管理サービスの操作、鍵の窃取、Tailnet Lockを使っていない環境での不正な端末登録が報告されています。Tailnet Lockが有効な環境で、この保護を実際に無効にできるかは実証されていません。PR21942は確認時点でOPENです。
- 対応:不要な転送を止めます。侵害が疑われる場合は、端末を隔離し、鍵を失効させ、不審な登録端末がないかを確認します。
図2:1台が侵害され、その端末からのSSHがpolicyで許可されている場合に、他の端末へ影響が広がる条件を示しています。この図は主にSSH関連の指摘を説明するもので、11項目すべてを同じように説明するものではありません。
4. C1:実験的な機能conn25
- 概要:アプリ単位の許可を越えて、内部の宛先に接続できるおそれがあります。
- 成立条件:conn25を使っていること、そして一定の権限があることです。
- 確認状況:研究報告の段階です。宛先まで届くことと、侵入に成功することは別の話です。
- 対応:使っているかを棚卸しし、使う場合は送信先を制限します。
5. T1:大量の要求によるメモリの枯渇
- 概要:許可済みのSSH接続から大量の要求を送り、メモリを使い切らせてサービスを止める問題です。
- 成立条件:組み込みのTailscale SSHへの接続が許可されていることです。
- 確認状況:研究報告の段階です。
- 対応:SSH policyで利用者を制限し、メモリを監視します。転送を止めるだけでは解決しません。
6. C2/C4+C3:headscaleとDERPの資源枯渇
- 概要:headscaleの登録キャッシュやDERPの資源を枯渇させるという複数の指摘です。
- 成立条件:認証済みの内部の利用者、認証前の公開登録窓口、悪意のある中継サーバーの応答など、指摘ごとに起点が異なります。
- 確認状況:研究報告の段階です。登録できなくなることと、不正に登録されることは別の話です。
- 対応:登録窓口のリクエスト数を制限し、メモリを監視し、DERPの設定を見直します。
7. SERVE-F-1:LocalAPIへのServe転送
- 概要:ServeのTCP転送先をLocalAPIにすると、管理操作が外から使える状態になります。
- 成立条件:その設定が行われていて、相手からの到達が許可されていることです。
- 確認状況:ラボでの研究報告の段階です。
- 対応:管理用socketへの転送設定を削除します。
8. SERVE-F-2:設定後のsocket差し替え
- 概要:Serveを設定した後にsocketを差し替えて、検査をすり抜ける問題です。
- 成立条件:その端末で、該当する場所への書き込み権限が必要です。
- 確認状況:LocalAPIへの実際の操作は、Hostヘッダーの検査で403(拒否)になったと報告されています。他の特権的なsocketには懸念が残ります。完全に突破できたと実証されたわけではありません。
- 対応:socketと親ディレクトリの権限を制限します。
9. SERVE-F-3:Funnel許可判定のCLIとdaemonの不一致
- 概要:Funnelで公開してよいかの判定が、CLIとdaemonとで食い違う問題です。
- 成立条件:通常のheadscaleでは、必要なingress許可を発行できません。ラボでは特別なテスト設定で代用しています。
- 確認状況:本番環境で誰でも無断で公開できると実証されたわけではありません。
- 対応:不要な機能やテスト用の設定を除去し、アプリ側でも認証を設けます。
10. SERVE-F-4:TS_SERVE_ALLOW_ALL_INTERFACES
- 概要:標準ではないこの環境変数を設定すると、設定やネットワークの条件によって公開範囲がLANまで広がる可能性があります。
- 成立条件:この環境変数が設定されていることです。
- 確認状況:コード確認に基づく設定上の注意点です。実際のLANでの検証は行われていません。
- 対応:不要であれば除去します。必要な場合は、firewallとアプリ側の認証で保護します。
11. SERVE-F-5:HTTP/2での公開先間の権限情報の混線
- 概要:HTTP/2で1本の接続を並行して使うと、同じpeerに認められたaccepted app capabilitiesが、複数の公開先の間で混ざるおそれがあります。他人のユーザーIDになりすますという話ではありません。
- 成立条件:公開先が複数あること、公開先ごとに権限設定が異なること、権限情報のヘッダーを信頼するアプリがあることなどです。
- 確認状況:PR21931が統合済みで、問題の方向は強く裏付けられています。ただし、安定版1.104.2に修正が含まれて配信されているかは別に確認が必要です。
- 対応:アプリ独自の認証を使い、公開先を絞り、修正版の配信を確認します。
図3:研究報告、ベンダーの認識、修正コード(OPENか統合済みか)、製品への配信は、それぞれ別の段階です。この図は主にSSH関連の指摘を例にしたもので、11項目すべてを同じように説明するものではありません。
作業手順と完了チェック
図4:組み込みのTailscale SSHを使っているか、SSH policyの範囲は適切か、転送は必要か。まずこの3点を確認します。この図は主にSSH関連の対応を示すもので、11項目すべての対応を網羅するものではありません。
変更前
- 組み込みのTailscale SSHが使えなくなっても作業できる、別の管理経路(コンソール、帯域外管理、通常のOpenSSHなど)を確保した
- 上記の棚卸し結果(バージョン、RunSSH、SSH policy、転送、Serve、Funnel、headscale、DERP)を記録した
- 変更対象の端末と、その切り戻し方法を決めた
変更後
- 必要な利用者がSSH接続できることを確認した
- 不要な利用者や端末から接続できないことを確認した
- 転送を止めた端末で、転送が実際に拒否されることを確認した(設定がtailscaledサービスの実行環境に反映され、再起動されていること)
- tailscaledと、公開しているサービスが正常に動いていることを確認した
- Serve/Funnelの不要な設定、管理用socketへの転送、TS_SERVE_ALLOW_ALL_INTERFACESが残っていないことを確認した
- headscaleの登録窓口の制限とメモリ監視が有効であることを確認した
継続確認
- PR21942の状態と、PR21931の修正が安定版に含まれているかを追跡している
- 公式の修正版が出たら適用し、全端末のバージョンを確認した
- Tailscaleのセキュリティ情報ページを定期的に確認している
check modeやTailnet Lockは有効な補助策ですが、権限の問題を根本から解決するものではありません。未確認の情報を「デマ」とも「安全」とも扱わず、証拠の段階を追い続けてください。
出典
- Tailworm:https://www.tailworm.com/
- r/Tailscaleのスレッド:https://www.reddit.com/r/Tailscale/comments/1xeoj1l/recent_tailscale_vulnerability_reports/
- tailscale PR21931:https://github.com/tailscale/tailscale/pull/21931
- tailscale PR21942:https://github.com/tailscale/tailscale/pull/21942
- Tailscale Security Bulletins:https://tailscale.com/security-bulletins
- Tailscaleのリリース:https://github.com/tailscale/tailscale/releases
- headscale v0.29.6:https://github.com/juanfont/headscale/releases/tag/v0.29.6
この記事のもとになった整理(新しい事実の出典ではありません):https://x.com/akira_papa_IT/status/2114527592422559798



