Signal Sciences-WAF-Protokolle erfassen

Unterstützt in:

In diesem Dokument wird beschrieben, wie Sie Signal Sciences-WAF-Logs mithilfe von Google Cloud Storage in Google Security Operations aufnehmen. Der Parser wandelt Signal Sciences-Protokolle aus dem JSON-Format in das einheitliche Datenmodell (Unified Data Model, UDM) von Chronicle um. Es werden zwei primäre Nachrichtenstrukturen verarbeitet: „RPC.PreRequest/PostRequest“-Nachrichten werden mit Grok-Mustern geparst, während andere Nachrichten als JSON-Objekte verarbeitet werden, wobei relevante Felder extrahiert und dem UDM-Schema zugeordnet werden.

Hinweise

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

  • Google SecOps-Instanz
  • VPC Flow ist in Ihrer Google Cloud -Umgebung eingerichtet und aktiv
  • Berechtigter Zugriff auf die WAF von Signal Sciences

Google Cloud Storage-Bucket erstellen

  1. Melden Sie sich in der Google Cloud Konsole an.
  2. Rufen Sie die Seite Cloud Storage-Buckets auf.

    Buckets aufrufen

  3. Klicken Sie auf Erstellen.

  4. Geben Sie auf der Seite Bucket erstellen die Bucket-Informationen ein. Klicken Sie nach jedem der folgenden Schritte auf Weiter, um mit dem nächsten Schritt fortzufahren:

    1. Führen Sie im Abschnitt Einstieg die folgenden Schritte aus:

      • Geben Sie einen eindeutigen Namen ein, der den Anforderungen für Bucket-Namen entspricht (z. B. vpcflow-logs).
      • Wenn Sie den hierarchischen Namespace aktivieren möchten, klicken Sie auf den Maximierungspfeil, um den Bereich Für dateiorientierte und datenintensive Arbeitslasten optimieren zu maximieren, und wählen Sie dann Hierarchischen Namespace für diesen Bucket aktivieren aus.
      • Wenn Sie ein Bucket-Label hinzufügen möchten, klicken Sie auf den Erweiterungspfeil, um den Bereich Labels zu maximieren.
      • Klicken Sie auf Label hinzufügen und geben Sie einen Schlüssel und einen Wert für das Label an.
    2. Gehen Sie im Bereich Speicherort für Daten auswählen so vor:

      • Standorttyp auswählen.
      • Wählen Sie im Menü für den Standorttyp einen Speicherort aus, an dem die Objektdaten in Ihrem Bucket dauerhaft gespeichert werden sollen.
      • Wenn Sie die Bucket-übergreifende Replikation einrichten möchten, maximieren Sie den Bereich Bucket-übergreifende Replikation einrichten.
    3. Wählen Sie im Abschnitt Speicherklasse für Ihre Daten auswählen entweder eine Standardspeicherklasse für den Bucket oder Autoclass für die automatische Verwaltung der Speicherklassen Ihrer Bucket-Daten aus.

    4. Wählen Sie im Abschnitt Zugriff auf Objekte steuern die Option nicht aus, um die Verhinderung des öffentlichen Zugriffs zu erzwingen, und wählen Sie ein Zugriffssteuerungsmodell für die Objekte Ihres Buckets aus.

    5. Gehen Sie im Bereich Auswählen, wie Objektdaten geschützt werden so vor:

      • Wählen Sie unter Datenschutz die Optionen aus, die Sie für Ihren Bucket festlegen möchten.
      • Um auszuwählen, wie Ihre Objektdaten verschlüsselt werden, klicken Sie auf den Erweiterungspfeil mit Label Datenverschlüsselung und wählen Sie eine Methode für die Datenverschlüsselung aus.
  5. Klicken Sie auf Erstellen.

