戻る
2026/10/27
Tailworm への対応:本番環境を止めずに Tailscale ネットワークを強化した記録
Tailworm の指摘事項に照らして自社の Tailscale ネットワークを点検し、Tailscale SSH の露出を取り除き、本番ジョブをすべて稼働させたまま対応した記録です。
概要
2026年10月25日、あるセキュリティ研究者が「Tailworm」を公開しました。Tailscale と headscale に関する 11 件の指摘で、協調的な開示(coordinated disclosure)を経ずに公表されたものです。本稿執筆時点で、Tailscale は修正を公開していません。私たちは同日夜、自社の Tailscale ネットワークを各指摘に照らして点検しました。該当した 1 件の露出を取り除き、アクセスを絞り込み、その間も本番ジョブはすべて稼働し続けました。
本稿では、何を確認し、何を変更し、どのように障害を避けたか、そして何を学んだかを紹介します。なお、本稿はレポート内容を独自に検証したものではありません。
Tailworm の報告内容(概要)
11 件の指摘は、大きく次のグループに分けられます。
- Tailscale SSH(最も深刻)。許可された SSH セッションから、接続先マシンの root 権限へ昇格できるというものです。研究者の検証環境では、そこからマシン間に次々と広がりました。
- App connectors。接続先(destination)が検証されません。
- メモリ枯渇。コントロールサーバーとクライアントの両方で発生します。
- Serve と Funnel のエッジケース。
どの指摘も、攻撃者がすでに足がかりを持っていることが前提です。インターネットから直接攻撃できるものはありません。一部のセキュリティ専門家はリスクが誇張されていると指摘していますが、主な露出である Tailscale SSH は現実の問題であり、取り除くのも簡単です。
ステップ 1:変更する前に確認する
まず読み取り専用の確認から始め、何かに手を加える前に結果を記録しました。
- 使用中の Tailscale クライアントのバージョン
- 実際に有効になっている機能
- 60 日分の SSH セッションログ(誰がどこから接続したか、ポートやソケットのフォワーディングが使われたか)
- デバイス一覧(何か月も接続のないデバイスを含む)
確認結果:
- 環境の一部で Tailscale SSH が有効になっていたため、指摘 F1–F3 と F5 が私たちに関係していました。
- その他の指摘が前提とする機能は使っていなかったため、大半は該当しませんでした。
- SSH ログには、想定外の接続元もフォワーディング要求もありませんでした。
ステップ 2:障害を起こさずに露出を取り除く
素直に考えれば、Tailscale SSH を無効にし、代わりに標準的な OpenSSH の鍵認証を使えば済みます。ところが、事前確認で落とし穴が見つかりました。
Tailscale SSH は SSH 鍵ではなく、tailnet 上の ID で認証します。自動化スクリプトはコマンドラインで SSH 鍵を指定していましたが、その鍵はパスフレーズで保護されており、無人運転で使えるはずのないものでした。ジョブが動いていたのは、Tailscale SSH が鍵をまったく見ていなかったからにすぎません。単純に Tailscale SSH を無効にしていたら、自動ジョブはすべて止まっていたはずです。
そこで、次の順序で切り替えました。
- 自動化専用の鍵を作成しました。接続元を 1 台のマシンに限定し、フォワーディングを無効にしています。
- 切り替え前に新しい経路をテストしました。tailnet 内からのみ到達できる一時的な OpenSSH ポートを開き、ジョブの実行環境と同じ条件(SSH エージェントなし、端末なし)から、スクリプトが SSH を呼び出すすべての方法で接続しました。
- 否定テストを行いました。許可された接続元以外からは新しい鍵が拒否されること、フォワーディング要求が拒否されることを確認しました。
- 先に自動ロールバックを仕掛けました。Tailscale SSH を無効にする前に、自動的に再有効化するタイマーを設定しました。この復旧手段は SSH が動いていることに依存しません。
- 切り替え後、すべての自動ジョブを新しい接続で確認しました。各ジョブが実際に 1 回ずつ正常に完了しました。すでに開いていたセッションは証拠として数えていません。
- 一時的な設定を削除しました。追加したポート、ファイアウォールルール、ロールバック用タイマーを削除し、もう一度検証しました。
ステップ 3:残った部分を引き締める
- Tailscale SSH のポリシーを空にしました。既定のポリシーでは、ユーザーは自分のどのデバイスからも自分の他のデバイスへ、root を含めて SSH セッションを開くことができ、必要なのは週 1 回のブラウザでの再承認だけでした。ポリシーを空にしたことで、誤って Tailscale SSH を再び有効にしてもアクセスは許可されません。
- インターネットからの SSH を閉じました。閉じる前に、帯域外(out-of-band)のコンソールからログインできることを確認し、締め出されないようにしました。閉じた後、外部ネットワークから SSH が応答しないことを確認しました。
- デバイス承認を必須にしました。新しいデバイスは、管理者の承認がなければ参加できません。
- 登録キーを確認しました。失効させるべきものはありませんでした。
- 管理者アカウントで MFA が有効なことを確認しました。ネットワークレベルの制御は、管理者ログインを乗っ取った人なら誰でも元に戻せてしまいます。
- デバイス間の実際の通信の観測を始めました。次のステップである「どのデバイスがどのサービスと通信できるか」の絞り込みを、推測ではなく根拠に基づいて行うためです。
Tailnet Lock とデバイス承認は、どちらも不正なデバイスの参加を防ぎますが、併用はできません。意図をもってどちらかを選んでください。
ステップ 4:サーバーだけでなく運用手順書も直す
以前の復旧手順では、Tailscale SSH を有効にした状態でサーバーを再接続することになっていました。今回の変更後にその手順に従えば、リスクのある機能が気づかないうちに復活していたはずです。そこで手順書を書き直しました。
- まず原因を切り分けます。ネットワーク接続が切れているのか、SSH そのもの(鍵、設定、ファイアウォール)の問題なのか。両者は対処法が異なります。
- 設定を変えずに再接続します。余計なフラグは付けず、再接続前にノードの設定を保存し、再接続後に比較します。
- 緊急アクセスはタイマー付きでのみ開きます。事前に承認を得て、開く前に自動で閉じる予定を設定し、接続元を限定し、IPv4 と IPv6 の両方を確認します。
- 緊急時であっても Tailscale SSH は再有効化しません。そのために必要なアクセスポリシーの変更は、自動でロールバックできないからです。
学んだこと
- セキュリティ機能を外す前に、それが実際に何を認証しているかを把握すること。スクリプトが指定していた鍵は、一度も使われていませんでした。
- 移行先の経路そのものを、ジョブが実際に動く環境と同じ条件で、切り替え前にテストすること。
- 変更対象に依存しないロールバックを用意すること。「SSH で入り直して直せばいい」ではなく、タイマーです。
- 扉を閉じる前に、復旧用のアクセスを確認すること。私たちは、インターネットからの SSH を閉じる前にコンソールアクセスを確認しました。
- 運用手順書も同じ変更の中で更新すること。古い復旧手順が、数か月後にセキュリティ対策を元に戻してしまうことがあります。
- 既定のポリシーを読むこと。「自分のデバイスからの接続を root も含めて許可」が、私たちの出発点となる既定設定でした。
- 「変更がうまくいった」と「脆弱性が解消された」を区別すること。Tailscale SSH に関する指摘の影響はもう受けませんが、上流の修正が出るまで Tailworm 全体としては解決していません。修正が出たらクライアントを更新します。
- まず測ってから絞り込むこと。通信の観測結果と実際の依存関係の一覧を先にそろえてからアクセスルールを厳しくすれば、強化によって業務を止めずに済みます。
今後の予定
観測した通信に基づき、デバイス間のネットワークアクセスを各サービスに必要な最小限まで絞り込んでいます。Tailscale の修正が公開され次第、すぐに適用します。
参考:Tailworm のレポート(tailworm.com)、Tailscale のドキュメント「Tailnet Lock」
Global
Korea
China
Taiwan
Vietnam
Thailand
Indonesia
Portugal
Spain
France
Germany
Egypt
Russia