Qualys-Asset-Kontextlogs erfassen

Unterstützt in:

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

Der Qualys-Asset-Kontext stellt Host-Asset-Inventardaten (IP-Adressen, DNS-Namen, Betriebssystem, Cloud-Anbieter-Metadaten und Tags) von der Qualys-Plattform bereit. 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, aus dem 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-Funktionen, 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“, „Biregional“ oder „Multiregional“ 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. Identifizieren oder erstellen Sie einen API-Nutzer:
    • Gehen Sie zu Nutzer > Nutzerverwaltung.
    • Verwenden Sie einen vorhandenen Nutzer oder klicken Sie auf Neu > Nutzer und weisen Sie die Rolle Manager (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). Informationen dazu finden Sie unter Qualys-Plattform identifizieren.

Dienstkonto für die Cloud Run-Funktion erstellen

  1. Rufen Sie IAM und Verwaltung > Dienstkonten auf.
  2. Klicken Sie auf Dienstkonto erstellen.
  3. Geben Sie die folgenden Konfigurationsdetails an:
    • Dienstkontoname: 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: Hosteinträge in den Bucket schreiben.
    • Cloud Run-Invoker: Pub/Sub erlauben, die Funktion aufzurufen.
  6. Klicken Sie auf Weiter und dann auf Fertig.

Dem 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. Wechseln Sie zu Pub/Sub > Themen.
  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 Hosteinträge 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:
    • Dienstname: 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 das Zeitlimit für Anfragen auf 600 Sekunden und den 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 für 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 für den Job auf Ausführung erzwingen und sehen Sie sich dann die Cloud Run-Logs und den Bucket an, um zu bestätigen, dass Hosteinträge geschrieben wurden.

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

  1. Rufen Sie die Einstellungen > Datenverwaltung > Feeds auf. Wenn Sie eine reine SIEM-Plattform verwenden, rufen Sie die Einstellungen > Feeds auf.
  2. Klicken Sie auf Neuen Feed hinzufügen.
  3. Klicken Sie auf der nächsten Seite auf 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 Schrägstrich (/) enden.
    • Optionen zum Löschen der Quelle: Wählen Sie die gewünschte Löschoption 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 Feedeinrichtung 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 Änderungsprotokoll zugeordnet

Änderungsprotokoll

Änderungsprotokoll für diesen Parser ansehen

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