Signal Sciences WAF API-Schlüssel konfigurieren

  1. Melden Sie sich in der Web-UI der Signal Sciences WAF an.
  2. Gehen Sie zu Mein Profil > API-Zugriffstokens.
  3. Klicken Sie auf API-Zugriffstoken hinzufügen.
  4. Geben Sie einen eindeutigen, aussagekräftigen Namen an (z. B. Google SecOps).
  5. Klicken Sie auf API-Zugriffstoken erstellen.
  6. Kopieren Sie das Token und speichern Sie es an einem sicheren Ort.
  7. Klicken Sie auf Verstanden, um das Token zu erstellen.

Ein Script auf einem Linux-Host bereitstellen, um Protokolle von Signal Sciences abzurufen und in Google Cloud

  1. Melden Sie sich über SSH beim Linux-Host an.
  2. Python-Bibliothek installieren, um die Signal Sciences-WAF-JSON-Datei in einem Cloud Storage-Bucket zu speichern:

    pip install google-cloud-storage
    
  3. Legen Sie diese Umgebungsvariable fest, um die JSON-Datei mit den Anmeldedaten von Google Cloudaufzurufen:

    export GOOGLE_APPLICATION_CREDENTIALS="path/to/your/service-account-key.json"
    
  4. Konfigurieren Sie die folgenden Umgebungsvariablen, da diese Informationen nicht hartcodiert werden dürfen:

    export SIGSCI_EMAIL=<Signal_Sciences_account_email>
    export SIGSCI_TOKEN=<Signal_Sciences_API_token>
    export SIGSCI_CORP=<Corporation_name_in_Signal_Sciences>
    
  5. Führen Sie das folgende Skript aus:

    import sys
    import requests
    import os
    import calendar
    import json
    from datetime import datetime, timedelta
    from google.cloud import storage
    
    # Check if all necessary environment variables are set
    
    if 'SIGSCI_EMAIL' not in os.environ or 'SIGSCI_TOKEN' not in os.environ or 'SIGSCI_CORP' not in os.environ:
    print("ERROR: You need to define SIGSCI_EMAIL, SIGSCI_TOKEN, and SIGSCI_CORP environment variables.")
    print("Please fix and run again. Existing...")
    sys.exit(1)  # Exit if environment variables are not set
    
    # Define the Google Cloud Storage bucket name and output file name
    
    bucket_name = 'Your_GCS_Bucket'  # Replace with your GCS bucket name
    output_file_name = 'signal_sciences_logs.json'
    
    # Initialize Google Cloud Storage client
    
    storage_client = storage.Client()
    
    # Function to upload data to Google Cloud Storage
    
    def upload_to_gcs(bucket_name, data, destination_blob_name):
        bucket = storage_client.bucket(bucket_name)
        blob = bucket.blob(destination_blob_name)
        blob.upload_from_string(data, content_type='application/json')
        print(f"Data uploaded to {destination_blob_name} in bucket {bucket_name}")
    
    # Signal Sciences API information
    
    api_host = 'https://dashboard.signalsciences.net'
    # email = '[email protected]'  # Signal Sciences account email
    # token = 'XXXXXXXX-XXXX-XXX-XXXX-XXXXXXXXXXXX'  # API token for authentication
    # corp_name = 'Domain'  # Corporation name in Signal Sciences
    # site_names = ['testenv']  # Replace with your actual site names
    
    # List of comma-delimited sites that you want to extract data from
    
    site_names = [ 'site123', 'site345' ]        # Define all sites to pull logs from
    
    email = os.environ.get('SIGSCI_EMAIL')       # Signal Sciences account email
    token = os.environ.get('SIGSCI_TOKEN')       # API token for authentication
    corp_name = os.environ.get('SIGSCI_CORP')    # Corporation name in Signal Sciences
    
    # Calculate the start and end timestamps for the previous hour in UTC
    
    until_time = datetime.utcnow().replace(minute=0, second=0, microsecond=0)
    from_time = until_time - timedelta(hours=1)
    until_time = calendar.timegm(until_time.utctimetuple())
    from_time = calendar.timegm(from_time.utctimetuple())
    
    # Prepare HTTP headers for the API request
    
    headers = {
        'Content-Type': 'application/json',
        'x-api-user': email,
        'x-api-token': token
    }
    
    # Collect logs for each site
    
    collected_logs = []
    
    for site_name in site_names:
        url = f"{api_host}/api/v0/corps/{corp_name}/sites/{site_name}/feed/requests?from={from_time}&until={until_time}"
        while True:
            response = requests.get(url, headers=headers)
            if response.status_code != 200:
                print(f"Error fetching logs: {response.text}", file=sys.stderr)
                break
    
            # Parse the JSON response
    
            data = response.json()
            collected_logs.extend(data['data'])  # Add the log messages to our list
    
            # Pagination: check if there is a next page
    
            next_url = data.get('next', {}).get('uri')
            if not next_url:
                break
            url = api_host + next_url
    
    # Convert the collected logs to a newline-delimited JSON string
    
    json_data = '\n'.join(json.dumps(log) for log in collected_logs)
    
    # Save the newline-delimited JSON data to a GCS bucket
    
    upload_to_gcs(bucket_name, json_data, output_file_name)
    

    Feeds einrichten

