Direkt zum Inhalt

Wie analysiere ich AWS-WAF-Protokolle in CloudWatch?

Lesedauer: 7 Minute
0

Ich möchte meine AWS-WAF-Protokolle, die ich in Amazon CloudWatch speichere, analysieren und filtern.

Lösung

Verwende CloudWatch Logs Insights oder den CloudWatch-Abfragegenerator, um bestimmte AWS-WAF-Protokollanfragen in CloudWatch zu analysieren und zu filtern.

Verwendung von CloudWatch Log Insights

Du kannst CloudWatch Log Insights in der CloudWatch-Konsole oder in der AWS-WAF-Konsole verwenden.

AWS-WAF-Konsole

Gehe wie folgt vor:

  1. Öffne die AWS-WAF-Konsole.
  2. Wähle im Navigationsbereich Protection packs (web ACLs) (Schutzpakete (Web-ACLs)) aus.
  3. Wähle dein Schutzpaket aus.
  4. Wähle View dashboard, logs and sampled requests (Dashboard, Protokolle und Stichprobenanforderungen anzeigen).
  5. Wähle im Log explorer (Protokoll-Explorer) die Option View in CloudWatch (In CloudWatch anzeigen) aus.
  6. Gib im Query Editor die Abfrage ein. Verwende query syntax (Syntax abfragen), um die Abfragen zu entwerfen. Du kannst auch Abfragen aus der Liste der Most frequently used queries (Am häufigsten verwendete Abfragen) auswählen.
  7. Wähle Run query (Abfrage ausführen) aus.

CloudWatch-Konsole

Gehe wie folgt vor:

  1. Öffne die CloudWatch-Konsole.
  2. Wähle im Navigationsbereich unter Logs (Protokolle) die Option Log Insights (Einblicke protokollieren) aus.
  3. Wähle für Selection criteria (Auswahlkriterien) eine oder mehrere Protokollgruppen für die Abfrage aus. Oder wähle Browse log groups (Protokollgruppen durchsuchen) und dann deine Protokollgruppe aus.
  4. (Optional) Wähle einen Zeitraum für die Abfrage aus.
  5. Verwende query syntax (Syntax abfragen), um die Abfragen zu entwerfen.
  6. Wähle Run query (Abfrage ausführen) aus, um die Ergebnisse anzuzeigen.

Verwendung des CloudWatch-Abfragegenerators

Um Abfragen in natürlicher Sprache zu generieren und die Zugriffsprotokolle zu analysieren, führe den Abfragegenerator in CloudWatch aus.

Beispielabfragen 

Verwende die folgenden Beispielabfragen, um bestimmte Informationen mit CloudWatch Logs Insights herauszufiltern.

Die häufigsten Client-IP-Adressen

Führe die folgende Abfrage aus, um die häufigsten Client-IP-Adressen zu zählen, die auf deine Anwendung zugreifen:

stats count(*) as requestCount by httpRequest.clientIp
| sort requestCount desc

Die häufigsten Länder

Führe die folgende Abfrage aus, um die häufigsten Quellländer zu zählen, die Anfragen an deine Anwendung stellen:

stats count(*) as RequestCount by httpRequest.country as Country
| sort RequestCount desc

Die häufigsten HTTP-Methoden

Führe die folgende Abfrage aus, um die häufigsten HTTP-Methoden zu zählen, die auf deine Anwendung zugreifen:

stats count(*)as RequestCount by httpRequest.httpMethod as Method
| sort RequestCount desc

Die häufigsten Beendigungsregeln

Führe die folgende Abfrage aus, um die häufigsten Beendigungsregeln in den Protokollen zu zählen:

stats count(*) as RequestCount by terminatingRuleId
| sort RequestCount desc

Die häufigsten Hosts

Führe die folgende Abfrage aus, um die häufigsten Hosts zu zählen, die auf deine Anwendung zugreifen:

