このドキュメントでは、VM Manager、Cloud Asset Inventory、BigQuery を使用して、組織内の Compute Engine インスタンスの脆弱性レポートを表示する方法について説明します。
Cloud Asset Inventory から BigQuery にデータをエクスポートすると、高度なクエリを実行して、組織全体の保留中のパッチと脆弱性情報を特定できます。
始める前に
- VM Manager を設定する。
- Cloud Asset Inventory API を有効にします。
- エクスポートされたデータを保存する BigQuery データセットを作成します。
- 脆弱性レポートを表示するために必要な権限があることを確認します。
-
まだ設定していない場合は、認証を設定します。認証では、 Google Cloud サービスと API にアクセスするための ID が確認されます。ローカル開発環境からコードまたはサンプルを実行するには、次のいずれかのオプションを選択して Compute Engine に対する認証を行います。
このページのサンプルをどのように使うかに応じて、タブを選択してください。
コンソール
Google Cloud コンソールを使用して Google Cloud サービスと API にアクセスする場合、認証を設定する必要はありません。
gcloud
-
Google Cloud CLI をインストールします。インストール後、次のコマンドを実行して Google Cloud CLI を初期化します。
gcloud init外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。
-
- デフォルトのリージョンとゾーンを設定します。
必要なロール
リソースデータを BigQuery にエクスポートするために必要な権限を取得するには、プロジェクト、フォルダ、または組織に対する次の IAM ロールを付与するよう管理者に依頼してください。
-
Cloud Asset 閲覧者 (
roles/cloudasset.viewer) -
BigQuery データ編集者(
roles/bigquery.dataEditor) -
BigQuery ジョブユーザー(
roles/bigquery.jobUser)
ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。
これらの事前定義ロールには、リソースデータを BigQuery にエクスポートするために必要な権限が含まれています。必要とされる正確な権限については、「必要な権限」セクションを開いてご確認ください。
必要な権限
リソースデータを BigQuery にエクスポートするには、次の権限が必要です。
-
cloudasset.assets.exportOSInventories -
cloudasset.assets.exportResource -
bigquery.datasets.get -
bigquery.tables.create -
bigquery.tables.update -
bigquery.tables.get -
bigquery.jobs.create
カスタムロールや他の事前定義ロールを使用して、これらの権限を取得することもできます。
VM Manager データを BigQuery にエクスポートする
OS インベントリとリソースデータを BigQuery にエクスポートするには、次の操作を行います。
組織 ID を確認します。
gcloud projects get-ancestors PROJECT_IDPROJECT_IDは、プロジェクトのプロジェクト ID に置き換えます。VM Manager によって収集された OS インベントリ データを VM インスタンスからエクスポートします。
gcloud asset export \ --content-type=os-inventory \ --organization=ORGANIZATION_ID \ --per-asset-type \ --bigquery-table="projects/BQ_PROJECT_ID/datasets/DATASET_ID/tables/os"次のように置き換えます。
ORGANIZATION_ID: 実際の組織 ID。BQ_PROJECT_ID: BigQuery データセットが配置されているプロジェクト ID。DATASET_ID: BigQuery データセットの名前。
リソース メタデータを BigQuery テーブルにエクスポートします。
gcloud asset export \ --content-type=resource \ --organization=ORGANIZATION_ID \ --per-asset-type \ --bigquery-table="projects/BQ_PROJECT_ID/datasets/DATASET_ID/tables/res"次のように置き換えます。
ORGANIZATION_ID: 組織 IDBQ_PROJECT_ID: BigQuery データセットが配置されているプロジェクト IDDATASET_ID: BigQuery データセットの ID
OS インベントリ スナップショットをエクスポートする方法については、アセット スナップショットをエクスポートするをご覧ください。
組織の脆弱性レポートを生成する
インベントリ データをエクスポートしたら、BigQuery で SQL クエリを実行して脆弱性レポートを生成できます。このレポートには、次の情報が表示されます。
- 組織全体の保留中のパッチの完全なリスト。
- Compute Engine インスタンスごとの保留中のパッチの概要。
- プロジェクトごとの保留中のパッチの概要。
レポートを生成する手順は次のとおりです。
Google Cloud コンソールで、[BigQuery] ページに移動します。
クエリエディタに次の SQL スクリプトを貼り付けます。
WITH UPDATES_GRANULAR_DATA AS ( SELECT project, instance, os, available_update, vuln.cve AS vuln_cve, vuln.severity AS linux_vuln_severity, windows_categories FROM ( SELECT SPLIT(inv.name, '/')[OFFSET(4)] AS project, SPLIT(inv.name, '/')[OFFSET(8)] AS instance, inv.os_inventory.os_Info.long_Name AS os, inv_item.key AS available_update, ( SELECT ARRAY_AGG(c.name) windows_cat_names FROM UNNEST(inv_item.value.available_Package.wua_Package.categories) c ) AS windows_categories FROM DATASET_ID.os_compute_googleapis_com_Instance AS inv CROSS JOIN UNNEST(inv.os_inventory.items) AS inv_item WHERE inv.name NOT LIKE '%/locations/%' AND inv_item.value.type = 2 --"AVAILABLE_PACKAGE" UNION ALL SELECT project, instance, os, NULL AS available_update, NULL AS windows_categories FROM ( SELECT SPLIT(name, '/')[OFFSET(4)] AS project, SPLIT(name, '/')[OFFSET(8)] AS instance, os_Inventory.os_Info.long_Name AS os, ( SELECT COUNT(*) FROM UNNEST(os_Inventory.items) WHERE value.type = 2 --"AVAILABLE_PACKAGE" ) AS count_available_updates FROM DATASET_ID.os_compute_googleapis_com_Instance WHERE name NOT LIKE '%/locations/%' ) WHERE count_available_updates = 0 ) LEFT JOIN ( SELECT inv_item, v.details.severity AS severity, v.details.cve AS cve FROM DATASET_ID.res_osconfig_googleapis_com_VulnerabilityReport CROSS JOIN UNNEST(resource.data.vulnerabilities) AS v CROSS JOIN UNNEST(v.availableInventoryItemIds) AS inv_item WHERE ARRAY_LENGTH(resource.data.vulnerabilities)>0 AND ARRAY_LENGTH(v.availableInventoryItemIds)>0 ) AS vuln ON vuln.inv_item = available_update ), REPORT_WITH_WINDOWS_CATEGORIES_VERBOSE AS ( SELECT project, instance, os, COUNTIF(available_update IS NOT NULL) as updates_pending, IF( COUNTIF(available_update IS NOT NULL)>0 AND ARRAY_LENGTH(ARRAY_CONCAT_AGG(windows_categories)) IS NULL, IF( ARRAY_LENGTH(ARRAY_AGG(DISTINCT(linux_vuln_severity) IGNORE NULLS)) > 0, IF( CONTAINS_SUBSTR(ARRAY_TO_STRING(ARRAY_AGG(DISTINCT(linux_vuln_severity) IGNORE NULLS),""), "CRITICAL"), "CRITICAL", IF( CONTAINS_SUBSTR(ARRAY_TO_STRING(ARRAY_AGG(DISTINCT(linux_vuln_severity) IGNORE NULLS),""), "HIGH"), "HIGH", IF( CONTAINS_SUBSTR(ARRAY_TO_STRING(ARRAY_AGG(DISTINCT(linux_vuln_severity) IGNORE NULLS),""), "MEDIUM"), "MEDIUM", IF( CONTAINS_SUBSTR(ARRAY_TO_STRING(ARRAY_AGG(DISTINCT(linux_vuln_severity) IGNORE NULLS),""), "LOW"), "LOW", "SEVERITY_UNSPECIFIED" ) ) ) ), "UNKNOWN" ), NULL ) as linux_vuln_severity, ARRAY_CONCAT_AGG(windows_categories) as windows_categories_agg FROM UPDATES_GRANULAR_DATA GROUP BY project, instance, os ORDER BY project, instance, os ), REPORT_BY_VM AS ( SELECT project, instance, os, updates_pending, linux_vuln_severity, IF( ARRAY_LENGTH(windows_categories_agg) > 0, IF( CONTAINS_SUBSTR(ARRAY_TO_STRING(ARRAY(SELECT DISTINCT(a) as n FROM UNNEST(windows_categories_agg) a ORDER BY n ASC),","), "Security Updates"), "SECURITY UPDATES", IF( CONTAINS_SUBSTR(ARRAY_TO_STRING(ARRAY(SELECT DISTINCT(a) as n FROM UNNEST(windows_categories_agg) a ORDER BY n ASC),","), "Update Rollups"), "UPDATE ROLLUPS", "OTHER UPDATES" ) ), NULL ) as windows_category FROM REPORT_WITH_WINDOWS_CATEGORIES_VERBOSE ), REPORT_BY_PROJECT AS ( SELECT project, COUNT(*) as total_vms, COUNTIF(updates_pending=0) as vms_up_to_date, COUNTIF(updates_pending>0) as vms_with_updates_pending, COUNTIF(linux_vuln_severity = "CRITICAL") as linux_vms_critical, COUNTIF(linux_vuln_severity = "HIGH") as linux_vms_high, COUNTIF(linux_vuln_severity = "MEDIUM") as linux_vms_medium, COUNTIF(linux_vuln_severity = "LOW") as linux_vms_low, COUNTIF(linux_vuln_severity = "SEVERITY_UNSPECIFIED") as linux_vms_severity_unspecified, COUNTIF(linux_vuln_severity = "UNKNOWN") as linux_vms_unknown, COUNTIF(windows_category = "SECURITY UPDATES") as win_vms_security_updates, COUNTIF(windows_category = "UPDATE ROLLUPS") as win_vms_update_rollups, COUNTIF(windows_category = "OTHER UPDATES") as win_vms_other_updates FROM REPORT_BY_VM GROUP BY project ) -- To view the report, uncomment one of the following SELECT statements: -- 1. List of every pending update package across all VMs with associated vulnerability severity: -- SELECT * FROM UPDATES_GRANULAR_DATA -- 2. List of VMs and pending updates count: -- SELECT * FROM REPORT_BY_VM -- 3. Summary of projects, showing count of VMs up-to-date and with pending updates: SELECT * FROM REPORT_BY_PROJECTDATASET_IDは、BigQuery データセットの ID に置き換えます。[実行] をクリックします。
データのクエリの詳細については、クエリの実行をご覧ください。
レポートを生成したら、データポータルを使用してカスタム ダッシュボードを作成できます。詳細については、データポータルでデータを分析するをご覧ください。
次のステップ
- VM Manager の OS インベントリの詳細を確認する。
- アセットのメタデータを BigQuery にエクスポートする方法を学習する。
- データポータルを使用して BigQuery データを可視化します。