이 문서에서는 VM Manager, Cloud 애셋 인벤토리, BigQuery를 사용하여 조직의 Compute Engine 인스턴스에 대한 취약점 보고서를 확인하는 방법을 설명합니다.
Cloud 애셋 인벤토리의 데이터를 BigQuery로 내보내면 고급 쿼리를 실행하여 조직 전체에서 대기 중인 패치와 취약점 정보를 식별할 수 있습니다.
시작하기 전에
- VM Manager 설정
- Cloud 애셋 인벤토리 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 애셋 뷰어(
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
커스텀 역할이나 다른 사전 정의된 역할을 사용하여 이 권한을 부여받을 수도 있습니다.
BigQuery로 VM Manager 데이터 내보내기
OS 인벤토리 및 리소스 데이터를 BigQuery로 내보내려면 다음 단계를 따르세요.
조직 ID를 확인합니다.
gcloud projects get-ancestors PROJECT_IDPROJECT_ID를 해당 프로젝트의 프로젝트 ID로 바꿉니다.VM 인스턴스에서 VM Manager가 수집한 OS 인벤토리 데이터를 내보냅니다.
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: 조직 ID입니다.BQ_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 데이터 시각화