צפייה בדוחות פגיעויות בארגון באמצעות Cloud Asset Inventory ו-BigQuery

במאמר הזה מוסבר איך להשתמש ב-VM Manager, במאגר משאבי ענן וב-BigQuery כדי לראות דוחות פגיעות במכונות של Compute Engine בארגון.

ייצוא נתונים ממאגר משאבי ענן ל-BigQuery מאפשר להריץ שאילתות מתקדמות כדי לזהות תיקוני אבטחה בהמתנה ומידע על פגיעויות בכל הארגון.

לפני שמתחילים

  • הגדרת VM Manager
  • מפעילים את Cloud Asset Inventory API.
  • יוצרים מערך נתונים ב-BigQuery לאחסון הנתונים המיוצאים.
  • מוודאים שיש לכם את ההרשאות הנדרשות כדי לראות את דוחות הפגיעות.
  • אם עדיין לא עשיתם את זה, תצטרכו להגדיר אימות. אימות הוא תהליך שבו מאמתים את הזהות שלכם כדי לקבל גישה לממשקי API ולשירותים של Google Cloud . כדי להריץ קוד או דוגמאות מסביבת פיתוח מקומית, אפשר לבצע אימות ל-Compute Engine באחת מהדרכים הבאות:

    צריך לבחור את הכרטיסייה הרלוונטית לאופן שבו תכננתם להשתמש בדוגמאות בדף הזה:

    המסוף

    כשמשתמשים במסוף Google Cloud כדי לגשת לשירותים ולממשקי ה-API, לא צריך להגדיר אימות. Google Cloud

    gcloud

    1. התקינו את ה-CLI של Google Cloud. אחר כך, אתחלו את ה-CLI של Google Cloud באמצעות הפקודה הבאה:

      gcloud init

      אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  • הגדרת אזור ותחום כברירת מחדל

התפקידים הנדרשים

כדי לקבל את ההרשאות שדרושות לייצוא נתוני משאבים ל-BigQuery, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים ברמת הפרויקט, התיקייה או הארגון:

להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.

התפקידים המוגדרים מראש האלה כוללים את ההרשאות שנדרשות לייצוא נתוני משאבים ל-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

כדי לייצא נתוני מלאי ומשאבים של מערכת הפעלה ל-BigQuery:

  1. מזהים את מזהה הארגון:

    gcloud projects get-ancestors PROJECT_ID
    

    מחליפים את PROJECT_ID במזהה הפרויקט.

  2. ייצוא של נתוני מלאי מערכת ההפעלה שנאספו על ידי VM Manager מהמכונות הווירטואליות:

    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: מזהה הארגון.
    • BQ_PROJECT_ID: מזהה הפרויקט שבו נמצא מערך הנתונים ב-BigQuery.
    • DATASET_ID: השם של מערך הנתונים ב-BigQuery.
  3. מייצאים את המטא-נתונים של המשאב לטבלה ב-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: מזהה הארגון
    • BQ_PROJECT_ID: מזהה הפרויקט שבו נמצא מערך הנתונים שלכם ב-BigQuery
    • DATASET_ID: המזהה של מערך הנתונים ב-BigQuery

כאן מוסבר איך לייצא תמונות מצב של מלאי מערכות הפעלה.

יצירת דוח על נקודות חולשה בארגון

אחרי שמייצאים את נתוני המלאי, אפשר להריץ שאילתת SQL ב-BigQuery כדי ליצור דוח פגיעויות. בדוח הזה מופיעים הפרטים הבאים:

  • רשימה מלאה של תיקוני אבטחה בהמתנה בכל הארגון.
  • סיכום של תיקוני אבטחה בהמתנה לכל מכונה של Compute Engine.
  • סיכום של תיקוני באגים בהמתנה לכל פרויקט.

כדי ליצור את הדוח, פועלים לפי השלבים הבאים:

  1. במסוף Google Cloud , עוברים לדף BigQuery.

    כניסה ל-BigQuery

  2. בעורך השאילתות, מדביקים את סקריפט ה-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
    

    מחליפים את DATASET_ID במזהה של מערך הנתונים ב-BigQuery.

  3. לוחצים על Run.

מידע נוסף על שליחת שאילתות לנתונים זמין במאמר הרצת שאילתות.

אחרי שיוצרים את הדוח, אפשר להשתמש ב-Data Studio כדי ליצור מרכז בקרה בהתאמה אישית. מידע נוסף זמין במאמר בנושא ניתוח נתונים באמצעות Data Studio.

המאמרים הבאים