Qualys-Asset-Kontextprotokolle erfassen

Unterstützt in:

In diesem Dokument wird beschrieben, wie Sie Qualys-Asset-Kontext-Logs mit Google Cloud Storage in Google Security Operations aufnehmen.

Der Qualys-Asset-Kontext enthält Host-Asset-Inventardaten (IP-Adressen, DNS-Namen, Betriebssystem, Cloud-Anbietermetadaten und Tags) von der Qualys-Plattform. Da diese Daten aus der Qualys API abgerufen werden, fragt eine Cloud Run-Funktion regelmäßig die Qualys Host List API ab, konvertiert die XML-Antwort in JSON und schreibt sie in einen Cloud Storage-Bucket, in den Google SecOps sie aufnimmt.

Hinweis

Prüfen Sie, ob folgende Voraussetzungen erfüllt sind:

  • Eine Google SecOps-Instanz
  • Ein Google Cloud-Projekt mit aktivierten Cloud Storage-, Cloud Run-, Pub/Sub- und Cloud Scheduler-APIs
  • Berechtigungen zum Erstellen und Verwalten von Cloud Storage-Buckets, Dienstkonten, Cloud Run Functions, Pub/Sub-Themen und Cloud Scheduler-Jobs
  • Ein Qualys-Konto mit API-Zugriff (ein Nutzer mit der Rolle Manager oder einer Rolle mit API-Zugriff und Sichtbarkeit der Assets, die Sie erfassen möchten)

Cloud Storage-Bucket erstellen

  1. Öffnen Sie die Google Cloud Console.
  2. Wählen Sie Ihr Projekt aus oder erstellen Sie ein neues.
  3. Rufen Sie Cloud Storage > Buckets auf.
  4. Klicken Sie auf Bucket erstellen.
  5. Geben Sie die folgenden Konfigurationsdetails an:
    • Bucket benennen: Geben Sie einen global eindeutigen Namen ein, z. B. qualys-asset-context-logs.
    • Standorttyp: Wählen Sie je nach Bedarf „Region“, „Zwei Regionen“ oder „Mehrere Regionen“ aus.
    • Standort: Wählen Sie den Standort aus, z. B. us-central1.
    • Speicherklasse: Wählen Sie Standard aus.
    • Zugriffssteuerung: Wählen Sie Einheitlich aus.
  6. Klicken Sie auf Erstellen.

Qualys API-Anmeldedaten erfassen

  1. Melden Sie sich in der Qualys-Webanwendung an.
  2. API-Nutzer identifizieren oder erstellen:
    • Rufen Sie Nutzer > Nutzerverwaltung auf.
    • Verwenden Sie einen vorhandenen Nutzer oder klicken Sie auf Neu > Nutzer und weisen Sie die Rolle Administrator (oder eine Rolle mit API-Zugriff) zu.
  3. Notieren Sie sich den Nutzernamen und das Passwort des Nutzers.
  4. Ermitteln Sie die URL Ihres Qualys-API-Servers. Sie ist spezifisch für Ihre Qualys-Plattform, z. B. https://qualysapi.qg3.apps.qualys.com. Weitere Informationen finden Sie unter Qualys-Plattform ermitteln.

Dienstkonto für die Cloud Run-Funktion erstellen

  1. Rufen Sie IAM & Verwaltung > Dienstkonten auf.
  2. Klicken Sie auf Dienstkonto erstellen.
  3. Geben Sie die folgenden Konfigurationsdetails an:
    • Name des Dienstkontos: Geben Sie qualys-asset-context-sa ein.
    • Beschreibung des Dienstkontos: Geben Sie Service account for Cloud Run function to collect Qualys asset context logs ein.
  4. Klicken Sie auf Erstellen und fortfahren.
  5. Weisen Sie die folgenden Rollen zu:
    • Storage-Objekt-Administrator: Hostdatensätze in den Bucket schreiben.
    • Cloud Run Invoker: Ermöglicht Pub/Sub, die Funktion aufzurufen.
  6. Klicken Sie auf Weiter und dann auf Fertig.

