JSON-Logs für Box Collaboration erfassen

Unterstützt in:

In diesem Dokument wird beschrieben, wie Sie JSON-Logs für die Box-Zusammenarbeit mit AWS S3, Lambda und EventBridge-Zeitplan in Google Security Operations aufnehmen. Der Parser verarbeitet Box-Ereignisprotokolle im JSON-Format und ordnet sie einem einheitlichen Datenmodell (Unified Data Model, UDM) zu. Sie extrahiert relevante Felder aus den Rohlogs, führt Datentransformationen wie Umbenennen und Zusammenführen durch und reichert die Daten mit Zwischeninformationen an, bevor die strukturierten Ereignisdaten ausgegeben werden.

Hinweise

  • Google SecOps-Instanz
  • Privilegierter Zugriff auf Box (Admin- und Entwicklerkonsole)
  • Privilegierter Zugriff auf AWS (S3, IAM, Lambda, EventBridge) in derselben Region, in der Sie die Logs speichern möchten

Box Developer Console konfigurieren (Clientanmeldedaten)

  1. Melden Sie sich in der Box Developer Console an.
  2. Erstellen Sie eine benutzerdefinierte App mit Serverauthentifizierung (Berechtigungstyp der Clientanmeldedaten).
  3. Legen Sie Application Access (Anwendungszugriff) auf App + Enterprise Access (App- + Unternehmenszugriff) fest.
  4. Aktivieren Sie unter Application Scopes (Anwendungsbereiche) die Option Manage enterprise properties (Unternehmenseigenschaften verwalten).
  5. Autorisieren Sie die App in der Admin-Konsole > Apps > Custom Apps Manager mit der Client-ID.
  6. Kopieren Sie die Client-ID und den Clientschlüssel und speichern Sie sie an einem sicheren Ort.
  7. Rufen Sie die Admin-Konsole > „Konto und Abrechnung“ > „Kontoinformationen“ auf.
  8. Kopieren und speichern Sie die Unternehmens-ID an einem sicheren Ort.

AWS S3-Bucket und IAM für Google SecOps konfigurieren

  1. Erstellen Sie einen Amazon S3-Bucket. Folgen Sie dazu dieser Anleitung: Bucket erstellen.
  2. Speichern Sie den Namen und die Region des Buckets zur späteren Verwendung (z. B. box-collaboration-logs).
  3. Erstellen Sie einen Nutzer gemäß dieser Anleitung: IAM-Nutzer erstellen.
  4. Wählen Sie den erstellten Nutzer aus.
  5. Wählen Sie den Tab Sicherheitsanmeldedaten aus.
  6. Klicken Sie im Abschnitt Zugriffsschlüssel auf Zugriffsschlüssel erstellen.
  7. Wählen Sie als Anwendungsfall Drittanbieterdienst aus.
  8. Klicken Sie auf Weiter.
  9. Optional: Fügen Sie ein Beschreibungstag hinzu.
  10. Klicken Sie auf Zugriffsschlüssel erstellen.
  11. Klicken Sie auf CSV-Datei herunterladen, um den Zugriffsschlüssel und den geheimen Zugriffsschlüssel zur späteren Verwendung zu speichern.
  12. Klicken Sie auf Fertig.
  13. Wählen Sie den Tab Berechtigungen aus.
  14. Klicken Sie im Bereich Berechtigungsrichtlinien auf Berechtigungen hinzufügen.
  15. Wählen Sie Berechtigungen hinzufügen aus.
  16. Wählen Sie Richtlinien direkt anhängen aus.
  17. Suchen Sie nach der Richtlinie AmazonS3FullAccess und wählen Sie sie aus.
  18. Klicken Sie auf Weiter.
  19. Klicken Sie auf Berechtigungen hinzufügen.

