Afficher les rapports sur les failles pour l'organisation à l'aide de l'inventaire des éléments cloud et de BigQuery

Ce document explique comment utiliser VM Manager, l'inventaire des éléments cloud et BigQuery pour afficher les rapports de failles des instances Compute Engine de votre organisation.

En exportant des données de inventaire des éléments cloud vers BigQuery, vous pouvez exécuter des requêtes avancées pour identifier les correctifs en attente et les informations sur les failles dans l'ensemble de votre organisation.

Avant de commencer

Rôles requis

Pour obtenir les autorisations nécessaires à l'exportation des données de ressources vers BigQuery, demandez à votre administrateur de vous accorder les rôles IAM suivants sur le projet, le dossier ou l'organisation :

Pour en savoir plus sur l'attribution de rôles, consultez Gérer l'accès aux projets, aux dossiers et aux organisations.

Ces rôles prédéfinis contiennent les autorisations requises pour exporter des données de ressources vers BigQuery. Pour connaître les autorisations exactes requises, développez la section Autorisations requises :

Autorisations requises

Les autorisations suivantes sont requises pour exporter des données de ressources vers BigQuery :

  • cloudasset.assets.exportOSInventories
  • cloudasset.assets.exportResource
  • bigquery.datasets.get
  • bigquery.tables.create
  • bigquery.tables.update
  • bigquery.tables.get
  • bigquery.jobs.create

Vous pouvez également obtenir ces autorisations avec des rôles personnalisés ou d'autres rôles prédéfinis.

Exporter des données VM Manager vers BigQuery

Pour exporter des données d'inventaire du système d'exploitation et de ressources vers BigQuery, procédez comme suit :

  1. Identifiez l'ID de votre organisation :

    gcloud projects get-ancestors PROJECT_ID
    

    Remplacez PROJECT_ID par l'ID de votre projet.

  2. Exportez les données d'inventaire du système d'exploitation collectées par VM Manager à partir des instances de 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"
    

    Remplacez les éléments suivants :

    • ORGANIZATION_ID : votre ID d'organisation.
    • BQ_PROJECT_ID : l'ID du projet dans lequel se trouve votre ensemble de données BigQuery.
    • DATASET_ID : le nom de votre ensemble de données BigQuery.
  3. Exportez les métadonnées des ressources vers une table BigQuery :

    gcloud asset export \
        --content-type=resource \
        --organization=ORGANIZATION_ID \
        --per-asset-type \
        --bigquery-table="projects/BQ_PROJECT_ID/datasets/DATASET_ID/tables/res"
    

    Remplacez les éléments suivants :

    • ORGANIZATION_ID : l'ID de votre organisation
    • BQ_PROJECT_ID : l'ID du projet dans lequel se trouve votre ensemble de données BigQuery
    • DATASET_ID : l'ID de votre ensemble de données BigQuery

Pour savoir comment exporter des instantanés d'inventaire du système d'exploitation, consultez Exporter un instantané d'élément.

Générer un rapport de failles pour votre organisation

Une fois les données d'inventaire exportées, vous pouvez exécuter une requête SQL dans BigQuery pour générer un rapport de failles. Ce rapport fournit les informations suivantes :

  • Liste complète des correctifs en attente dans l'organisation.
  • Récapitulatif des correctifs en attente par instance Compute Engine.
  • Récapitulatif des correctifs en attente par projet.

Pour générer le rapport, procédez comme suit :

  1. Dans la Google Cloud console, accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, collez le script SQL suivant :

    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_PROJECT
    

    Remplacez DATASET_ID par l'ID de votre ensemble de données BigQuery.

  3. Cliquez sur Exécuter.

Pour en savoir plus sur l'interrogation des données, consultez Exécuter des requêtes.

Une fois le rapport généré, vous pouvez utiliser Data Studio pour créer un tableau de bord personnalisé. Pour en savoir plus, consultez Analyser des données avec Data Studio.

Étape suivante