Dienstkonto Zugriff auf den Cloud Storage-Bucket gewähren

  1. Rufen Sie Cloud Storage > Buckets auf.
  2. Klicken Sie auf den Namen Ihres Buckets.
  3. Wechseln Sie zum Tab Berechtigungen.
  4. Klicken Sie auf Zugriff erlauben.
  5. Geben Sie die folgenden Konfigurationsdetails an:
    • Hauptkonten hinzufügen: Geben Sie die E‑Mail-Adresse des Dienstkontos (qualys-asset-context-sa@<PROJECT_ID>.iam.gserviceaccount.com) ein.
    • Rollen zuweisen: Wählen Sie Storage Object Admin aus.
  6. Klicken Sie auf Speichern.

Pub/Sub-Thema erstellen

  1. Rufen Sie Pub/Sub > Themen auf.
  2. Klicken Sie auf Thema erstellen.
  3. Geben Sie im Feld Themen-ID den Wert qualys-asset-context-trigger ein.
  4. Klicken Sie auf Erstellen.

Cloud Run-Funktion zum Erfassen von Logs erstellen

Die Cloud Run-Funktion wird durch Pub/Sub-Nachrichten von Cloud Scheduler ausgelöst. Sie ruft die Qualys FO Host List API auf, konvertiert die XML-Antwort in JSON und schreibt die Hostdatensätze in den Bucket.

  1. Rufen Sie Cloud Run auf.
  2. Klicken Sie auf Dienst erstellen.
  3. Wählen Sie Funktion aus, um den Inline-Code-Editor zu verwenden.
  4. Geben Sie die folgenden Konfigurationsdetails an:
    • Servicename: Geben Sie qualys-asset-context-collector ein.
    • Region: Wählen Sie die Region aus, die Ihrem Bucket entspricht (z. B. us-central1).
    • Laufzeit: Wählen Sie Python 3.12 oder höher aus.
  5. Im Abschnitt Trigger:
    1. Klicken Sie auf Trigger hinzufügen.
    2. Wählen Sie Cloud Pub/Sub aus.
    3. Wählen Sie unter Cloud Pub/Sub-Thema auswählen die Option qualys-asset-context-trigger aus.
    4. Klicken Sie auf Speichern.
  6. Wählen Sie im Bereich Authentifizierung die Option Authentifizierung erforderlich aus.
  7. Maximieren Sie Container, Netzwerk, Sicherheit und legen Sie auf dem Tab Sicherheit für Dienstkonto den Wert qualys-asset-context-sa fest.
  8. Fügen Sie auf dem Tab Container > Variablen und Secrets die folgenden Umgebungsvariablen hinzu:

    Variablenname Beispielwert
    GCS_BUCKET qualys-asset-context-logs
    GCS_PREFIX qualys-asset-context/
    QUALYS_BASE_URL https://qualysapi.qg3.apps.qualys.com
    QUALYS_USERNAME your-qualys-username
    QUALYS_PASSWORD your-qualys-password
    TRUNCATION_LIMIT 1000
    HTTP_TIMEOUT 300
    MAX_PAGES 50
  9. Legen Sie Request timeout (Zeitüberschreitung für Anfragen) auf 600 Sekunden und Memory (Arbeitsspeicher) auf 512 MiB oder höher fest.

  10. Klicken Sie auf Erstellen. Nachdem der Dienst erstellt wurde, wird der Inline-Code-Editor geöffnet.

