2023年1月24日、サービストークンを管理するコードのリリースエラーにより、複数のCloudflareサービスが121分間利用できなくなりました。このインシデントにより、Workersプラットフォーム、Zero Trustソリューション、コンテンツ配信ネットワーク(CDN)のコントロールプレーン機能の面など、Cloudflareのさまざまな製品の評価が落ちました。
Cloudflareは、自動化されたサービスが他のサービスを認証できるようにするために、サービストークンの機能性を提供しています。例えば、お客様は、データセンターで実行されているアプリケーションとパブリッククラウドプロバイダーのリソース間の相互作用を保護するために、サービストークンを使用することができます。このリリースの一環として、トークンが最後に使用された時間を管理者に表示する機能を導入し、ユーザーが未使用のトークンを安全にクリーンアップできるようにすることを目的としていました。この変更により、サービストークンに関する他のメタデータが誤って上書きされ、影響を受けたアカウントのトークンがインシデントの期間中無効になりました。
今回のリリースが他のサービスに影響を与えた理由は、CloudflareがCloudflare上で実行していることに起因しています。サービストークンは、アカウントの認証機能に影響を与え、影響を受けたアカウントのうち2つは、複数のCloudflareサービスを強化します。これらのアカウントのサービストークンが上書きされると、これらのアカウント上で実行するサービスで、リクエストの失敗やその他の予期せぬエラーが発生するようになりました。
限られた一部のお客様やエンドユーザーがこのインシデントによる直接的な影響を受け、他のお客様はサービスの低下を経験した可能性がありますが、Cloudflareのネットワークやサービスへの全体的な影響は重大ではありませんでした。とはいえ、被害を被ったお客様への影響は、大変なことであったと思います。当社は、このようなことが起こった理由と再発防止対策をご理解いただくために、問題点を文書化しています。
サービストークンとは何ですか?
ユーザーがアプリケーションやIDプロバイダーのログイン時、通常は、ユーザー名とパスワードを入力します。パスワードは、ユーザーがユーザー名を管理していることを証明し、パスワードにより、そのサービスが続行できるようになります。ハードキーやデバイスポスチャーのような追加認証のレイヤーを追加することは可能ですが、ワークフローは、サービスに対して自分が何者であるかを人間が証明することで構成されています。
しかし、サービスに対して認証が必要なユーザーは人間だけではありません。アプリケーションは頻繁に他のアプリケーションと対話する必要があります。例えば、今度の旅行プランに関する情報をユーザーに表示するアプリケーションを作ったとします。
航空会社は、フライトとその期間に関する詳細を独自のシステムで保持しています。彼らは、個々の旅行の詳細をインターネット上で公開したくないですし、アプリケーションをプライベートネットワークに招待したくないのです。同様に、ホテルは、彼らが宿泊予約の詳細を有効かつ承認された第三者サービスに送信のみすることを確認したいのです。
アプリケーションは、これらの外部システムで認証するための信頼できる方法が必要です。 サービストークンは、お客様のサービスのユーザー名やパスワードの一種として機能することにより、この問題を解決します。ユーザ名やパスワードと同様に、サービストークンは、クライアントIDとクライアントシークレットの2つの部分があります。IDとシークレットの両方を認証リクエストとともに送信する必要があります。 また、トークンは、期間が割り当てられ、その後、無効となり、ローテーションする必要があります。アプリケーションにサービストークンを付与し、必要な上流システムがそれを検証すると、サービスは航空会社やホテルの情報を取得し、共同レポートでエンドユーザーにそれを提示できます。
管理者がCloudflareサービストークンを作成すると、クライアントIDとクライアントシークレットのペアが生成されます。お客様は、保護されたリソースに到達する必要がある場合、HTTPヘッダーとして両方の値を送信するようにリクエストサービスを構成することができます。リクエストサービスは、Workerの形式で、Cloudflareのネットワーク内、またはパブリッククラウドプロバイダーのような別の場所を含むあらゆる環境で実行できます。お客様は、対応する保護されたリソースをCloudflareのリバースプロキシの背後にデプロイする必要があります。当社のネットワークは、HTTPヘッダに設定されたサービスにバインドされたすべてのリクエストをチェックします。もし存在すれば、Cloudflareはその信頼性を検証し、リクエストをブロックするか、リクエストの続行を許可します。また、認証イベントを記録します。
インシデント・タイムライン
タイムスタンプは全て協定世界時(UTC)です。
2023年1月24日16:55にAccessのエンジニアリングチームがリリースを開始したところ、誤ってサービストークンのメタデータを上書きし始め、このインシデントが発生しました。
2023年1月24日17:05にAccessのエンジニアリングチームが無関係の問題に気付き、リリースをロールバックしました。このリリースで、サービストークンのメタデータのさらなる上書きを停止しました。
サービストークン自体が更新されるまで、サービストークンの値は、Cloudflareのネットワーク上で更新されません(詳細は以下を参照)。このため、メタデータが上書きされたサービストークンの影響にズレがありました。
2023年1月24日17:50: Cloudflare WARPの最初の無効なサービストークンが当社のグローバルネットワークに同期されました。WARPおよびZero Trustユーザーへの影響が出始めました。
WARPデバイスポスチャーのアップロードがゼロになり、内部アラートが発生しました
2023年1月24日18:12に、正常なWARPデバイスポスチャーのアップロードが大幅に減少したため、インシデントが宣言されました。
2023年1月24日18:19:Cloudflare APIの最初の無効なサービストークンが当社のグローバルネットワークに同期されました。**キャッシュパージ、Cache Reserve、イメージ、およびR2への影響が出始めました。**これらの製品のアラートがトリガーされ、より大きなインシデント範囲が特定されました。
2023年1月24日18:21に、初期調査中、上書きされたサービストークンが発見されました。
2023年1月24日18:28に、影響を受けたすべての製品を含めるようにインシデントを上げました。
2023年1月24日18:51に、Cloudflare WARPアカウントのサービストークンを元の値に戻すための最初のソリューションを特定・実装し、WARPとZero Trustに影響を与えました。WARPとZero Trustへの影響は終了しました。
2023年1月24日18:56に、Cloudflare APIアカウントに同じソリューションを実施し、キャッシュパージ、Cache Reserve、イメージ、R2に影響を与えました。キャッシュパージ、Cache Reserve、イメージ、R2への影響は終了しました。
2023年1月24日19:00に、Cloudflare APIアカウントに更新が行われ、Cloudflare APIアカウントを誤って上書きしました。**キャッシュパージ、Cache Reserve、イメージ、R2への影響が再び始まりました。**その後、インシデントの解決まで、すべての内部Cloudflareアカウントの変更がロックされました。
2023年1月24日19:07に Cloudflare APIが更新され、正しいサービストークンの値が含まれました。キャッシュパージ、Cache Reserve、イメージ、R2への影響は終了しました。
2023年1月24日19:51に、影響を受けるすべてのアカウントのサービストークンがデータベースのバックアップから復元されました。インシデントが終了しました。
何がリリースされ、どのように壊れたのですか?
Accessチームは、「最終確認日時」フィールドを追加したサービストークンに新しい変更をロールアウトしていました。これは、どのサービストークンがアクティブに使用されているかを特定するのに役立つ、よくある機能リクエストでした。
何が問題だったのでしょうか?
「最終確認日時」の値は、アカウントのログインイベントKafkaキュー内のすべての新規ログインイベントをスキャンすることで導き出されました。サービストークンを使用したログインイベントを検出した場合、対応するサービストークンの最終確認値の更新が開始されました。
サービストークンの「最終確認日時」の値を更新するために、対応するサービストークンの情報を収集するための読み取り書き込みトランザクションが実行されます。サービストークンの読み取りリクエストは、セキュリティ上の理由から、デフォルトで「クライアントシークレット」の値を作成します。そして、サービストークンへの「最終確認日時」の更新では、読み取り時の情報に「クライアントシークレット」が含まれていないことを利用して、書き込み時に空の「クライアントシークレット」でサービストークンを更新しました。
サービストークンの正しい値、誤った値の例を以下に示します。
Accessサービストークンの値の例
サービストークン「クライアントシークレット」データベースは、「not null」チェックがありましたが、この状況では、空のテキスト文字列をnull値としてトリガーしませんでした。
{
"1a4ddc9e-a1234-4acc-a623-7e775e579c87": {
"client_id": "6b12308372690a99277e970a3039343c.access",
"client_secret": "<hashed-value>", <-- what you would expect
"expires_at": 1698331351
},
"23ade6c6-a123-4747-818a-cd7c20c83d15": {
"client_id": "1ab44976dbbbdadc6d3e16453c096b00.access",
"client_secret": "", <--- this is the problem
"expires_at": 1670621577
}
}
このバグの結果、「最終確認日時」のリリースが終了する10分間にサービストークンを使用して認証したCloudflareアカウントは、その「クライアントシークレット」の値が空の文字列に設定されます。次に、空の「クライアントシークレット」を認証に使用するために、サービストークンを変更する必要がありました。この状態で、合計4つのアカウントがあり、すべてCloudflareの内部にあります。
どのようにその問題を解決したのですか?
一時的なソリューションとして、サービストークンを上書きしたアカウントに対し、正しいサービストークンの値を手動で復元できました。これにより、影響を受けたCloudflareサービス全体への影響を直ちに食い止めることができました。
その後、データベースチームは、影響を受けるすべてのアカウントのサービストークンを古いデータベースコピーから復元するためのソリューションを実行できました。これにより、この事件による影響はすべて終了しました。
なぜ、他のCloudflareサービスに影響を与えたのでしょうか?
サービストークンは、アカウントの認証機能に影響を与えます。影響を受けたアカウントのうち2つは、複数のCloudflareサービスを強化します。これらのアカウントのサービストークンが上書きされると、これらのアカウント上で実行するサービスで、リクエストの失敗やその他の予期せぬエラーを経験するようになりました。
Cloudflare WARP登録
Cloudflareは、どのユーザーもデバイスにインストールし、インターネットトラフィックのプライバシーを向上できる、モバイルおよびデスクトップのフォワードプロキシ、Cloudflare WARP(当社の「1.1.1」アプリ)を提供しています。このサービスは、Cloudflareのアカウントを必要とせず、誰でもインストールでき、当社は、アクティビティをユーザーにマッピングするログを保持しません。
ユーザーがWARPを使用して接続する際、Cloudflareはデバイスのキーを受信して検証するサービスに依存することで、デバイスの登録を検証します。次に、このサービスは、ネットワークへのアクセスを新しく登録されたデバイスに提供するよう、当社のネットワークに指示する別のシステムと通信します。
インシデントの間、登録サービスは、デバイスを検証するネットワーク内のシステムと通信できなくなりました。その結果として、ユーザーは新しいデバイスを登録したり、新しいデバイスにアプリをインストールしたりできなくなり、アプリの新しいバージョンへ更新するのに問題が発生した可能性があります(これにより、再登録もトリガーする)。
Cloudflare Zero Trustデバイスポスチャーと再認証ポリシー
Cloudflareは、デバイス上にエージェントが存在してもしなくても、お客様がデプロイできる包括的なZero Trustソリューションを提供しています。一部のユースケースは、デバイス上でCloudflareエージェントを使用する場合にのみ可能使用です。エージェントは同じCloudflare WARPソリューションのエンタープライズ版で、エージェントがデバイスの状態を送受信する必要があるたびに、同様の劣化を経験しました。このため、Cloudflare Zero Trustの3つのユースケースに影響を与えました。
まず、コンシューマー製品と同様に、新しいデバイスを登録することも、既存のデバイスを無効にすることもできませんでした。また、管理者は、登録されたデバイスの設定を変更することもできませんでした。いかなる場合でも、ユーザーにエラーが表示されます。
第二に、既存のプライベートネットワークをCloudflareのZero Trustソリューションに置き換える多くのお客様は、セッション期間ポリシーを使用してユーザーのIDを継続的に検証するルールを追加する場合があります。これらのルールの目的は、古いセッションが内部システムに継続的にアクセスすることを防ぐために、ユーザーに再認証を強制することです。デバイス上のエージェントは、Cloudflareのコントロールプレーンからの信号に基づいて、ユーザーに再認証を促します。インシデントの間、信号が送信されず、ユーザーは、再認証を正常に行うことができませんでした。
最後に、デバイスポスチャールールに依存しているお客様も影響を受けました。デバイスポスチャールールにより、AccessまたはGatewayポリシーを使用するお客様がWARPエージェントに依存し、デバイスが企業のコンプライアンスルールを満たしていることを継続的に強制できるようにします。
エージェントはこれらのシグナルをデバイスの状態を維持する責任を負うCloudflareサービスに伝達します。CloudflareのZero Trustアクセス制御製品は、サービストークンを使用して、このシグナルを受け取り、他のルールとともに評価して、ユーザーが所定のリソースにアクセスできるかどうか判断します。今回のインシデントの間、これらのルールがデフォルトでブロックアクションに設定されました。つまり、これらのポリシーによって変更されたトラフィックは、ユーザーには壊れたように見えるということです。場合によっては、それは、デバイスからすべてのインターネットバウンドトラフィックが完全にブロックされ、ユーザーが何もアクセスできなくなることを意味していました。
Cloudflare Gatewayは、Gatewayのポリシーを適用するために、5分ごとにユーザーのデバイスポスチャー状態をキャッシュします。デバイスポスチャーの状態はキャッシュされるため、ゲートウェイはリクエストごとにデバイスの状態を確認する必要がなく、ポリシーを適用できます。どのゲートウェイポリシーの種類が一致するかによって、ユーザーは2つの異なる結果を経験します。それらが、ネットワークポリシーに一致する場合、ユーザーは接続が切断され、HTTPポリシーの場合は、5XXエラーページが表示されます。ベースラインを超える5XXエラーは、5万件/分を超え、ピークに達し、インシデントが解決するまで、ポスチャー読み取りエラーは1050万件を超えました。
ゲートウェイ5XXエラー/分
ゲートウェイデバイスポスチャーエラーの総カウント数
Cloudflare R2ストレージとCache Reserve
Cloudflare R2ストレージにより、開発者は一般的なクラウドストレージサービスに関連する高価なエグレス帯域幅料金なしで、大量の非構造化データを保存することが可能になります。
このインシデントの間、R2サービスはCloudflareインフラストラクチャの他の部分へのアウトバウンドAPIリクエストを行うことができませんでした。その結果として、R2ユーザーがR2にリクエストする際に、リクエスト失敗率が上がったことに気付きました。
また、Cloudflareの多くの製品もデータストレージに関して、R2に依存しており、こちらも影響を受けていました。例えば、Cache Reserveのユーザーは、この期間に影響を受け、プライマリキャッシュにないアイテムのオリジン負荷の増加を確認しました。このインシデントの間、Cache Reserveサービスへの読み込みと書き込み操作の大部分が影響を受け、Cache ReserveへのエントリとCache Reserveからのエントリ書き込みに失敗しました。しかし、Cache ReserveがR2エラーを検出すると、顧客オリジンにフォールバックするため、この期間中もまだ、ユーザートラフィックをサービスしていました。
Cloudflareキャッシュパージ
Cloudflareのコンテンツ配信ネットワーク(CDN)は、世界中の当社のデータセンター内のネットワーク上のインターネットプロパティのコンテンツをキャッシュし、ユーザーのリクエストが応答するために必要な移動距離を短縮します。場合によっては、当社がキャッシュしたものをパージし、別のデータに置き換えたいというお客様もいらっしゃいます。
Cloudflareのコントロールプレーン(管理者がネットワークでやり取りする場所)では、サービストークンを使用して認証を行い、キャッシュパージサービスにアクセスします。このインシデントの間、サービストークンが無効な状態で多くのパージ・リクエストが失敗しました。平均して20回/秒のパージリクエストが失敗し、最大で70回/秒のパージリクエストが失敗する影響を確認しました。
再発防止に向け、何を取り組んでいるのでしょうか?
私たちはこのようなインシデントを真摯に受け止め、それが与えた影響を認識しています。 今後、同様の問題が発生するリスクに対処するために、当社が講じることのできるいくつかの対応策を特定しました。このインシデントの結果として、以下の改善プランを実施しています:
**デスト:**Accessのエンジニアリングチームは、新機能を開始する前に、サービストークンの上書きに関する同様の問題を自動的に検出するユニットテストを追加する予定です。
アラート: Accessチームは、失敗したサービストークン認証リクエストが大幅に増加した場合、自動アラートを実装し、問題が本格化する前に検出します。
**プロセス:**Accessチームは、特定のデータベーステーブルのロールバックの高速化を可能にするプロセス改善を特定しました。
**実装:**関連するすべてのデータベースフィールドは、更新され、既存の「not null チェック」に加えて、空の文字列のチェックを含めます。
このたびは、多くのCloudflareサービスにわたり、お客様に混乱を招き、誠に申し訳ございませんでした。今後、このような問題が再発しないように、安定性を向上させ、こういった改善を積極的に行っています。