Firewall events script

I’ve been trying to refine my firewall rules, and have the same question many others have posted: “How can I tell which requests solved a Challenge?”

GraphQL for Firewall Events keeps track of that. With much help from @cbrandt’s tutorial, I started on a script a long time ago to export Firewall Events as a CSV, and have now refined it to export requests that passed Challenge.

Assuming your device has a /tmp directory you can write to, all that’s left to add are a Token and Output file. The script will query the API to get all your zones, then use GraphQL to export all matching events:

#!/bin/bash

## Beginning of setup - assumes you have write access to /tmp ##

# Token for zone list and firewall events
# Only needs Analytics:Read permission for all zones
token="YOUR_TOKEN"

# egrep list of hostnames to exclude from CSV
badhosts="DOMAIN_1|DOMAIN_2"

# Final output file
savefile="/FULL_PATH/FILENAME.csv"

## End of setup ##

# Add headings to new CSV

echo "Host, Date/Time, Action, ASN, Country, IP, HTTP, ReqPath, Query String, Scheme, Referer, RefPath, Source, RuleID, User Agent" > $savefile

# Get Zone list

curl -sX GET "https://api.cloudflare.com/client/v4/zones/?per_page=50" -H "Authorization: Bearer $token" -H "Content-Type: application/json" | jq -r .result[].id > /tmp/zones.txt

## Get filtered firewall events for each zone ##

# Set up query

for zone in `cat /tmp/zones.txt`
do
DATENOW=`date -u +"%Y-%m-%dT%H:%M:%SZ"` # Current Date and Time
DATETHEN=`date -v -1d -u +"%Y-%m-%dT%H:%M:%SZ"` # 24 Hours Earlier
PAYLOAD='{ "query":
  "query ListFirewallEvents($zoneTag: string, $filter: FirewallEventsAdaptiveFilter_InputObject) {
      viewer {
        zones(filter: { zoneTag: $zoneTag }) {
          firewallEventsAdaptive(
            filter: $filter
            limit: 100
            orderBy: [datetime_DESC]
          ) {
            clientRequestHTTPHost
            datetime
            action
            clientAsn
            clientCountryName
            clientIP
            clientRequestHTTPProtocol
            clientRequestPath
            clientRequestQuery
            clientRefererScheme
            clientRefererHost
            clientRefererPath
            source
	        ruleId
            userAgent
          }
        }
      }
    }",
    "variables": {
      "zoneTag": "'"$zone"'",
      "filter": {
        "datetime_geq": "'"$DATETHEN"'",
        "datetime_leq": "'"$DATENOW"'",
        "action_in": [
          "challenge_solved",
          "challenge_bypassed",
          "js_challenge_solved",
          "js_challenge_bypassed",
          "managed_challenge_non_interactive_solved",
          "managed_challenge_interactive_solved",
          "managed_challenge_bypassed"
        ]
      }
    }
  }'

# Query GraphQL and add to /tmp CSV file

curl \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $token" \
  --data "$(echo $PAYLOAD)" \
  https://api.cloudflare.com/client/v4/graphql/ \
  | jq -r '.data.viewer.zones[].firewallEventsAdaptive[] | [.clientRequestHTTPHost, .datetime, .action, .clientAsn, .clientCountryName, .clientIP, .clientRequestHTTPProtocol, .clientRequestPath, .clientRequestQuery, .clientRefererScheme, .clientRefererHost, .clientRefererPath, .source, .ruleId, .userAgent] | join(",")' >> /tmp/temp.csv
done

# Filter out unwanted host(s) from /tmp CSV file and populate final CSV

egrep -v "$badhosts" /tmp/temp.csv >> $savefile

# Cleanup

/bin/rm /tmp/temp.csv
/bin/rm /tmp/zones.txt

exit

The Actions I use in my filter are described here:
https://developers.cloudflare.com/logs/reference/security-fields/#securityactions

Token instructions are here:
https://developers.cloudflare.com/fundamentals/api/get-started/create-token/

7 Likes

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.