parse @message /\{"name":"[Hh]ost","value":"(?<Host>[^"]*)"/
| stats count(*) as RequestCount by Host
| sort RequestCount desc

Die häufigsten Benutzeragenten

Führe die folgende Abfrage aus, um die häufigsten Benutzeragenten zu zählen, die auf deine Anwendung zugreifen:

parse @message /\{"name":"[Uu]ser\-[Aa]gent","value":"(?<UserAgent>[^"]*)"/  
| stats count(*) as RequestCount by UserAgent
| sort RequestCount desc

Die häufigsten weitergeleiteten IP-Adressen

Führe die folgende Abfrage aus, um die häufigsten XFF-IP-Adressen zu zählen, die Anfragen an deine Anwendung stellen:

parse @message /\{"name":"[Xx]-[Ff]orwarded-[Ff]or","value":"(?<XFF_IP>[^"}]*)/
| stats count(*) as RequestCount by XFF
| sort RequestCount desc

Die häufigsten IP-Adressen, die durch eine ratenbasierte Regel blockiert wurden

Führe die folgende Abfrage aus, um IP-Adressen zu finden, die den Schwellenwert überschreiten, und im Fall von HTTP-Flood DDoS:

fields httpRequest.clientIp
| filter terminatingRuleType = "RATE_BASED" ## and webaclId = "<Webacl ARN>" ## uncomment to filter for specific WebACL|
| stats count(*) as requestCount by httpRequest.clientIp, httpRequest.country
| sort requestCount desc
| limit 100

Nach blockierten Anfragen filtern

Führe die folgende Abfrage aus, um nach allen blockierten Anfragen und deren Beendigungsregel, URI-Pfad und Client-IP zu filtern:

fields @timestamp, httpRequest.clientIp as ClientIP, httpRequest.uri as URI, terminatingRuleId as rule
| filter action = "BLOCK"
| sort @timestamp desc

Nach Host filtern

Führe die folgende Abfrage aus, um die Protokolle nach einem bestimmten Host zu filtern:

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.uri as URI
| parse @message /\{"name":"[Hh]ost","value":"(?<Host>[^"]*)"/  
| filter Host = "www.example.com"

Hinweis: Ersetze www.example.com durch den Namen des Hosts.

Nach einer bestimmten Zeichenfolge filtern

Führe die folgende Abfrage aus, um die Protokolle nach einer bestimmten Zeichenfolge zu filtern:

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.httpMethod as Method,httpRequest.uri as URI
| parse @message /\{"name":"[Hh]ost","value":"(?<Host>[^"]*)"/
| parse @message /\{"name":"[Uu]ser\-[Aa]gent","value":"(?<UserAgent>[^"]*)"/  
| filter @message like "{jndi:ldap"
| sort action, URI desc

Hinweis: Ersetze {jndi:ldap durch deine Zeichenfolge.

Nach POST-Anfragen filtern

Führe die folgende Anfrage aus, um nach POST-Abfragen zu filtern:

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.httpMethod as Method, httpRequest.uri as URI
| parse @message /\{"name":"[Uu]ser\-[Aa]gent","value":"(?<UserAgent>[^"]*)"/  
| parse @message /\{"name":"[Hh]ost","value":"(?<Host>[^"]*)"/  
| filter httpRequest.httpMethod ="POST"
| display Rule, action, Country, ClientIP, Method, URI, Host, UserAgent
| sort Rule, action desc

HINWEIS: Du kannst die vorherige Abfrage verwenden, um nach anderen HTTP-Methoden zu filtern. Ersetze POST durch GET, Head oder andere HTTP-Methoden.

XSS- oder SQL-Injektion

Führe die folgende Abfrage aus, um Muster zu finden, die Cross-Site-Scripting (XSS) oder SQL-Injektion in der Beendigungsregel für benutzerdefinierte Regeln oder von AWS verwaltete Regelgruppen verursachen:

fields @timestamp  
| parse @message ',"terminatingRuleMatchDetails":[*],' as terminatingRuleMatchData  
| filter (terminatingRuleMatchData like /XSS/ or terminatingRuleMatchData like /SQL/)  
| display @timestamp, httpRequest.clientIp, httpRequest.country, terminatingRuleMatchData, httpRequest.requestId

Die Abfrage zeigt Einträge mit einem Zeitstempel, einer Client-IP-Adresse, einem Ursprungsland, Übereinstimmungsdetails und der Anfragen-ID.

Nach Land filtern

Führe die folgende Abfrage aus, um Anfragen herauszufiltern, die nicht aus einem bestimmten Land stammen:

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.uri as URI
| parse @message /\{"name":"[Uu]ser\-[Aa]gent","value":"(?<UserAgent>[^"]*)"/  
| parse @message /\{"name":"[Hh]ost","value":"(?<Host>[^"]*)"/
| filter Country != "US"
| sort Country, action desc

Hinweis: Ersetze US durch die Landesvorwahl, die du herausfiltern möchtest.

Nach Anfragen filtern, die nach einer bestimmten Regel in einer Regelgruppe gezählt wurden

Führe die folgende Abfrage aus, um Protokolleinträge nach Anfragen zu filtern, die eine bestimmte Regel in einer Regelgruppe standardmäßig zählt und beendet:

fields @timestamp
| filter (@message like 'excludedRules":[{"exclusionType":"EXCLUDED_AS_COUNT","ruleId":"NoUserAgent_HEADER"}]}' and @message like 'terminatingRuleId":"Default_Action"')
| parse @message '"ruleId":*}]}' as ruleMatchDetails
| display @timestamp, httpRequest.clientIp, httpRequest.country, ruleMatchDetails, httpRequest.requestId

Hinweis: Ersetze ruleId durch deine Regel-ID.

Nach Anfragen mit einem CAPTCHA filtern, der nicht gültig ist

Führe die folgende Abfrage aus, um nach den 100 häufigsten Anfragen mit einem ungültigen CAPTCHA zu filtern:

fields @timestamp, httpRequest.clientIp, httpRequest.requestId, captchaResponse.failureReason, @message
| filter captchaResponse.failureReason ='TOKEN_MISSING'
| sort @timestamp desc| limit 100

Hinweis: Ersetze 100 in der limit-Klausel durch die Anzahl der Anfragen, nach denen du filtern möchtest.

Diese Abfrage zeigt den Zeitpunkt der Anfrage, die IP-Adresse, die Anfragen-ID, den Antwortcode und die gesamte Nachricht.

**Alle Anfragen filtern, die von von AWS verwalteten ABC-, ATP-, ACFP- und AntiDDOS-Regeln erkannt wurden **

Führe die folgende Abfrage aus, um die 100 häufigsten Anfragen zu filtern, die den von AWS verwalteten Regelbezeichnungen ABC, ATP, ACFP oder AntiDDoS entsprechen:

fields @timestamp
| filter @message like 'awswaf:managed:aws:bot-control'
| display @timestamp,httpRequest.clientIp, httpRequest.uri,Labels, @message
| sort @timestamp desc
| limit 100

Hinweis: Ersetze 100 in der limit-Klausel durch die Anzahl der Anfragen, nach denen du filtern möchtest. Ersetze awswaf:managed:aws:bot-control durch die Bezeichnung der Regelgruppe. Verwende für die ATP-Regelgruppe awswaf:managed:aws:atp. Verwende für die ACFP-Regelgruppe awswaf:managed:aws:acfp. Verwende für die AntiDDOS AMR-Regelgruppe awswaf:managed:aws:anti-ddos.

Um die Protokolle mit einer bestimmten Bezeichnung zu filtern, füge die folgende Zeile in die vorherige Abfrage ein:

| filter @message like 'awswaf:managed:aws:bot-control:signal:non_browser_user_agent'