Trong bài viết này, mình sẽ chia sẻ cách để các bạn có thể phân tích logs Cloudflare Firewall Event thông qua GraphQL, thay vì Cloudflare Dashboard, để tránh được một số hạn chế trên dashboard ở bản Cloudflare Free.

Hạn chế của Cloudflare Dashboard bản Free

Các bạn nào đã dùng chùa Cloudflare (free subscription) trong một thời gian tương đối, chắc hẳn sẽ thấy dashboard cho phần Firewall Events được cải thiện rất nhiều so với trước đây. Tuy nhiên, cá nhân mình thấy dashboard này vẫn có một hạn chế, gây ra nhiều bất cập trong việc phân tích security logs, đó là:

Không cho phép người dùng xem log trong nhiều ngày liên tiếp!!

Cloudflare Dashboard không cho phép chọn time range nhiều hơn một ngày
Cloudflare Dashboard không cho phép chọn time range nhiều hơn một ngày

Ví dụ, nếu muốn điều tra các request được gửi đi từ IP 178.128.58.213 từ ngày 07/10/2024 → 11/10/2024, bạn sẽ phải chọn từng ngày một (từ mùng 7 tới 11 tháng 10) để kiểm tra và tổng hợp lại thông tin. Việc này tốn rất bất tiện và tốn thời gian.

Có một cách khác là bạn trả cho Cloudflare đâu đó $20 / tháng để nâng cấp subscription lên thành Pro :), tất nhiên là cách này rất đau ví.
Rất may, ngoài dashboard, Cloudflare cho phép người dùng sử dụng GraphQL để query Firewall Events.

Sử dụng Python + GraphQL để query security event nhiều ngày liên tiếp

Lưu ý: tất cả các logs query trong phần này đều chỉ là sample logs, chứ không phải log của toàn bộ http request gửi đến Cloudflare zone của bạn.

Đây là một đoạn GraphQL query giúp lấy ra Firewall Events của một CF Zone từ 2024-10-07T11:00:00Z tới 2024-10-08T12:00:00Z , với mỗi event sẽ query ra các fields như action, clientAsn, clientCountryName, v.v.

{ 
"query":
  "query ListFirewallEvents($zoneTag: string, $filter: FirewallEventsAdaptiveFilter_InputObject) {
    viewer {
      zones(filter: { zoneTag: $zoneTag }) {
        firewallEventsAdaptive(
          filter: $filter
          limit: 10000
          orderBy: [datetime_DESC]
        ) {
          action
          clientAsn
          clientCountryName
          clientIP
          clientRequestPath
          clientRequestQuery
          datetime
          source
          userAgent
        }
      }
    }
  }",
  "variables": {
    "zoneTag": "<CLOUDFLARE_ZONE_ID>",
    "filter": {
      "datetime_geq": "2024-10-07T11:00:00Z",
      "datetime_leq": "2024-10-08T12:00:00Z"
    }
  }
}

Bạn có thể xem thêm tại đây.
Điều đó có nghĩa là bạn có thể dùng bash (curl) hay bất cứ ngôn ngữ nào để query firewall event thông qua http requests.

Trong bài viết này mình sẽ sử dụng python để làm việc này:

https://github.com/phongvq/cloudflare-fw-log-analyser/blob/main/analyzer.py

Script phía trên cho phép người dùng query Firewall Event của một Cloudflare zone cụ thể trong khoảng thời gian do người dùng chỉ định.

Về cơ bản, tất cả những gì nó làm là fetch event của từng ngày một (từ START_DATE đến END_DATE), sau đó tổng hợp lại và xuất ra một file csv (cloudflare_security_events.csv).

Để chạy script này, bạn chỉ cần làm theo các bước phía dưới đây:

  • Tạo một Cloudflare api token tại https://dash.cloudflare.com/profile/api-tokens.
    • Set quyền cho token: Account:Logs:Read Zone:Logs:ReadZone:Analytics:Read .
    • Sau đó chọn account và zone mà bạn đang muốn phân tích logs.
Các quyền cần cấp cho API Token, để Python có thể fetch Firewall Event log từ Cloudflare
Các quyền cần cấp cho API Token, để Python có thể fetch Firewall Event log từ Cloudflare
  • Thay các biến môi trường cần thiết như: CLOUDFLARE_API_TOKEN, START_DATE, END_DATE, CLOUDFLARE_ZONE_ID vào và chạy các lệnh dưới đây.
pip3 install -r requirements.txt