Funktionscode hinzufügen

  1. Geben Sie im Feld Funktionseinstiegspunkt den Wert main ein.
  2. Ersetzen Sie im Inline-Code-Editor den Inhalt von main.py durch den folgenden Code:

    import functions_framework
    from google.cloud import storage
    import os
    import time
    import uuid
    import json
    import base64
    import requests
    import xmltodict
    
    storage_client = storage.Client()
    
    GCS_BUCKET = os.environ.get('GCS_BUCKET')
    GCS_PREFIX = os.environ.get('GCS_PREFIX', 'qualys-asset-context/')
    QUALYS_BASE_URL = os.environ.get('QUALYS_BASE_URL')
    QUALYS_USERNAME = os.environ.get('QUALYS_USERNAME')
    QUALYS_PASSWORD = os.environ.get('QUALYS_PASSWORD')
    TRUNCATION_LIMIT = int(os.environ.get('TRUNCATION_LIMIT', '1000'))
    HTTP_TIMEOUT = int(os.environ.get('HTTP_TIMEOUT', '300'))
    MAX_PAGES = int(os.environ.get('MAX_PAGES', '50'))
    
    def _headers():
        """Qualys FO API requires Basic auth and the X-Requested-With header."""
        token = base64.b64encode(f'{QUALYS_USERNAME}:{QUALYS_PASSWORD}'.encode()).decode()
        return {'Authorization': f'Basic {token}', 'X-Requested-With': 'Cloud Run function'}
    
    def _extract_hosts(xml_text):
        """Parse the FO Host List XML into (list_of_host_dicts, next_page_url)."""
        doc = xmltodict.parse(xml_text)
        response = (doc.get('HOST_LIST_OUTPUT') or {}).get('RESPONSE') or {}
        host_list = (response.get('HOST_LIST') or {}).get('HOST')
        if host_list is None:
            hosts = []
        elif isinstance(host_list, list):
            hosts = host_list
        else:
            hosts = [host_list]
        # When the result is truncated, RESPONSE contains <WARNING><URL>...</URL></WARNING>.
        warning = response.get('WARNING')
        next_url = warning.get('URL') if isinstance(warning, dict) else None
        return hosts, next_url
    
    def _write_hosts(bucket, hosts, page_num):
        """Write one batch of hosts to GCS as JSON, one host per line."""
        ts_path = time.strftime('%Y/%m/%d', time.gmtime())
        uniq = f'{int(time.time() * 1e6)}_{uuid.uuid4().hex[:8]}'
        key = f'{GCS_PREFIX}{ts_path}/qualys_asset_context_p{page_num:03d}_{uniq}.json'
        lines = [json.dumps(host, separators=(',', ':')) for host in hosts]
        bucket.blob(key).upload_from_string('\n'.join(lines), content_type='application/x-ndjson')
        return key
    
    @functions_framework.cloud_event
    def main(cloud_event):
        """Triggered by Pub/Sub to pull the Qualys host asset inventory and write it to GCS."""
        if not all([GCS_BUCKET, QUALYS_BASE_URL, QUALYS_USERNAME, QUALYS_PASSWORD]):
            print('Error: missing required environment variables')
            return
    
        bucket = storage_client.bucket(GCS_BUCKET)
        session = requests.Session()
        session.headers.update(_headers())
    
        url = f"{QUALYS_BASE_URL.rstrip('/')}/api/2.0/fo/asset/host/"
        params = {
            'action': 'list',
            'details': 'All',
            'truncation_limit': TRUNCATION_LIMIT,
            # show_cloud_tags, host_metadata, and show_tags add the cloud provider
            # tags, cloud instance metadata, and asset tags that the parser maps.
            'show_cloud_tags': 1,
            'host_metadata': 'all',
            'show_tags': 1,
        }
    
        pages = 0
        total = 0
        try:
            while pages < MAX_PAGES:
                resp = session.get(url, params=params, timeout=HTTP_TIMEOUT)
                resp.raise_for_status()
                hosts, next_url = _extract_hosts(resp.text)
                if hosts:
                    _write_hosts(bucket, hosts, pages + 1)
                    total += len(hosts)
                pages += 1
                if not next_url:
                    break
                # The pagination URL already includes every query parameter.
                url, params = next_url, None
    
            print(f'Wrote {total} hosts across {pages} pages')
        except Exception as e:
            print(f'Error collecting Qualys asset context: {e}')
            raise
    
  3. Erstellen Sie eine requirements.txt-Datei mit folgendem Inhalt:

    functions-framework==3.*
    google-cloud-storage==2.*
    requests>=2.31.0
    xmltodict>=0.13.0
    
  4. Klicken Sie auf Bereitstellen und warten Sie, bis die Bereitstellung abgeschlossen ist.

