Ver relatórios de vulnerabilidade da organização usando o Inventário de recursos do Cloud e o BigQuery

Neste documento, descrevemos como usar o VM Manager, o Inventário de recursos do Cloud e o BigQuery para visualizar relatórios de vulnerabilidade das instâncias do Compute Engine na sua organização.

Ao exportar dados do Inventário de recursos do Cloud para o BigQuery, é possível executar consultas avançadas para identificar patches pendentes e informações de vulnerabilidade em toda a organização.

Antes de começar

Funções exigidas

Para receber as permissões necessárias para exportar dados de recursos para o BigQuery, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto, na pasta ou na organização:

Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Esses papéis predefinidos contêm as permissões necessárias para exportar dados de recursos para o BigQuery. Para acessar as permissões exatas necessárias, expanda a seção Permissões necessárias:

Permissões necessárias

As seguintes permissões são necessárias para exportar dados de recursos para o BigQuery:

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

Essas permissões também podem ser concedidas com funções personalizadas ou outros papéis predefinidos.

Exportar dados do VM Manager para o BigQuery

Para exportar dados de inventário e recursos do SO para o BigQuery, faça o seguinte:

  1. Identifique o ID da sua organização:

    gcloud projects get-ancestors PROJECT_ID
    

    Substitua PROJECT_ID pelo ID do projeto de destino.

  2. Exporte os dados do inventário do SO coletados pelo VM Manager das instâncias 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"
    

    Substitua:

    • ORGANIZATION_ID: o ID da organização.
    • BQ_PROJECT_ID: o ID do projeto em que o conjunto de dados do BigQuery está localizado.
    • DATASET_ID: o nome do conjunto de dados do BigQuery.
  3. Exporte os metadados do recurso para uma tabela do BigQuery:

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

    Substitua:

    • ORGANIZATION_ID: o ID da organização
    • BQ_PROJECT_ID: o ID do projeto em que o conjunto de dados do BigQuery está localizado
    • DATASET_ID: o ID do conjunto de dados do BigQuery

Para saber como exportar snapshots do inventário do SO, consulte Exportar snapshot de recurso.

Gerar um relatório de vulnerabilidade para sua organização

Depois de exportar os dados do inventário, você pode executar uma consulta SQL no BigQuery para gerar um relatório de vulnerabilidade. Esse relatório fornece as seguintes informações:

  • Uma lista completa de patches pendentes em toda a organização.
  • Um resumo dos patches pendentes por instância do Compute Engine.
  • Um resumo dos patches pendentes por projeto.

Para gerar o relatório, siga estas etapas:

  1. No console do Google Cloud , acesse a página BigQuery.

    Acessar o BigQuery

  2. No editor de consultas, cole o seguinte script 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_PROJECT
    

    Substitua DATASET_ID pelo ID do seu conjunto de dados do BigQuery.

  3. Clique em Executar.

Para mais informações sobre como consultar dados, consulte Executar consultas.

Depois de gerar o relatório, use o Data Studio para criar um painel personalizado. Para mais informações, consulte Analisar dados com o Data Studio.

A seguir