Es gibt zwei verschiedene Einstiegspunkte zum Einrichten von Feeds auf der Google SecOps-Plattform:

  • SIEM-Einstellungen > Feeds
  • Content Hub > Content-Pakete

Feeds unter „SIEM-Einstellungen“ > „Feeds“ einrichten

So konfigurieren Sie einen Feed:

  1. Gehen Sie zu SIEM-Einstellungen > Feeds.
  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. Signal Sciences WAF Logs.
  5. Wählen Sie Google Cloud Storage als Quelltyp aus.
  6. Wählen Sie Signal Sciences WAF als Protokolltyp aus.
  7. Klicken Sie als Chronicle-Dienstkonto auf Dienstkonto abrufen.
  8. Klicken Sie auf Weiter.
  9. Geben Sie Werte für die folgenden Eingabeparameter an:

    • Storage Bucket-URI: Google Cloud Storage Bucket-URL im Format gs://my-bucket/<value>.
    • URI ist: Wählen Sie Verzeichnis mit Unterverzeichnissen aus.
    • Optionen zum Löschen der Quelle: Wählen Sie die gewünschte Löschoption aus.

  10. Klicken Sie auf Weiter.

  11. Prüfen Sie die neue Feedkonfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.

Feeds über den Content Hub einrichten

Geben Sie Werte für die folgenden Felder an:

  • Storage Bucket-URI: Google Cloud Storage Bucket-URL im Format gs://my-bucket/<value>.
  • URI ist: Wählen Sie Verzeichnis mit Unterverzeichnissen aus.
  • Optionen zum Löschen der Quelle: Wählen Sie die gewünschte Löschoption aus.

Erweiterte Optionen

  • Feedname: Ein vordefinierter Wert, der den Feed identifiziert.
  • Quelltyp: Methode, mit der Protokolle in Google SecOps erfasst werden.
  • Asset-Namespace: Namespace, der dem Feed zugeordnet ist.
  • Aufnahmelabels: Labels, die auf alle Ereignisse aus diesem Feed angewendet werden.

UDM-Zuordnungstabelle