IAM-Richtlinie und -Rolle für S3-Uploads konfigurieren

  1. Rufen Sie in der AWS-Konsole IAM > Richtlinien > Richtlinie erstellen > JSON-Tab auf.
  2. Geben Sie die folgende Richtlinie ein:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowPutBoxObjects",
          "Effect": "Allow",
          "Action": ["s3:PutObject"],
          "Resource": "arn:aws:s3:::box-collaboration-logs/*"
        },
        {
          "Sid": "AllowGetStateObject",
          "Effect": "Allow",
          "Action": ["s3:GetObject"],
          "Resource": "arn:aws:s3:::box-collaboration-logs/box/collaboration/state.json"
        }
      ]
    }
    
    
    • Ersetzen Sie box-collaboration-logs, wenn Sie einen anderen Bucket-Namen eingegeben haben.
  3. Klicken Sie auf Weiter > Richtlinie erstellen.

  4. Rufen Sie IAM > Rollen > Rolle erstellen > AWS-Service > Lambda auf.

  5. Hängen Sie die neu erstellte Richtlinie an.

  6. Geben Sie der Rolle den Namen WriteBoxToS3Role und klicken Sie auf Rolle erstellen.

Lambda-Funktion erstellen

  1. Rufen Sie in der AWS Console Lambda > Funktionen > Funktion erstellen auf.
  2. Klicken Sie auf Von Grund auf erstellen.
  3. Geben Sie die folgenden Konfigurationsdetails an:

    Einstellung Wert
    Name box_collaboration_to_s3
    Laufzeit Python 3.13
    Architektur x86_64
    Ausführungsrolle WriteBoxToS3Role
  4. Nachdem die Funktion erstellt wurde, öffnen Sie den Tab Code, löschen Sie den Stub und geben Sie den folgenden Code ein (box_collaboration_to_s3.py):

    #!/usr/bin/env python3
    # Lambda: Pull Box Enterprise Events to S3 (no transform)
    
    import os, json, time, urllib.parse
    from urllib.request import Request, urlopen
    from urllib.error import HTTPError, URLError
    import boto3
    
    TOKEN_URL = "https://api.box.com/oauth2/token"
    EVENTS_URL = "https://api.box.com/2.0/events"
    
    CID         = os.environ["BOX_CLIENT_ID"]
    CSECRET     = os.environ["BOX_CLIENT_SECRET"]
    ENT_ID      = os.environ["BOX_ENTERPRISE_ID"]
    STREAM_TYPE = os.environ.get("STREAM_TYPE", "admin_logs_streaming")
    LIMIT       = int(os.environ.get("LIMIT", "500"))
    BUCKET      = os.environ["S3_BUCKET"]
    PREFIX      = os.environ.get("S3_PREFIX", "box/collaboration/")
    STATE_KEY   = os.environ.get("STATE_KEY", "box/collaboration/state.json")
    
    s3 = boto3.client("s3")
    
    def get_state():
        try:
            obj = s3.get_object(Bucket=BUCKET, Key=STATE_KEY)
            data = json.loads(obj["Body"].read())
            return data.get("stream_position")
        except Exception:
            return None
    
    def put_state(pos):
        body = json.dumps({"stream_position": pos}, separators=(",", ":")).encode("utf-8")
        s3.put_object(Bucket=BUCKET, Key=STATE_KEY, Body=body, ContentType="application/json")
    
    def get_token():
        body = urllib.parse.urlencode({
            "grant_type": "client_credentials",
            "client_id": CID,
            "client_secret": CSECRET,
            "box_subject_type": "enterprise",
            "box_subject_id": ENT_ID,
        }).encode()
        req = Request(TOKEN_URL, data=body, method="POST")
        req.add_header("Content-Type", "application/x-www-form-urlencoded")
        with urlopen(req, timeout=30) as r:
            tok = json.loads(r.read().decode())
        return tok["access_token"]
    
    def fetch_events(token, stream_position=None, timeout=60, max_retries=5):
        params = {"stream_type": STREAM_TYPE, "limit": LIMIT, "stream_position": stream_position or "now"}
        qs = urllib.parse.urlencode(params)
        attempt, backoff = 0, 1.0
        while True:
            try:
                req = Request(f"{EVENTS_URL}?{qs}", method="GET")
                req.add_header("Authorization", f"Bearer {token}")
                with urlopen(req, timeout=timeout) as r:
                    return json.loads(r.read().decode())
            except HTTPError as e:
                if e.code == 429 and attempt < max_retries:
                    ra = e.headers.get("Retry-After")
                    delay = int(ra) if (ra and ra.isdigit()) else int(backoff)
                    time.sleep(max(1, delay)); attempt += 1; backoff *= 2; continue
                if 500 <= e.code <= 599 and attempt < max_retries:
                    time.sleep(backoff); attempt += 1; backoff *= 2; continue
                raise
            except URLError:
                if attempt < max_retries:
                    time.sleep(backoff); attempt += 1; backoff *= 2; continue
                raise
    
    def write_chunk(data):
        ts = time.strftime("%Y/%m/%d/%H%M%S", time.gmtime())
        key = f"{PREFIX}/{ts}-box-events.json"  
        s3.put_object(Bucket=BUCKET, Key=key,
                      Body=json.dumps(data, separators=(",", ":")).encode("utf-8"),
                      ContentType="application/json")  
        return key
    
    def lambda_handler(event=None, context=None):
        token = get_token()
        pos = get_state()
        total, idx = 0, 0
        while True:
            page = fetch_events(token, pos)
            entries = page.get("entries") or []
            if not entries:
                next_pos = page.get("next_stream_position") or pos
                if next_pos and next_pos != pos:
                    put_state(next_pos)
                break
    
            # уникальный ключ
            ts = time.strftime("%Y/%m/%d/%H%M%S", time.gmtime())
            key = f"{PREFIX}/{ts}-box-events-{idx:03d}.json"
            s3.put_object(Bucket=BUCKET, Key=key,
                          Body=json.dumps(page, separators=(",", ":")).encode("utf-8"),
                          ContentType="application/json")
            idx += 1
            total += len(entries)
    
            pos = page.get("next_stream_position") or pos
            if pos:
                put_state(pos)
    
            if len(entries) < LIMIT:
                break
    
        return {"ok": True, "written": total, "next_stream_position": pos}
    
    
  5. Klicken Sie auf Konfiguration> Umgebungsvariablen> Bearbeiten> Neue Umgebungsvariable hinzufügen.

  6. Geben Sie die folgenden Umgebungsvariablen ein und ersetzen Sie die Platzhalter durch Ihre Werte:

    Schlüssel Beispiel
    S3_BUCKET box-collaboration-logs
    S3_PREFIX box/collaboration/
    STATE_KEY box/collaboration/state.json
    BOX_CLIENT_ID Box-Client-ID eingeben
    BOX_CLIENT_SECRET Box-Clientschlüssel eingeben
    BOX_ENTERPRISE_ID Box-Unternehmens-ID eingeben
    STREAM_TYPE admin_logs_streaming
    LIMIT 500
  7. Bleiben Sie nach dem Erstellen der Funktion auf der zugehörigen Seite oder öffnen Sie Lambda > Funktionen > Ihre Funktion.

  8. Wählen Sie den Tab Konfiguration aus.

  9. Klicken Sie im Bereich Allgemeine Konfiguration auf Bearbeiten.

  10. Ändern Sie Zeitlimit in 10 Minuten (600 Sekunden) und klicken Sie auf Speichern.