Cloud Scheduler-Job erstellen

  1. Rufen Sie Cloud Scheduler auf.
  2. Klicken Sie auf Job erstellen.
  3. Geben Sie die folgenden Konfigurationsdetails an:
    • Name: Geben Sie qualys-asset-context-collector-daily ein.
    • Region: Wählen Sie dieselbe Region wie die Cloud Run-Funktion aus.
    • Häufigkeit: Geben Sie 0 */6 * * * ein (alle sechs Stunden).
    • Zeitzone: Wählen Sie UTC aus.
    • Zieltyp: Wählen Sie Pub/Sub aus.
    • Thema: Wählen Sie qualys-asset-context-trigger aus.
    • Inhalt der Nachricht: Geben Sie {} ein.
  4. Klicken Sie auf Erstellen.
  5. Klicken Sie zum Prüfen der Einrichtung auf Ausführung erzwingen für den Job und sehen Sie dann in den Cloud Run-Logs und im Bucket nach, ob Hostdatensätze geschrieben wurden.

Feed in Google SecOps konfigurieren, um Qualys-Asset-Kontextlogs aufzunehmen

  1. Rufen Sie die SIEM-Einstellungen > Feeds auf.
  2. Klicken Sie auf Neuen Feed hinzufügen.
  3. Klicken Sie auf der nächsten Seite auf Einen einzelnen Feed konfigurieren.
  4. Geben Sie im Feld Feedname einen Namen für den Feed ein, z. B. Qualys asset context logs.
  5. Wählen Sie Google Cloud Storage V2 als Quelltyp aus.
  6. Wählen Sie Qualys-Asset-Kontext als Protokolltyp aus.
  7. Klicken Sie neben dem Feld Chronicle-Dienstkonto auf Dienstkonto abrufen und kopieren Sie die E‑Mail-Adresse des Dienstkontos.
  8. Klicken Sie auf Weiter.
  9. Geben Sie Werte für die folgenden Eingabeparameter an:
    • Storage-Bucket-URI: Geben Sie gs://qualys-asset-context-logs/qualys-asset-context/ ein. Diese URL muss mit einem nachgestellten Schrägstrich (/) enden.
    • Optionen zum Löschen von Quellen: Wählen Sie die gewünschte Option zum Löschen aus.
    • Maximales Dateialter: Dateien einschließen, die in den letzten Tagen geändert wurden. Der Standardwert ist 180 Tage.
  10. Klicken Sie auf Weiter.
  11. Prüfen Sie die neue Feedkonfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.

Dem Google SecOps-Dienstkonto Zugriff auf den Bucket gewähren

  1. Rufen Sie Cloud Storage > Buckets auf.
  2. Klicken Sie auf den Namen Ihres Buckets.
  3. Wechseln Sie zum Tab Berechtigungen.
  4. Klicken Sie auf Zugriff erlauben.
  5. Geben Sie die folgenden Konfigurationsdetails an:
    • Hauptkonten hinzufügen: Fügen Sie die E‑Mail-Adresse des Google SecOps-Dienstkontos aus der Feed-Einrichtung ein.
    • Rollen zuweisen: Wählen Sie Storage Object Viewer (oder Storage Object Admin, wenn Sie eine Löschoption ausgewählt haben) aus.
  6. Klicken Sie auf Speichern.

UDM-Zuordnungstabelle

Logfeld UDM-Zuordnung Logik
ASSET_ID entity.asset.asset_id Direkt zugeordnet
DNS_DATA.HOSTNAME entity.asset.hostname Direkt zugeordnet
IP entity.asset.ip Zusammengeführt
OS entity.asset.platform_software.platform Zugeordnet: (?i)windows → WINDOWS
ID entity.asset.product_object_id Direkt zugeordnet
dataset relations Zusammengeführt
– entity.asset.platform_software.platform Konstante: WINDOWS
– metadata.entity_type Konstante: ASSET
– metadata.product_name Konstante: QUALYS ASSET CONTEXT
– metadata.vendor_name Konstante: QUALYS ASSET CONTEXT
DNS_DATA.HOSTNAME entity.entity.asset.hostname Aus dem Änderungsprotokoll zugeordnet

Änderungsprotokoll

Änderungsprotokoll für diesen Parser ansehen

Benötigen Sie weitere Hilfe? Antworten von Community-Mitgliedern und Google SecOps-Experten erhalten