Fastly-WAF-Protokolle erfassen
Übersicht
Dieser Parser extrahiert Felder aus Fastly-WAF-JSON-Logs, transformiert und benennt sie um und ordnet sie dem UDM zu. Er verarbeitet verschiedene Datentypen, wandelt Schweregrade um und kategorisiert Ereignisse anhand der verfügbaren IP- und Hostnameninformationen. Außerdem werden potenzielle Parsefehler behoben und fehlerhafte Logeinträge gelöscht.
Hinweise
- Sie benötigen eine Google SecOps-Instanz.
- Ein Fastly-Konto mit Zugriff auf die WAF-Einstellungen.
Feed in Google SecOps für die Aufnahme der Fastly-WAF-Logs konfigurieren
- Gehen Sie zu SIEM-Einstellungen > Feeds.
- Klicken Sie auf Neu hinzufügen.
- Geben Sie im Feld Feedname einen Namen für den Feed ein, z. B. Fastly-WAF-Logs.
- Wählen Sie als Quelltyp Webhook aus.
- Wählen Sie Fastly WAF als Logtyp aus.
- Klicken Sie auf Weiter.
- Optional: Geben Sie Werte für die folgenden Eingabeparameter an:
- Trennzeichen für die Aufteilung: Das Trennzeichen, mit dem Logzeilen getrennt werden, z. B.
\n
. - Asset-Namespace: der Asset-Namespace.
- Aufnahmelabels: Das Label, das auf die Ereignisse aus diesem Feed angewendet wird.
- Trennzeichen für die Aufteilung: Das Trennzeichen, mit dem Logzeilen getrennt werden, z. B.
- Klicken Sie auf Weiter.
- Überprüfen Sie die Feedkonfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.
- Klicken Sie auf Secret-Schlüssel generieren, um einen Secret-Schlüssel zur Authentifizierung dieses Feeds zu generieren.
- Kopieren und speichern Sie den geheimen Schlüssel. Sie können sich diesen geheimen Schlüssel nicht noch einmal ansehen. Bei Bedarf können Sie einen neuen Secret-Schlüssel generieren. Dadurch wird der vorherige Secret-Schlüssel jedoch ungültig.
- Kopieren Sie auf dem Tab Details die Feedendpunkt-URL aus dem Feld Endpunktinformationen. Sie müssen diese Endpunkt-URL in Ihrer Clientanwendung angeben.
- Klicken Sie auf Fertig.
API-Schlüssel für den Webhook-Feed erstellen
Rufen Sie die Google Cloud Console > Anmeldedaten auf.
Klicken Sie auf Anmeldedaten erstellen und wählen Sie anschließend API-Schlüssel aus.
Beschränken Sie den API-Schlüsselzugriff auf die Google Security Operations API.
Endpunkt-URL angeben
- Geben Sie in Ihrer Clientanwendung die HTTPS-Endpunkt-URL an, die im Webhook-Feed angegeben ist.
Aktiviere die Authentifizierung, indem du den API-Schlüssel und den geheimen Schlüssel als Teil der benutzerdefinierten Kopfzeile im folgenden Format angibst:
X-goog-api-key = API_KEY X-Webhook-Access-Key = SECRET
Empfehlung: Geben Sie den API-Schlüssel als Header an, anstatt ihn in der URL anzugeben.
Wenn Ihr Webhook-Client keine benutzerdefinierten Header unterstützt, können Sie den API-Schlüssel und den geheimen Schlüssel mithilfe von Suchparametern im folgenden Format angeben:
ENDPOINT_URL?key=API_KEY&secret=SECRET
Ersetzen Sie Folgendes:
ENDPOINT_URL
: die URL des Feedendpunkts.API_KEY
: Der API-Schlüssel, mit dem Sie sich bei Google Security Operations authentifizieren.SECRET
: der geheime Schlüssel, den Sie zur Authentifizierung des Feeds generiert haben.
Webhook in Fastly konfigurieren
- Melden Sie sich in Fastly an.
- Optional: Wählen Sie im Menü Websites eine Website aus, falls Sie mehrere haben.
- Wählen Sie Verwalten > Websiteintegrationen aus.
- Klicken Sie auf Websiteintegration hinzufügen.
- Wählen Sie Generischer Webhook aus.
- Webhook-URL: Geben Sie die ENDPOINT_URL von Google SecOps gefolgt von API_KEY und SECRET ein.
- Platzierung der Benachrichtigung: Wählen Sie Alle Aktivitäten oder Bestimmte Aktivitäten aus.
- Optional: Wenn Sie Bestimmte Aktivität ausgewählt haben, rufen Sie das Menü „Aktivität“ auf und wählen Sie die Aktivitätstypen aus, die der Webhook senden soll.
- Klicken Sie auf Website-Einbindung erstellen.
UDM-Zuordnungstabelle
Logfeld | UDM-Zuordnung | Logik |
---|---|---|
anomaly_score |
security_result.detection_fields[].key : „anomaly“security_result.detection_fields[].value : anomaly_score |
Wenn waf.score.anomaly = 0 oder leer ist und anomaly_score nicht leer oder 0 ist, wird der Wert von anomaly_score verwendet, um das Array security_result.detection_fields mit dem Schlüssel „Anomalie“ und dem Wert des Felds anomaly_score zu füllen. |
cache_status |
additional.fields[].key : „cache_status“additional.fields[].value.string_value : cache_status |
Der Wert cache_status wird verwendet, um das Array additional.fields mit dem Schlüssel „cache_status“ und dem Wert des Felds cache_status zu füllen. |
client_ip |
principal.ip : client_ip |
Das Feld client_ip ist principal.ip zugeordnet. |
connection.fastly_is_edge |
additional.fields[].key : „fastly_is_edge“additional.fields[].value.bool_value : connection.fastly_is_edge |
Mit dem Wert connection.fastly_is_edge wird das Array additional.fields mit dem Schlüssel „fastly_is_edge“ und dem Wert des Felds connection.fastly_is_edge gefüllt. |
connection.fastly_is_shield |
additional.fields[].key : „fastly_is_shield“additional.fields[].value.bool_value : connection.fastly_is_shield |
Der Wert connection.fastly_is_shield wird verwendet, um das Array additional.fields mit dem Schlüssel „fastly_is_shield“ und dem Wert des Felds connection.fastly_is_shield zu füllen. |
connection.request_tls_version |
network.tls.version : connection.request_tls_version |
Das Feld connection.request_tls_version ist network.tls.version zugeordnet. |
fastly.server |
target.hostname : fastly.server |
Das Feld fastly.server ist target.hostname zugeordnet. |
fastly.service_id |
additional.fields[].key : „service_id“additional.fields[].value.string_value : fastly.service_id |
Der Wert fastly.service_id wird verwendet, um das additional.fields -Array mit dem Schlüssel „service_id“ und dem Wert des Felds fastly.service_id zu füllen. |
geo.city |
principal.location.city : geo.city |
Das Feld geo.city ist principal.location.city zugeordnet. |
geo.country |
principal.location.country_or_region : geo.country |
Das Feld geo.country ist principal.location.country_or_region zugeordnet. |
geo.location |
principal.location.region_latitude : aus geo.location extrahiert principal.location.region_longitude : aus geo.location extrahiert |
Breiten- und Längengrad werden mit einem regulären Ausdruck aus dem Feld geo.location extrahiert und jeweils principal.location.region_latitude und principal.location.region_longitude zugeordnet. |
geo.region |
principal.location.state : geo.region |
Das Feld geo.region ist principal.location.state zugeordnet. |
host |
principal.hostname : host |
Das Feld host ist principal.hostname zugeordnet. |
request_headers.accept_charset |
additional.fields[].key : „accept_charset“additional.fields[].value.string_value : request_headers.accept_charset |
Der Wert request_headers.accept_charset wird verwendet, um das additional.fields -Array mit dem Schlüssel „accept_charset“ und dem Wert des Felds request_headers.accept_charset zu füllen. |
request_headers.accept_language |
additional.fields[].key : „accept_language“additional.fields[].value.string_value : request_headers.accept_language |
Mit dem Wert request_headers.accept_language wird das Array additional.fields mit dem Schlüssel „accept_language“ und dem Wert des Felds request_headers.accept_language gefüllt. |
request_headers.referer |
network.http.referral_url : request_headers.referer |
Das Feld request_headers.referer ist network.http.referral_url zugeordnet. |
request_headers.user_agent |
network.http.user_agent : request_headers.user_agent |
Das Feld request_headers.user_agent ist network.http.user_agent zugeordnet. |
request_id |
metadata.product_log_id : request_id |
Das Feld request_id ist metadata.product_log_id zugeordnet. |
request_method |
network.http.method : request_method |
Das Feld request_method ist network.http.method zugeordnet. |
response_headers.cache_control |
additional.fields[].key : „cache_control“additional.fields[].value.string_value : response_headers.cache_control |
Der Wert response_headers.cache_control wird verwendet, um das additional.fields -Array mit dem Schlüssel „cache_control“ und dem Wert des Felds response_headers.cache_control zu füllen. |
response_headers.content_type |
additional.fields[].key : „content_type“additional.fields[].value.string_value : response_headers.content_type |
Mit dem Wert response_headers.content_type wird das additional.fields -Array mit dem Schlüssel „content_type“ und dem Wert des response_headers.content_type -Felds gefüllt. |
response_state |
additional.fields[].key : „response_state“additional.fields[].value.string_value : response_state |
Mit dem Wert response_state wird das Array additional.fields mit dem Schlüssel „response_state“ und dem Wert des Felds response_state gefüllt. |
response_status |
network.http.response_code : response_status |
Das Feld response_status wird network.http.response_code zugeordnet, wenn das Feld status leer ist. |
rule_id |
security_result.rule_id : rule_id |
Wenn waf.rule_id leer ist, wird der Wert rule_id verwendet, um security_result.rule_id zu füllen. |
severity |
waf.severity : severity |
Der Wert des Felds severity wird in waf.severity kopiert. |
size_bytes.request_header |
network.sent_bytes : size_bytes.request_header |
Das Feld size_bytes.request_header ist network.sent_bytes zugeordnet. |
size_bytes.response_header |
network.received_bytes : size_bytes.response_header |
Das Feld size_bytes.response_header ist network.received_bytes zugeordnet. |
status |
network.http.response_code : status |
Das Feld status ist network.http.response_code zugeordnet. |
timestamp |
metadata.event_timestamp : timestamp |
Das Feld timestamp wird analysiert und metadata.event_timestamp zugeordnet. |
url |
target.url : url |
Das Feld url ist target.url zugeordnet. |
waf.blocked |
security_result.action : abgeleitet |
Wenn waf.blocked auf „false“ gesetzt ist, wird security_result.action auf „ALLOW“ (ZULASSEN) gesetzt. Wenn waf.blocked wahr ist, wird security_result.action auf „BLOCK“ gesetzt. |
waf.executed |
security_result.detection_fields[].key : „executed“security_result.detection_fields[].value : waf.executed |
Mit dem Wert waf.executed wird das Array security_result.detection_fields mit dem Schlüssel „executed“ und dem Wert des Felds waf.executed gefüllt. |
waf.failures |
security_result.detection_fields[].key : „failures“security_result.detection_fields[].value : waf.failures |
Mit dem Wert waf.failures wird das security_result.detection_fields -Array mit dem Schlüssel „failures“ und dem Wert des waf.failures -Felds gefüllt. |
waf.logged |
security_result.detection_fields[].key : „logged“security_result.detection_fields[].value : waf.logged |
Der Wert waf.logged wird verwendet, um das security_result.detection_fields -Array mit dem Schlüssel „geloggt“ und dem Wert des waf.logged -Felds zu füllen. |
waf.message |
metadata.description : waf.message |
Wenn waf.message nicht leer ist, wird es metadata.description zugeordnet. |
waf.rule_id |
security_result.rule_id : waf.rule_id |
Wenn waf.rule_id nicht leer ist, wird es security_result.rule_id zugeordnet. |
waf.score.anomaly |
security_result.detection_fields[].key : „anomaly“security_result.detection_fields[].value : waf.score.anomaly |
Wenn waf.score.anomaly nicht 0 und nicht leer ist, wird der Wert verwendet, um das security_result.detection_fields -Array mit dem Schlüssel „anomaly“ und dem Wert des waf.score.anomaly -Felds zu füllen. |
waf.score.http_violation |
security_result.detection_fields[].key : „http_violation“security_result.detection_fields[].value : waf.score.http_violation |
Wenn waf.score.http_violation nicht 0 und nicht leer ist, wird der Wert verwendet, um das security_result.detection_fields -Array zu füllen. |
waf.score.lfi |
security_result.detection_fields[].key : „lfi“security_result.detection_fields[].value : waf.score.lfi |
Ähnliche Logik wie bei waf.score.http_violation . |
waf.score.php_injection |
security_result.detection_fields[].key : „php_injection“security_result.detection_fields[].value : waf.score.php_injection |
Ähnliche Logik wie bei waf.score.http_violation . |
waf.score.rce |
security_result.detection_fields[].key : „rce“security_result.detection_fields[].value : waf.score.rce |
Ähnliche Logik wie bei waf.score.http_violation . |
waf.score.rfi |
security_result.detection_fields[].key : „rfi“security_result.detection_fields[].value : waf.score.rfi |
Ähnliche Logik wie bei waf.score.http_violation . |
waf.score.session_fixation |
security_result.detection_fields[].key : „session_fixation“security_result.detection_fields[].value : waf.score.session_fixation |
Ähnliche Logik wie bei waf.score.http_violation . |
waf.score.sql_injection |
security_result.detection_fields[].key : „sql_injection“security_result.detection_fields[].value : waf.score.sql_injection |
Ähnliche Logik wie bei waf.score.http_violation . |
waf.score.xss |
security_result.detection_fields[].key : „xss“security_result.detection_fields[].value : waf.score.xss |
Ähnliche Logik wie bei waf.score.http_violation . |
waf.severity |
security_result.severity : abgeleitetsecurity_result.severity_details : waf.severity |
Wenn waf.severity nicht leer ist, wird der Wert von security_result.severity anhand von Bereichen bestimmt: <=3: HOCH, > 3 und <=6: MITTEL, > 6 und <=8: NIEDRIG, andernfalls UNKNOWN_SEVERITY. Der ursprüngliche waf.severity -Wert wird ebenfalls security_result.severity_details zugeordnet. |
waf_message |
metadata.description : waf_message |
Wenn waf.message leer ist und waf_message nicht leer ist, wird waf_message auf metadata.description zugeordnet. Wenn client_ip oder host und fastly.server nicht leer sind, wird metadata.event_type auf „NETWORK_HTTP“ gesetzt. Andernfalls, wenn client_ip oder host nicht leer sind, wird metadata.event_type auf „STATUS_UPDATE“ gesetzt. Andernfalls wird „GENERIC_EVENT“ verwendet. Hartcodierter Wert. Hartcodierter Wert. Hartcodierter Wert. |
Änderungen
2022-06-06
- Neu erstellter Parser.