CLOUDFLARE_API_TOKEN=XXXXX START_DATE="2024-10-01" END_DATE="2024-10-12" CLOUDF
LARE_ZONE_ID=XXXXX python3 analyzer.py
Fetching events for 2024-10-01...
Fetching events for 2024-10-02...
Fetching events for 2024-10-03...
Fetching events for 2024-10-04...
Fetching events for 2024-10-05...
Fetching events for 2024-10-06...
Fetching events for 2024-10-07...
Fetching events for 2024-10-08...
Fetching events for 2024-10-09...
Fetching events for 2024-10-10...
Fetching events for 2024-10-11...
Fetching events for 2024-10-12...
All events have been saved to cloudflare_security_events.csv

Output sẽ được ghi ra file cloudflare_security_events.csv , nằm ở cùng directory với script analyzer.py , và sẽ có format như dưới đây:

action,clientAsn,clientCountryName,clientIP,clientRequestPath,clientRequestQuery,datetime,source,userAgent
block,396982,US,25.210.31.237,/,,2024-10-01T16:16:24Z,firewallCustom,"Expanse, a Palo Alto Networks company, searches across the global IPv4 space multiple times per day to identify customers&#39; presences on the Internet. If you would like to be excluded from our scans, please send IP addresses/domains to: scaninfo@paloaltonetworks.com"
...
skip,32934,US,2a03:2880:ff:4::face:b0c,/wp-content/uploads/2024/08/Screenshot-2024-08-11-at-23.34.26.png,,2024-10-08T15:51:20Z,firewallCustom,facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)
block,23033,US,26.244.66.233,/robots.txt,,2024-10-08T13:31:35Z,firewallCustom,Mozilla/5.0 (compatible; DotBot/1.2; +https://opensiteexplorer.org/dotbot; help@moz.com)
...

Phân tích logs

Giờ đã có logs, bạn có thể sử dụng một số tool xử lý text đơn giản trên Linux như sed, grep, cut, v.v. để phân tích; hoặc có thể ném file này vào excel, format thành bảng rồi filter data tuỳ vào nhu cầu.

Ví dụ nếu muốn lấy ra danh sách các địa chỉ IP truy cập nhiều nhất, các bạn có thể dùng lệnh dưới dây.

$ cat cloudflare_security_events.csv| cut -d , -f4 | grep -v IP | sort | uniq -c | sort -nrk 1
 
  50 216.x.x.233
  19 66.x.x.166
  16 66.x.x.236
  16 185.x.x.115
  15 66.x.x.236
  12 52.x.x.166
  10 66.x.x.167
  10 66.x.x.237
   9 66.x.x.238
   9 66.x.x.231
...

Ở đây mình có dùng ChatGPT để viết thêm một script phân tích logs và visualize data dưới dạng đồ thị.

https://github.com/phongvq/cloudflare-fw-log-analyser/blob/main/ip_analyser.py

Cách sử dụng rất đơn giản, bạn chỉ cần làm theo các bước sau

pip3 install -r requirements.txt

# Chạy script và truyền vào field bạn muốn phân tích 
# cloudflare_security_events.csv - là file logs fetch từ cloudflare về ở phần phía trên

cat cloudflare_security_events.csv | grep skip | python3 ip_analyser.py  --group-by userAgent

# ngoài userAgent như trong ví dụ, bạn có thể thử với 'action', 'clientAsn', 'clientCountryName', 'clientIP', 'clientRequestPath', 'clientRequestQuery', 'datetime', 'source', 'userAgent'

Và chúng ta sẽ có được một chiếc đồ thị như dưới đây:

Thống kê requests theo ClientIP
Thống kê requests theo ClientIP
Thống kê requests theo UserAgent
Thống kê requests theo UserAgent

Ví dụ ở đây, bot của Bing đọc vào blog của mình rất nhiều, mình có thể setup WAF rule để block tất cả các requests có User Agent là Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) Chrome/116.0.1938.76 Safari/537.36.

Các bạn có thể phân tích thêm theo nhiều hướng khác, tuỳ vào ứng dụng và vấn đề bạn đang gặp phải. Dựa vào kết quả phân tích, bạn có thể cài đặt các WAF rule phù hợp để nâng cao tính bảo mật cho website.

Kết luận

Trong bài viết này, mình đã trình bày cách sử dụng GraphQL để query ra Firewall Events của Cloudflare. Tuy nhiên ngoài Firewall Events, GraphQL API còn có thể dùng để lấy ra rất nhiều thông tin khác trên Cloudflare. Bạn có thể đọc thêm tại đây.

Sắp tới mình có dự định viết một loạt bài liên quan tới Cloudflare: Worker, WAF, v.v. Hy vọng sẽ nhận được nhiều sự đón nhận và góp ý từ các bạn.

Nếu có chủ đề nào bạn quan tâm về Cloudflare, hãy để lại bình luận ở phía dưới cho mình biết nhé!

Peace <3