Protokolle des File Scanning Framework erfassen
In diesem Dokument wird beschrieben, wie Sie Protokolle des File Scanning Framework mit Google Cloud Storage V2 in Google Security Operations aufnehmen.
Das File Scanning Framework (FSF) ist eine Open-Source-Lösung für das rekursive Scannen von Dateien, die von Emerson Electric Co. entwickelt wurde. FSF verwendet eine Client-Server-Architektur, um Dateien zu analysieren und detaillierte JSON-Scanergebnisse zu generieren, einschließlich Dateimetadaten, YARA-Signaturübereinstimmungen, extrahierten Unterobjekten und modulspezifischen Metadaten.
Hinweise
Folgende Voraussetzungen müssen erfüllt sein:
- Eine Google SecOps-Instanz
- Ein GCP-Projekt mit aktivierter Cloud Storage API
- Berechtigungen zum Erstellen und Verwalten von GCS-Buckets
- Berechtigungen zum Verwalten von IAM-Richtlinien für GCS-Buckets
- Eine bereitgestellte FSF-Serverinstanz mit Schreibzugriff auf das Logverzeichnis
- Root- oder sudo-Zugriff auf den FSF-Serverhost
Google Cloud Storage-Bucket erstellen
- Gehen Sie zur Google Cloud Console.
- Wählen Sie Ihr Projekt aus oder erstellen Sie ein neues.
- Rufen Sie im Navigationsmenü Cloud Storage > Buckets auf.
- Klicken Sie auf Bucket erstellen.
Geben Sie die folgenden Konfigurationsdetails an:
Einstellung Wert Bucket benennen Geben Sie einen global eindeutigen Namen ein, z. B. fsf-logs-secops.Standorttyp Wählen Sie je nach Bedarf „Region“, „Dual-Region“ oder „Multi-Region“ aus. Standort Wählen Sie den Speicherort aus (z. B. us-central1).Speicherklasse Standard (empfohlen für Logs, auf die häufig zugegriffen wird). Zugriffskontrolle Einheitlich (empfohlen). Schutzmaßnahmen Optional: Aktivieren Sie die Objektversionsverwaltung oder die Aufbewahrungsrichtlinie. Klicken Sie auf Erstellen.
FSF-Log-Ausgabeverzeichnis konfigurieren
FSF schreibt JSON-Scanergebnisse in ein konfigurierbares Logverzeichnis. Konfigurieren Sie ein dediziertes Verzeichnis für die Google SecOps-Aufnahme.
- Stellen Sie über SSH eine Verbindung zum FSF-Serverhost her.
Öffnen Sie die FSF-Serverkonfigurationsdatei:
sudo nano /opt/fsf/fsf-server/conf/config.pySuchen Sie das
SCANNER_CONFIG-Wörterbuch.Aktualisieren Sie den Parameter
LOG_PATHauf ein dediziertes Verzeichnis:SCANNER_CONFIG = { 'LOG_PATH': '/var/log/fsf', 'YARA_PATH': '/opt/fsf/fsf-server/yara/rules.yara', 'PID_PATH': '/tmp/scanner.pid', 'EXPORT_PATH': '/tmp', 'TIMEOUT': 60, 'MAX_DEPTH': 10 }Speichern und schließen Sie die Datei.
Erstellen Sie das Logverzeichnis mit den entsprechenden Berechtigungen:
sudo mkdir -p /var/log/fsf sudo chown -R fsf:fsf /var/log/fsf sudo chmod 755 /var/log/fsfStarten Sie den FSF-Server neu, damit die Änderungen wirksam werden:
sudo systemctl restart fsfPrüfen Sie, ob FSF Logs in das neue Verzeichnis schreibt:
ls -lh /var/log/fsf/
Fluentd installieren und konfigurieren
Fluentd liest FSF-Logdateien und sendet sie an Google Cloud Storage.
Fluentd installieren
Installieren Sie Fluentd (td-agent) auf dem FSF-Serverhost:
curl -fsSL https://toolbelt.treasuredata.com/sh/install-ubuntu-jammy-td-agent4.sh | shInstallieren Sie das GCS-Ausgabe-Plug-in:
sudo td-agent-gem install fluent-plugin-gcsPlug-in-Installation prüfen:
td-agent-gem list | grep fluent-plugin-gcs
GCP-Dienstkonto für Fluentd erstellen
- Wechseln Sie in der GCP Console zu IAM & Verwaltung > Dienstkonten.
- Klicken Sie auf Dienstkonto erstellen.
- Geben Sie die folgenden Konfigurationsdetails an:
- Name des Dienstkontos: Geben Sie
fsf-fluentd-shipperein. - Beschreibung des Dienstkontos: Geben Sie
Service account for Fluentd to ship FSF logs to GCSein.
- Name des Dienstkontos: Geben Sie
- Klicken Sie auf Erstellen und fortfahren.
- Im Abschnitt Diesem Dienstkonto Zugriff auf das Projekt erteilen:
- Klicken Sie auf Rolle auswählen.
- Suchen Sie nach Storage-Objekt-Administrator und wählen Sie die Rolle aus.
- Klicken Sie auf Weiter.
- Klicken Sie auf Fertig.
Dienstkontoschlüssel erstellen
- Klicken Sie in der Liste Dienstkonten auf das Dienstkonto (
fsf-fluentd-shipper). - Rufen Sie den Tab Schlüssel auf.
- Klicken Sie auf Schlüssel hinzufügen > Neuen Schlüssel erstellen.
- Wählen Sie JSON als Schlüsseltyp aus.
- Klicken Sie auf Erstellen.
- Die JSON-Schlüsseldatei wird auf Ihren Computer heruntergeladen.
Übertragen Sie die Schlüsseldatei auf den FSF-Serverhost:
scp /path/to/downloaded-key.json user@fsf-server:/etc/td-agent/gcp-key.jsonLegen Sie die entsprechenden Berechtigungen für die Schlüsseldatei fest:
sudo chown td-agent:td-agent /etc/td-agent/gcp-key.json sudo chmod 600 /etc/td-agent/gcp-key.json
IAM-Berechtigungen für GCS-Bucket erteilen
- Rufen Sie Cloud Storage > Buckets auf.
- Klicken Sie auf den Bucket-Namen (
fsf-logs-secops). - Wechseln Sie zum Tab Berechtigungen.
- Klicken Sie auf Zugriff erlauben.
- Geben Sie die folgenden Konfigurationsdetails an:
- Hauptkonten hinzufügen: Geben Sie die E-Mail-Adresse des Dienstkontos ein (z. B.
fsf-fluentd-shipper@PROJECT_ID.iam.gserviceaccount.com). - Rollen zuweisen: Wählen Sie Storage-Objekt-Administrator aus.
- Hauptkonten hinzufügen: Geben Sie die E-Mail-Adresse des Dienstkontos ein (z. B.
- Klicken Sie auf Speichern.
Fluentd konfigurieren
Erstellen Sie auf dem FSF-Serverhost eine Fluentd-Konfigurationsdatei:
sudo nano /etc/td-agent/td-agent.confFügen Sie die folgende Konfiguration hinzu:
# Tail FSF JSON logs <source> @type tail path /var/log/fsf/*.log pos_file /var/log/td-agent/fsf.log.pos tag fsf.scan read_from_head true <parse> @type json time_key timestamp time_format %Y-%m-%dT%H:%M:%S.%L%z </parse> </source> # Ship to Google Cloud Storage <match fsf.scan> @type gcs project YOUR_GCP_PROJECT_ID keyfile /etc/td-agent/gcp-key.json bucket fsf-logs-secops object_key_format %{path}%{time_slice}_%{index}.%{file_extension} path fsf-logs/ <buffer tag,time> @type file path /var/log/td-agent/buffer/gcs timekey 3600 timekey_wait 10m timekey_use_utc true chunk_limit_size 10MB </buffer> <format> @type json </format> store_as json auto_create_bucket false </match>Ersetzen Sie
YOUR_GCP_PROJECT_IDdurch Ihre tatsächliche GCP-Projekt-ID.Speichern und schließen Sie die Datei.
Erstellen Sie das Pufferverzeichnis:
sudo mkdir -p /var/log/td-agent/buffer/gcs sudo chown -R td-agent:td-agent /var/log/td-agent/bufferStarten Sie Fluentd neu, um die Konfiguration anzuwenden:
sudo systemctl restart td-agentAktivieren Sie, dass Fluentd beim Booten gestartet wird:
sudo systemctl enable td-agentPrüfen Sie, ob Fluentd ausgeführt wird:
sudo systemctl status td-agent
Logversand prüfen
Prüfen Sie die Fluentd-Logs auf Fehler:
sudo tail -f /var/log/td-agent/td-agent.logLösen Sie einen FSF-Testscan aus, um Logs zu generieren:
echo "test content" > /tmp/test.txt /opt/fsf/fsf-client/fsf_client.py /tmp/test.txt --suppress-reportWarten Sie ein bis zwei Minuten, bis Fluentd die Logs verarbeitet und gesendet hat.
Rufen Sie in der GCP Console Cloud Storage > Buckets auf.
Klicken Sie auf den Bucket-Namen (
fsf-logs-secops).Rufen Sie das Präfix
fsf-logs/auf.Prüfen Sie, ob JSON-Dateien mit Zeitstempeln erstellt werden.
Laden Sie eine Datei herunter und prüfen Sie sie, um zu bestätigen, dass sie FSF-Scanergebnisse im JSON-Format enthält.
Google SecOps-Dienstkonto abrufen
Google SecOps verwendet ein eindeutiges Dienstkonto, um Daten aus Ihrem GCS-Bucket zu lesen. Sie müssen diesem Dienstkonto Zugriff auf Ihren Bucket gewähren.
E-Mail-Adresse des Dienstkontos abrufen
- Rufen Sie die SIEM-Einstellungen > Feeds auf.
- Klicken Sie auf Neuen Feed hinzufügen.
- Klicken Sie auf Einzelnen Feed konfigurieren.
- Geben Sie im Feld Feedname einen Namen für den Feed ein, z. B.
FSF File Scanning Logs. - Wählen Sie Google Cloud Storage V2 als Quelltyp aus.
- Wählen Sie File Scanning Framework als Log type (Logtyp) aus.
Klicken Sie auf Dienstkonto abrufen. Es wird eine eindeutige E-Mail-Adresse für das Dienstkonto angezeigt, z. B.:
secops-12345678@secops-gcp-prod.iam.gserviceaccount.comKopieren Sie die E-Mail-Adresse, um sie im nächsten Schritt zu verwenden.
Klicken Sie auf Weiter.
Geben Sie Werte für die folgenden Eingabeparameter an:
Storage-Bucket-URL: Geben Sie den GCS-Bucket-URI mit dem Präfixpfad ein:
gs://fsf-logs-secops/fsf-logs/Option zum Löschen der Quelle: Wählen Sie die gewünschte Löschoption aus:
- Nie: Es werden nach Übertragungen nie Dateien gelöscht (empfohlen für Tests).
- Übertragene Dateien löschen: Dateien werden nach der erfolgreichen Übertragung gelöscht.
Übertragene Dateien und leere Verzeichnisse löschen: Löscht Dateien und leere Verzeichnisse nach der erfolgreichen Übertragung.
Höchstalter für Dateien: Dateien einschließen, die in den letzten Tagen geändert wurden (Standardwert: 180 Tage).
Asset-Namespace: Der Asset-Namespace.
Aufnahmelabels: Das Label, das auf die Ereignisse aus diesem Feed angewendet werden soll.
Klicken Sie auf Weiter.
Prüfen Sie die neue Feedkonfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.
Dem Google SecOps-Dienstkonto IAM-Berechtigungen gewähren
Das Google SecOps-Dienstkonto benötigt die Rolle Storage-Objekt-Betrachter für Ihren GCS-Bucket.
- Rufen Sie Cloud Storage > Buckets auf.
- Klicken Sie auf den Bucket-Namen (
fsf-logs-secops). - Wechseln Sie zum Tab Berechtigungen.
- Klicken Sie auf Zugriff erlauben.
- Geben Sie die folgenden Konfigurationsdetails an:
- Hauptkonten hinzufügen: Fügen Sie die E‑Mail-Adresse des Google SecOps-Dienstkontos ein.
- Rollen zuweisen: Wählen Sie Storage-Objekt-Betrachter aus.
- Klicken Sie auf Speichern.
Aufnahme überprüfen
- Warten Sie 10 bis 15 Minuten, bis die erste Aufnahme abgeschlossen ist.
- Rufen Sie in Google SecOps die SIEM-Einstellungen > Feeds auf.
- Suchen Sie den Feed (
FSF File Scanning Logs). - Prüfen Sie, ob der Status als Aktiv angezeigt wird.
- Klicken Sie auf den Feednamen, um die Messwerte für die Aufnahme aufzurufen.
- Prüfen Sie, ob die Anzahl der aufgenommenen Ereignisse zunimmt.
- Rufen Sie in Google SecOps die Suche auf.
Führen Sie eine Suchanfrage aus, um zu prüfen, ob FSF-Logs aufgenommen werden:
metadata.log_type = "FILE_SCANNING_FRAMEWORK"Prüfen Sie, ob die FSF-Scanergebnisse in den Suchergebnissen angezeigt werden.
Fehlerbehebung
In GCS werden keine Logs angezeigt
Prüfen Sie, ob FSF Protokolle in
/var/log/fsf/schreibt:ls -lh /var/log/fsf/ tail -f /var/log/fsf/*.logPrüfen Sie die Fluentd-Logs auf Fehler:
sudo tail -f /var/log/td-agent/td-agent.logPrüfen Sie, ob der GCP-Dienstkontoschlüssel gültig ist und die richtigen Berechtigungen hat.
Prüfen Sie, ob der Bucket-Name in der Fluentd-Konfiguration mit dem tatsächlichen Bucket-Namen übereinstimmt.
Fluentd-Berechtigungsfehler
- Prüfen Sie, ob das Dienstkonto (
fsf-fluentd-shipper) die Rolle Storage-Objekt-Administrator für den Bucket hat. - Prüfen Sie, ob der Schlüsselpfad in der Fluentd-Konfiguration korrekt ist.
Prüfen Sie, ob die Schlüsseldatei den richtigen Eigentümer und die richtigen Berechtigungen hat:
ls -l /etc/td-agent/gcp-key.json
Google SecOps nimmt keine Logs auf
- Prüfen Sie, ob das Google SecOps-Dienstkonto die Rolle Storage-Objekt-Betrachter für den Bucket hat.
- Prüfen Sie, ob der Bucket-URI in der Feedkonfiguration korrekt ist und den abschließenden Schrägstrich enthält.
- Prüfen Sie, ob Dateien im GCS-Bucket unter dem angegebenen Präfixpfad vorhanden sind.
- Prüfen Sie den Feedstatus in den SIEM-Einstellungen > Feeds auf Fehlermeldungen.
FSF-Logs nicht im erwarteten Format
- Prüfen Sie, ob FSF für das Schreiben von JSON-Ausgabe konfiguriert ist (Standardverhalten).
- Prüfen Sie, ob der Fluentd-Abschnitt
<parse>mit@type jsonkonfiguriert ist. So prüfen Sie eine Protokolldatei manuell, um festzustellen, ob sie gültiges JSON enthält:
head -n 1 /var/log/fsf/*.log | jq .
UDM-Zuordnungstabelle
| Logfeld | UDM-Zuordnung | Logik |
|---|---|---|
| CompressType_label, compressed_parents | about.labels | Zusammengeführt aus CompressType_label (Schlüssel „Compress Type“, Wert aus Object.EXTRACT_ZIP.Object_0.Compress Type, wenn die Nachricht „Compress Type“ enthält) und compressed_parents (Schlüssel „Compressed Parent Files“, verkettet aus Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.additional_info.compressed_parents) |
| Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.MD5, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.MD5, Object.EXTRACT_SWF.META_BASIC_INFO.MD5, Object.EXTRACT_GZIP.META_BASIC_INFO.MD5, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.MD5 | intermediary.file.md5 | Wert aus Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.MD5, falls EXTRACT_EMBEDDED vorhanden ist, andernfalls Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.MD5, falls EXTRACT_ZIP vorhanden ist, andernfalls Object.EXTRACT_SWF.META_BASIC_INFO.MD5, falls EXTRACT_SWF vorhanden ist, andernfalls Object.EXTRACT_GZIP.META_BASIC_INFO.MD5, falls EXTRACT_GZIP vorhanden ist, andernfalls Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.MD5 |
| Object.EXTRACT_EMBEDDED.Object_0.Description | intermediary.file.mime_type | Wert direkt kopiert |
| Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA1, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA1, Object.EXTRACT_SWF.META_BASIC_INFO.SHA1, Object.EXTRACT_GZIP.META_BASIC_INFO.SHA1, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA1 | intermediary.file.sha1 | Wert aus Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA1, falls EXTRACT_EMBEDDED vorhanden ist, andernfalls Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA1, falls EXTRACT_ZIP vorhanden ist, andernfalls Object.EXTRACT_SWF.META_BASIC_INFO.SHA1, falls EXTRACT_SWF vorhanden ist, andernfalls Object.EXTRACT_GZIP.META_BASIC_INFO.SHA1, falls EXTRACT_GZIP vorhanden ist, andernfalls Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA1 |
| Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA256, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA256, Object.EXTRACT_SWF.META_BASIC_INFO.SHA256, Object.EXTRACT_GZIP.META_BASIC_INFO.SHA256, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA256 | intermediary.file.sha256 | Wert aus Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA256, falls EXTRACT_EMBEDDED vorhanden ist, andernfalls Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA256, falls EXTRACT_ZIP vorhanden ist, andernfalls Object.EXTRACT_SWF.META_BASIC_INFO.SHA256, falls EXTRACT_SWF vorhanden ist, andernfalls Object.EXTRACT_GZIP.META_BASIC_INFO.SHA256, falls EXTRACT_GZIP vorhanden ist, andernfalls Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA256 |
| Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.Size, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.Size, Object.EXTRACT_SWF.META_BASIC_INFO.Size, Object.EXTRACT_GZIP.META_BASIC_INFO.Size, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.Size | intermediary.file.size | Wert aus Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.Size, falls EXTRACT_EMBEDDED vorhanden ist, andernfalls Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.Size, falls EXTRACT_ZIP vorhanden ist, andernfalls Object.EXTRACT_SWF.META_BASIC_INFO.Size, falls EXTRACT_SWF vorhanden ist, andernfalls Object.EXTRACT_GZIP.META_BASIC_INFO.Size, falls EXTRACT_GZIP vorhanden ist, andernfalls Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.Size; ohne nachgestelltes „ .*“ und in uinteger konvertiert |
| Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.scan_id | intermediary.resource.id | Wert direkt kopiert |
| Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.permalink | intermediary.url | Wert direkt kopiert |
| Object.META_EMERSON_INFO.results | intermediary.user.email_addresses | Zusammengeführt aus „matched_email“ im Ergebnis-Array |
| Summary.Observations | metadata.description | Verkettet aus Array mit dem Trennzeichen „, “, führendes Komma entfernt |
| Scanzeit | metadata.event_timestamp | Konvertiert mit Datumsfilter im Format JJJJ-MM-TT HH:MM:SS |
| Quelle | metadata.event_type | Auf „SCAN_FILE“ festgelegt, wenn „Source“ nicht leer ist, andernfalls „GENERIC_EVENT“ |
| Object.META_VT_CACHE._id | metadata.product_log_id | Wert direkt kopiert |
| result.ad_data.message | network.http.response_code | Als Ganzzahl mit dem Grok-Muster INT aus „result.ad_data.message“ extrahiert |
| Quelle | principal.hostname | Wert direkt kopiert |
| Object.META_EMERSON_INFO.result_summary, Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.verbose_msg | security_result.summary | Auf Object.META_EMERSON_INFO.result_summary festlegen, falls vorhanden, andernfalls auf Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.verbose_msg. |
| Dateiname | target.file.full_path | Wert direkt kopiert |
| Object.META_BASIC_INFO.MD5 | target.file.md5 | Wert direkt kopiert |
| Summary.Yara | target.file.mime_type | Aus dem ersten Index von Summary.Yara extrahiert, in Großbuchstaben umgewandelt und „FT_“ entfernt, falls Yara vorhanden ist. Andernfalls wird „ZIP“ festgelegt, falls EXTRACT_ZIP vorhanden ist, „SWF“, falls EXTRACT_SWF vorhanden ist, „GZIP“, falls EXTRACT_GZIP vorhanden ist, und „CAB“, falls EXTRACT_CAB vorhanden ist. |
| Object.META_BASIC_INFO.SHA1, Object.META_VT_CACHE.SHA1 | target.file.sha1 | Wert aus Object.META_BASIC_INFO.SHA1, falls nicht leer, andernfalls Object.META_VT_CACHE.SHA1 |
| Object.META_BASIC_INFO.SHA256 | target.file.sha256 | Wert direkt kopiert |
| Object.META_BASIC_INFO.Size | target.file.size | Das nachgestellte „ .*“ wurde entfernt und in „uinteger“ konvertiert. |
| metadata.vendor_name | Auf „EMERSON“ festgelegt | |
| metadata.product_name | Auf „FILE SCANNING FRAMEWORK“ festgelegt |
Benötigen Sie weitere Hilfe? Antworten von Community-Mitgliedern und Google SecOps-Experten erhalten