Security Command Center検出結果のPub/Subエクスポートをフィルタリングする
こんにちは。フクヤマです。
Google Cloudプレミアパートナーである株式会社G-gen様との技術ブログ相互寄稿企画、第2弾をお届けします。第1弾の「VPC Service Controls」に関する記事(リンクはこちら)も、大変ご好評をいただきました。
今回G-gen 杉村様から寄稿いただいたテーマは、「Security Command Center検出結果のPub/Subエクスポートをフィルタリングする」方法です。
Security Command Centerは強力な脆弱性検知ツールですが、その膨大な検出結果の中から、本当に対応が必要なアラートをいかに効率的に見つけ出すかが運用の鍵となります。本記事では、Pub/Subへ通知する際に、特定の条件に合う検出結果のみを抽出する「フィルタリング」の具体的なクエリ作成方法を、サンプルを交えて分かりやすく解説されています。SIEMなどの外部ツールとの連携を考えている方には特に必見の内容です。
それでは、日々のセキュリティ運用を一段レベルアップさせる実践的なテクニックをご覧ください。
G-gen の杉村です。Security Command Center の検出結果は、Pub/Sub に通知することができます。このとき、特定の条件に合致する検出結果のみを通知対象とするようにフィルタリングできます。当記事では、フィルタの書き方やいくつかのサンプルを紹介します。
1. Security Command Center と Pub/Sub 通知
Security Command Center は、Google Cloud に備わるセキュリティプラットフォームです。脆弱性の自動検出や、異常検知、AI アプリケーションの保護など、様々な機能を備えます。検知された脆弱性や異常な挙動は、検出結果としてリストアップされます。
Security Command Center の検出結果は、Google Cloud のメッセージキューサービスである Pub/Sub トピックに通知することができます。これにより、Pub/Sub 経由で Google SecOps や Sumo Logic、Splunk といったツールに検出結果を送出できます。
この機能を継続的エクスポート(continuous exports)と呼びます。継続的エクスポートを有効化すると、新しい検出結果や、更新された検出結果が、ほぼリアルタイムに Pub/Sub へエクスポートされます。
- 参考 : Security Command Center データをエクスポートする - 継続的エクスポート
- 参考 : Security Command Centerを徹底解説。Google Cloud(GCP)の脆弱性を自動検知 - G-gen Tech Blog - Pub/Sub エクスポート
2. 検出結果のフィルタリング
2-1. フィルタリングとクエリ
Pub/Sub への継続的エクスポートでは、設定を有効化する際、宛先の Pub/Sub トピック等を指定するほか、検出結果クエリ(findings query)を指定して、エクスポートの対象とする検出結果をフィルタリングすることができます。
例えば、以下のようなフィルタリングが可能です。
- ミュートされていない、かつアクティブな検出結果のみエクスポートする
- 特定のプロジェクトの検出結果のみをエクスポートする
- 特定のフォルダ配下のプロジェクトの検出結果のみをエクスポートする
ここで指定する検出結果クエリは、Security Command Center のコンソール画面や API で検出結果をクエリする際のフィルタと同じ、独自の文法が用いられます。
2-2. クエリの書き方
基本的な文法は、以下のドキュメントに記載されています。
- 参考 : コンソールで検出結果をクエリする
文法を覚えて細かくクエリを作らなくても、Google Cloud コンソールの「検出結果」ページでは、グラフィカルな UI に基づいてクエリを生成することが可能です。検出結果一覧表の左側のフィルタをチェックボックスのオン・オフで作成すると、それに対応するクエリが、画面上部のテキストボックスに自動生成されます。

ミュートされていない、かつアクティブな検出結果のみ
以下のクエリは、「ミュートされていない、かつアクティブな検出結果のみ」を意味します。
state="ACTIVE"
AND NOT mute="MUTED"
特定プロジェクトの検出結果のみ
以下のクエリは、「ミュートされていない、かつアクティブな検出結果のみ」に加えて、ある特定のプロジェクト群で検知された検出結果のみを対象としています。
state="ACTIVE"
AND NOT mute="MUTED"
AND (resource.gcp_metadata.project_display_name="my_project_01" OR resource.gcp_metadata.project_display_name="my_project_02")
なおここでフィルタの対象としている属性である resource.gcp_metadata.project_display_name は、要素名から一見、プロジェクト名のように思えますが、実際にはプロジェクト ID が格納される属性です。検出結果クエリでは、Security Command Center の検出結果(finding)リソースの属性をフィルタ対象としています。サンプルが欲しい場合、Google Cloud コンソールで検出結果の詳細画面を開き、JSON タブを選択すると、検出結果がどのような属性を持っているか確認できます。

検出元のプロジェクトを表す属性としては、resource.gcp_metadata.project がありますが、//cloudresourcemanager.googleapis.com/projects/${プロジェクト番号} の形式です。プロジェクト ID で指定したい場合は、resource.gcp_metadata.project_display_name を使います。
特定フォルダの配下のプロジェクトの検出結果のみ
以下のクエリは、「ミュートされていない、かつアクティブな検出結果のみ」に加えて、ある特定のフォルダの配下に存在するプロジェクト群で検知された検出結果のみを対象としています。
state="ACTIVE"
AND NOT mute="MUTED"
AND contains(resource.resource_path.nodes, id="folders/123456789012")
上記のクエリでは「123456789012 という ID を持つフォルダの配下」という条件を、contains() 関数で抽出しています。contains() 関数は、配列型属性のいずれかの要素に、特定のキー・バリューが登場するかどうかを検索することができます。
上記では、resource.resource_path.nodes 配列要素を検索対象としています。この配列要素は、以下のような形式です。
{
"finding": {
~略~
"resourcePath": {
"nodes": [
{
"nodeType": "GCP_PROJECT",
"id": "projects/098765432109",
"displayName": "my-project-01"
},
{
"nodeType": "GCP_FOLDER",
"id": "folders/012345678901",
"displayName": "my-child-folder"
},
{
"nodeType": "GCP_FOLDER",
"id": "folders/123456789012",
"displayName": "my-parent-folder"
},
{
"nodeType": "GCP_ORGANIZATION",
"id": "organizations/123123123123"
}
]
},
~略~
}
}
G-gen 杉村様、実践的な解説をありがとうございました。
セキュリティ運用において、膨大なアラートの中から本当に重要な情報を見つけ出す「ノイズのフィルタリング」は「万が一」のインシデントを確実に捕捉するために不可欠な技術です。今回ご紹介いただいた具体的なクエリは、すぐにでも業務に活かせるものばかりで、効率的なセキュリティ運用体制の構築に繋がる大きなヒントをいただきました。
さて、次回はいよいよ最終回、「検出結果を一時的にミュートする方法」についてです。ぜひご覧ください。
Discussion