Lambda-Funktion planen (EventBridge Scheduler)

  1. Gehen Sie zu Amazon EventBridge > Scheduler > Create schedule (Amazon EventBridge > Scheduler > Zeitplan erstellen).
  2. Geben Sie die folgenden Konfigurationsdetails an:
    • Wiederkehrender Zeitplan: Preis (15 min).
    • Ziel: Ihre Lambda-Funktion.
    • Name: box-collaboration-schedule-15min.
  3. Klicken Sie auf Zeitplan erstellen.

Feed in Google SecOps konfigurieren, um Box-Logs aufzunehmen

  1. Rufen Sie die SIEM-Einstellungen > Feeds auf.
  2. Klicken Sie auf Neuen Feed hinzufügen.
  3. Geben Sie im Feld Feed name (Feedname) einen Namen für den Feed ein, z. B. Box Collaboration.
  4. Wählen Sie Amazon S3 V2 als Quelltyp aus.
  5. Wählen Sie Box als Logtyp aus.
  6. Klicken Sie auf Weiter.
  7. Geben Sie Werte für die folgenden Eingabeparameter an:
    • S3-URI: Der Bucket-URI (das Format sollte s3://box-collaboration-logs/box/collaboration/ sein). Ersetzen Sie box-collaboration-logs durch den tatsächlichen Namen des Buckets.
    • Optionen zum Löschen der Quelle: 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.
    • Zugriffsschlüssel-ID: Zugriffsschlüssel des Nutzers mit Zugriff auf den S3-Bucket.
    • Secret Access Key (Geheimer Zugriffsschlüssel): Geheimer Nutzersicherheitsschlüssel mit Zugriff auf den S3-Bucket.
    • Asset-Namespace: Der Asset-Namespace.
    • Aufnahmelabels: Das Label, das auf die Ereignisse aus diesem Feed angewendet werden soll.
  8. Klicken Sie auf Weiter.
  9. Prüfen Sie die neue Feedkonfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.

UDM-Zuordnungstabelle

Logfeld UDM-Zuordnung Logik
additional_details.ekm_id additional.fields Wert aus „additional_details.ekm_id“
additional_details.service_id additional.fields Wert aus „additional_details.service_id“
additional_details.service_name additional.fields Wert aus „additional_details.service_name“
additional_details.shared_link_id additional.fields Wert aus „additional_details.shared_link_id“
additional_details.size target.file.size Wert aus „additional_details.size“
additional_details.version_id additional.fields Wert aus „additional_details.version_id“
created_at metadata.event_timestamp Wert aus „created_at“
created_by.id principal.user.userid Wert aus „created_by.id“
created_by.login principal.user.email_addresses Wert aus „created_by.login“
created_by.name principal.user.user_display_name Wert aus „created_by.name“
event_id metadata.product_log_id Wert aus „event_id“
event_type metadata.product_event_type Wert aus „event_type“
ip_address principal.ip Wert aus „ip_address“ übernommen
source.item_id target.file.product_object_id Wert aus „source.item_id“
source.item_name target.file.full_path Wert aus „source.item_name“
source.item_type Nicht zugeordnet
source.login target.user.email_addresses Wert aus source.login
source.name target.user.user_display_name Wert aus „source.name“
source.owned_by.id target.user.userid Wert aus „source.owned_by.id“
source.owned_by.login target.user.email_addresses Wert aus „source.owned_by.login“
source.owned_by.name target.user.user_display_name Wert aus „source.owned_by.name“
source.parent.id Nicht zugeordnet
source.parent.name Nicht zugeordnet
source.parent.type Nicht zugeordnet
source.type Nicht zugeordnet
Typ metadata.log_type Wert aus Typ übernommen
metadata.vendor_name Hartcodierter Wert
metadata.product_name Hartcodierter Wert
security_result.action Abgeleitet von „event_type“. Wenn event_type FAILED_LOGIN ist, dann BLOCK, wenn event_type USER_LOGIN ist, dann ALLOW, andernfalls UNSPECIFIED.
extensions.auth.type Abgeleitet von „event_type“. Wenn event_type USER_LOGIN oder ADMIN_LOGIN ist, dann MACHINE, andernfalls UNSPECIFIED.
extensions.auth.mechanism Abgeleitet von „event_type“. Wenn event_type USER_LOGIN oder ADMIN_LOGIN ist, dann USERNAME_PASSWORD, andernfalls UNSPECIFIED.

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