Logfeld UDM-Zuordnung Logik
CLIENT-IP target.ip Wird aus dem CLIENT-IP-Header-Feld extrahiert.
CLIENT-IP target.port Wird aus dem CLIENT-IP-Header-Feld extrahiert.
Verbindung security_result.about.labels Der Wert wird aus dem Feld Connection des Rohlogs übernommen und security_result.about.labels zugeordnet.
Content-Length security_result.about.labels Der Wert wird aus dem Feld Content-Length des Rohlogs übernommen und security_result.about.labels zugeordnet.
Content-Type security_result.about.labels Der Wert wird aus dem Feld Content-Type des Rohlogs übernommen und security_result.about.labels zugeordnet.
erstellt metadata.event_timestamp Der Wert wird aus dem Feld created des Rohlogs übernommen und metadata.event_timestamp zugeordnet.
details.headersIn security_result.about.resource.attribute.labels Der Wert wird aus dem Feld details.headersIn des Rohlogs übernommen und security_result.about.resource.attribute.labels zugeordnet.
details.headersOut security_result.about.resource.attribute.labels Der Wert wird aus dem Feld details.headersOut des Rohlogs übernommen und security_result.about.resource.attribute.labels zugeordnet.
details.id principal.process.pid Der Wert wird aus dem Feld details.id des Rohlogs übernommen und principal.process.pid zugeordnet.
details.method network.http.method Der Wert wird aus dem Feld details.method des Rohlogs übernommen und network.http.method zugeordnet.
details.protocol network.application_protocol Der Wert wird aus dem Feld details.protocol des Rohlogs übernommen und network.application_protocol zugeordnet.
details.remoteCountryCode principal.location.country_or_region Der Wert wird aus dem Feld details.remoteCountryCode des Rohlogs übernommen und principal.location.country_or_region zugeordnet.
details.remoteHostname target.hostname Der Wert wird aus dem Feld details.remoteHostname des Rohlogs übernommen und target.hostname zugeordnet.
details.remoteIP target.ip Der Wert wird aus dem Feld details.remoteIP des Rohlogs übernommen und target.ip zugeordnet.
details.responseCode network.http.response_code Der Wert wird aus dem Feld details.responseCode des Rohlogs übernommen und network.http.response_code zugeordnet.
details.responseSize network.received_bytes Der Wert wird aus dem Feld details.responseSize des Rohlogs übernommen und network.received_bytes zugeordnet.
details.serverHostname principal.hostname Der Wert wird aus dem Feld details.serverHostname des Rohlogs übernommen und principal.hostname zugeordnet.
details.serverName principal.asset.network_domain Der Wert wird aus dem Feld details.serverName des Rohlogs übernommen und principal.asset.network_domain zugeordnet.
details.tags security_result.detection_fields Der Wert wird aus dem Feld details.tags des Rohlogs übernommen und security_result.detection_fields zugeordnet.
details.tlsCipher network.tls.cipher Der Wert wird aus dem Feld details.tlsCipher des Rohlogs übernommen und network.tls.cipher zugeordnet.
details.tlsProtocol network.tls.version Der Wert wird aus dem Feld details.tlsProtocol des Rohlogs übernommen und network.tls.version zugeordnet.
details.userAgent network.http.user_agent Der Wert wird aus dem Feld details.userAgent des Rohlogs übernommen und network.http.user_agent zugeordnet.
details.uri network.http.referral_url Der Wert wird aus dem Feld details.uri des Rohlogs übernommen und network.http.referral_url zugeordnet.
eventType metadata.product_event_type Der Wert wird aus dem Feld eventType des Rohlogs übernommen und metadata.product_event_type zugeordnet.
headersIn security_result.about.labels Der Wert wird aus dem Feld headersIn des Rohlogs übernommen und security_result.about.labels zugeordnet.
headersOut security_result.about.labels Der Wert wird aus dem Feld headersOut des Rohlogs übernommen und security_result.about.labels zugeordnet.
id principal.process.pid Der Wert wird aus dem Feld id des Rohlogs übernommen und principal.process.pid zugeordnet.
Nachricht metadata.description Der Wert wird aus dem Feld message des Rohlogs übernommen und metadata.description zugeordnet.
Methode network.http.method Der Wert wird aus dem Feld method des Rohlogs übernommen und network.http.method zugeordnet.
ModuleVersion metadata.ingestion_labels Der Wert wird aus dem Feld ModuleVersion des Rohlogs übernommen und metadata.ingestion_labels zugeordnet.
msgData.actions security_result.action Der Wert wird aus dem Feld msgData.actions des Rohlogs übernommen und security_result.action zugeordnet.
msgData.changes target.resource.attribute.labels Der Wert wird aus dem Feld msgData.changes des Rohlogs übernommen und target.resource.attribute.labels zugeordnet.
msgData.conditions security_result.description Der Wert wird aus dem Feld msgData.conditions des Rohlogs übernommen und security_result.description zugeordnet.
msgData.detailLink network.http.referral_url Der Wert wird aus dem Feld msgData.detailLink des Rohlogs übernommen und network.http.referral_url zugeordnet.
msgData.name target.resource.name Der Wert wird aus dem Feld msgData.name des Rohlogs übernommen und target.resource.name zugeordnet.
msgData.reason security_result.summary Der Wert wird aus dem Feld msgData.reason des Rohlogs übernommen und security_result.summary zugeordnet.
msgData.sites network.http.user_agent Der Wert wird aus dem Feld msgData.sites des Rohlogs übernommen und network.http.user_agent zugeordnet.
Protokoll network.application_protocol Der Wert wird aus dem Feld protocol des Rohlogs übernommen und network.application_protocol zugeordnet.
remoteCountryCode principal.location.country_or_region Der Wert wird aus dem Feld remoteCountryCode des Rohlogs übernommen und principal.location.country_or_region zugeordnet.
remoteHostname target.hostname Der Wert wird aus dem Feld remoteHostname des Rohlogs übernommen und target.hostname zugeordnet.
remoteIP target.ip Der Wert wird aus dem Feld remoteIP des Rohlogs übernommen und target.ip zugeordnet.
responseCode network.http.response_code Der Wert wird aus dem Feld responseCode des Rohlogs übernommen und network.http.response_code zugeordnet.
responseSize network.received_bytes Der Wert wird aus dem Feld responseSize des Rohlogs übernommen und network.received_bytes zugeordnet.
serverHostname principal.hostname Der Wert wird aus dem Feld serverHostname des Rohlogs übernommen und principal.hostname zugeordnet.
serverName principal.asset.network_domain Der Wert wird aus dem Feld serverName des Rohlogs übernommen und principal.asset.network_domain zugeordnet.
Tags security_result.detection_fields Der Wert wird aus dem Feld tags des Rohlogs übernommen und security_result.detection_fields zugeordnet.
timestamp metadata.event_timestamp Der Wert wird aus dem Feld timestamp des Rohlogs übernommen und metadata.event_timestamp zugeordnet.
tlsCipher network.tls.cipher Der Wert wird aus dem Feld tlsCipher des Rohlogs übernommen und network.tls.cipher zugeordnet.
tlsProtocol network.tls.version Der Wert wird aus dem Feld tlsProtocol des Rohlogs übernommen und network.tls.version zugeordnet.
URI target.url Der Wert wird aus dem Feld URI des Rohlogs übernommen und target.url zugeordnet.
userAgent network.http.user_agent Der Wert wird aus dem Feld userAgent des Rohlogs übernommen und network.http.user_agent zugeordnet.
uri network.http.referral_url Der Wert wird aus dem Feld uri des Rohlogs übernommen und network.http.referral_url zugeordnet.
X-ARR-SSL network.tls.client.certificate.issuer Der Wert wird mithilfe von Grok- und KV-Filtern aus dem Header-Feld X-ARR-SSL extrahiert.
metadata.event_type Der Ereignistyp wird vom Parser anhand der Anwesenheit von Ziel- und Hauptinformationen bestimmt. Wenn sowohl „target“ als auch „principal“ vorhanden sind, ist der Ereignistyp NETWORK_HTTP. Wenn nur „principal“ vorhanden ist, ist der Ereignistyp STATUS_UPDATE. Andernfalls ist der Ereignistyp GENERIC_EVENT.
metadata.log_type Der Wert ist auf SIGNAL_SCIENCES_WAF hartcodiert.
metadata.product_name Der Wert ist auf Signal Sciences WAF hartcodiert.
metadata.vendor_name Der Wert ist auf Signal Sciences hartcodiert.
principal.asset.hostname Der Wert wird aus dem Feld principal.hostname übernommen.
target.asset.hostname Der Wert wird aus dem Feld target.hostname übernommen.
target.asset.ip Der Wert wird aus dem Feld target.ip übernommen.
target.user.user_display_name Der Wert wird mit einem Grok-Filter aus dem Feld message_data extrahiert.
target.user.userid Der Wert wird mit einem Grok-Filter aus dem Feld message_data extrahiert.

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