Cloudflare HTTP DDoS Attack Protection Managed Ruleset とは
これまで Cloudflare の DDoS 保護ルールはブラックボックスでしたが、HTTP DDoS に関してはマネージドルールの一覧がユーザーに公開され、カスタマイズもできるようになりました。
ダッシュボードでルール情報を確認
https://dash.cloudflare.com/?to=/:account/:zone/security/ddos から確認できます。
その中から Test rule を使って挙動の確認ができます。
API でルール情報を確認
API からも取得できる情報を確認しましょう。
export ZONE_ID='YOUR_ZONE_ID'
cli4 zones/:$ZONE_ID/rulesets | jq -r '.[] | select (.phase=="ddos_l7")'
{
"description": "Automatic mitigation of HTTP-based DDoS attacks. Cloudflare routinely adds signatures to address new attack vectors. Additional configuration allows you to customize the sensitivity of each rule and the performed mitigation action.",
"id": "4d21379b4f9f4bb088e0729962c8b3cf",
"kind": "managed",
"last_updated": "2022-05-10T14:30:42.926686Z",
"name": "DDoS L7 ruleset",
"phase": "ddos_l7",
"version": "636"
}
ルール一覧の中に先ほどの Test rule も確認できます。
cli4 zones/:$ZONE_ID/rulesets/:4d21379b4f9f4bb088e0729962c8b3cf | jq -r '.rules[] | select (.categories[]=="test")'
{
"action": "block",
"categories": [
"test"
],
"description": "Test rule: will quickly block URI containing 'blockme=npvenJAo9gMlnd5yD37xQ9P2qp3934'.",
"enabled": true,
"id": "ca3c07df048b4c2c9c9350116f9d3516",
"last_updated": "2022-05-10T14:30:42.926686Z",
"ref": "GEN0006",
"version": "326"
}
テストルールを使った挙動の確認
具体的な閾値は公開されていませんが、テスト用にトリガーされやすい(?)ルールとなっているようです。
以下のスクリプトを流して確認します。後半は 403 でブロックされたことがわかります。
export FQDN='example.com'
for i in {1..200}; \
do echo $i $(curl 'https://'$FQDN'/?blockme=npvenJAo9gMlnd5yD37xQ9P2qp3934' -v -s 2>&1 | grep '< HTTP/'); done
コマンド1回目結果
1 < HTTP/2 200
2 < HTTP/2 200
3 < HTTP/2 200
4 < HTTP/2 200
5 < HTTP/2 200
6 < HTTP/2 200
7 < HTTP/2 200
8 < HTTP/2 200
9 < HTTP/2 200
10 < HTTP/2 200
11 < HTTP/2 200
12 < HTTP/2 200
13 < HTTP/2 200
14 < HTTP/2 200
15 < HTTP/2 200
16 < HTTP/2 200
17 < HTTP/2 200
18 < HTTP/2 200
19 < HTTP/2 200
20 < HTTP/2 200
21 < HTTP/2 200
22 < HTTP/2 200
23 < HTTP/2 200
24 < HTTP/2 200
25 < HTTP/2 200
26 < HTTP/2 200
27 < HTTP/2 200
28 < HTTP/2 200
29 < HTTP/2 200
30 < HTTP/2 200
31 < HTTP/2 200
32 < HTTP/2 200
33 < HTTP/2 200
34 < HTTP/2 200
35 < HTTP/2 200
36 < HTTP/2 200
37 < HTTP/2 200
38 < HTTP/2 200
39 < HTTP/2 200
40 < HTTP/2 200
41 < HTTP/2 200
42 < HTTP/2 200
43 < HTTP/2 200
44 < HTTP/2 200
45 < HTTP/2 200
46 < HTTP/2 200
47 < HTTP/2 200
48 < HTTP/2 200
49 < HTTP/2 200
50 < HTTP/2 200
51 < HTTP/2 200
52 < HTTP/2 200
53 < HTTP/2 200
54 < HTTP/2 200
55 < HTTP/2 200
56 < HTTP/2 200
57 < HTTP/2 200
58 < HTTP/2 200
59 < HTTP/2 200
60 < HTTP/2 200
61 < HTTP/2 200
62 < HTTP/2 200
63 < HTTP/2 200
64 < HTTP/2 200
65 < HTTP/2 200
66 < HTTP/2 200
67 < HTTP/2 200
68 < HTTP/2 200
69 < HTTP/2 200
70 < HTTP/2 200
71 < HTTP/2 200
72 < HTTP/2 200
73 < HTTP/2 200
74 < HTTP/2 200
75 < HTTP/2 200
76 < HTTP/2 200
77 < HTTP/2 200
78 < HTTP/2 200
79 < HTTP/2 200
80 < HTTP/2 200
81 < HTTP/2 200
82 < HTTP/2 200
83 < HTTP/2 200
84 < HTTP/2 200
85 < HTTP/2 200
86 < HTTP/2 200
87 < HTTP/2 200
88 < HTTP/2 200
89 < HTTP/2 200
90 < HTTP/2 200
91 < HTTP/2 200
92 < HTTP/2 200
93 < HTTP/2 200
94 < HTTP/2 200
95 < HTTP/2 200
96 < HTTP/2 200
97 < HTTP/2 200
98 < HTTP/2 200
99 < HTTP/2 200
100 < HTTP/2 200
101 < HTTP/2 200
102 < HTTP/2 200
103 < HTTP/2 200
104 < HTTP/2 200
105 < HTTP/2 200
106 < HTTP/2 200
107 < HTTP/2 200
108 < HTTP/2 200
109 < HTTP/2 200
110 < HTTP/2 200
111 < HTTP/2 200
112 < HTTP/2 200
113 < HTTP/2 200
114 < HTTP/2 200
115 < HTTP/2 200
116 < HTTP/2 200
117 < HTTP/2 200
118 < HTTP/2 200
119 < HTTP/2 200
120 < HTTP/2 200
121 < HTTP/2 200
122 < HTTP/2 200
123 < HTTP/2 200
124 < HTTP/2 200
125 < HTTP/2 200
126 < HTTP/2 200
127 < HTTP/2 200
128 < HTTP/2 200
129 < HTTP/2 200
130 < HTTP/2 200
131 < HTTP/2 200
132 < HTTP/2 200
133 < HTTP/2 200
134 < HTTP/2 200
135 < HTTP/2 200
136 < HTTP/2 200
137 < HTTP/2 200
138 < HTTP/2 200
139 < HTTP/2 200
140 < HTTP/2 200
141 < HTTP/2 200
142 < HTTP/2 200
143 < HTTP/2 200
144 < HTTP/2 200
145 < HTTP/2 200
146 < HTTP/2 200
147 < HTTP/2 200
148 < HTTP/2 200
149 < HTTP/2 200
150 < HTTP/2 200
151 < HTTP/2 200
152 < HTTP/2 200
153 < HTTP/2 200
154 < HTTP/2 200
155 < HTTP/2 200
156 < HTTP/2 200
157 < HTTP/2 200
158 < HTTP/2 200
159 < HTTP/2 200
160 < HTTP/2 200
161 < HTTP/2 200
162 < HTTP/2 200
163 < HTTP/2 200
164 < HTTP/2 200
165 < HTTP/2 200
166 < HTTP/2 200
167 < HTTP/2 200
168 < HTTP/2 200
169 < HTTP/2 200
170 < HTTP/2 200
171 < HTTP/2 200
172 < HTTP/2 200
173 < HTTP/2 200
174 < HTTP/2 200
175 < HTTP/2 200
176 < HTTP/2 200
177 < HTTP/2 200
178 < HTTP/2 200
179 < HTTP/2 200
180 < HTTP/2 200
181 < HTTP/2 200
182 < HTTP/2 200
183 < HTTP/2 200
184 < HTTP/2 200
185 < HTTP/2 200
186 < HTTP/2 200
187 < HTTP/2 200
188 < HTTP/2 200
189 < HTTP/2 200
190 < HTTP/2 403
191 < HTTP/2 200
192 < HTTP/2 200
193 < HTTP/2 200
194 < HTTP/2 200
195 < HTTP/2 200
196 < HTTP/2 200
197 < HTTP/2 200
198 < HTTP/2 200
199 < HTTP/2 403
200 < HTTP/2 403
コマンド2回目結果
1 < HTTP/2 403
2 < HTTP/2 403
3 < HTTP/2 403
4 < HTTP/2 403
5 < HTTP/2 403
6 < HTTP/2 403
7 < HTTP/2 200
8 < HTTP/2 403
9 < HTTP/2 403
10 < HTTP/2 403
11 < HTTP/2 403
12 < HTTP/2 403
13 < HTTP/2 403
14 < HTTP/2 403
15 < HTTP/2 403
16 < HTTP/2 403
17 < HTTP/2 403
18 < HTTP/2 403
19 < HTTP/2 403
20 < HTTP/2 200
21 < HTTP/2 403
22 < HTTP/2 200
23 < HTTP/2 403
24 < HTTP/2 403
25 < HTTP/2 200
26 < HTTP/2 403
27 < HTTP/2 403
28 < HTTP/2 200
29 < HTTP/2 403
30 < HTTP/2 403
31 < HTTP/2 403
32 < HTTP/2 403
33 < HTTP/2 403
34 < HTTP/2 200
35 < HTTP/2 403
36 < HTTP/2 403
37 < HTTP/2 403
38 < HTTP/2 403
39 < HTTP/2 200
40 < HTTP/2 403
41 < HTTP/2 200
42 < HTTP/2 403
43 < HTTP/2 403
44 < HTTP/2 403
45 < HTTP/2 403
46 < HTTP/2 403
47 < HTTP/2 403
48 < HTTP/2 403
49 < HTTP/2 403
50 < HTTP/2 403
51 < HTTP/2 403
52 < HTTP/2 403
53 < HTTP/2 403
54 < HTTP/2 403
55 < HTTP/2 403
56 < HTTP/2 403
57 < HTTP/2 403
58 < HTTP/2 403
59 < HTTP/2 403
60 < HTTP/2 403
61 < HTTP/2 403
62 < HTTP/2 403
63 < HTTP/2 200
64 < HTTP/2 403
65 < HTTP/2 403
66 < HTTP/2 403
67 < HTTP/2 403
68 < HTTP/2 403
69 < HTTP/2 200
70 < HTTP/2 403
71 < HTTP/2 403
72 < HTTP/2 403
73 < HTTP/2 403
74 < HTTP/2 403
75 < HTTP/2 403
76 < HTTP/2 403
77 < HTTP/2 403
78 < HTTP/2 403
79 < HTTP/2 403
80 < HTTP/2 403
81 < HTTP/2 403
82 < HTTP/2 403
83 < HTTP/2 403
84 < HTTP/2 403
85 < HTTP/2 403
86 < HTTP/2 403
87 < HTTP/2 403
88 < HTTP/2 403
89 < HTTP/2 403
90 < HTTP/2 403
91 < HTTP/2 403
92 < HTTP/2 403
93 < HTTP/2 403
94 < HTTP/2 403
95 < HTTP/2 403
96 < HTTP/2 403
97 < HTTP/2 403
98 < HTTP/2 403
99 < HTTP/2 403
100 < HTTP/2 403
101 < HTTP/2 403
102 < HTTP/2 403
103 < HTTP/2 403
104 < HTTP/2 403
105 < HTTP/2 403
106 < HTTP/2 403
107 < HTTP/2 403
108 < HTTP/2 403
109 < HTTP/2 403
110 < HTTP/2 403
111 < HTTP/2 403
112 < HTTP/2 403
113 < HTTP/2 403
114 < HTTP/2 403
115 < HTTP/2 403
116 < HTTP/2 403
117 < HTTP/2 403
118 < HTTP/2 403
119 < HTTP/2 403
120 < HTTP/2 403
121 < HTTP/2 403
122 < HTTP/2 403
123 < HTTP/2 403
124 < HTTP/2 403
125 < HTTP/2 403
126 < HTTP/2 403
127 < HTTP/2 403
128 < HTTP/2 403
129 < HTTP/2 403
130 < HTTP/2 403
131 < HTTP/2 403
132 < HTTP/2 403
133 < HTTP/2 403
134 < HTTP/2 403
135 < HTTP/2 403
136 < HTTP/2 403
137 < HTTP/2 403
138 < HTTP/2 403
139 < HTTP/2 403
140 < HTTP/2 403
141 < HTTP/2 403
142 < HTTP/2 403
143 < HTTP/2 403
144 < HTTP/2 403
145 < HTTP/2 403
146 < HTTP/2 403
147 < HTTP/2 403
148 < HTTP/2 403
149 < HTTP/2 403
150 < HTTP/2 403
151 < HTTP/2 403
152 < HTTP/2 403
153 < HTTP/2 403
154 < HTTP/2 403
155 < HTTP/2 403
156 < HTTP/2 403
157 < HTTP/2 403
158 < HTTP/2 403
159 < HTTP/2 403
160 < HTTP/2 403
161 < HTTP/2 403
162 < HTTP/2 403
163 < HTTP/2 403
164 < HTTP/2 403
165 < HTTP/2 403
166 < HTTP/2 403
167 < HTTP/2 403
168 < HTTP/2 403
169 < HTTP/2 403
170 < HTTP/2 403
171 < HTTP/2 403
172 < HTTP/2 403
173 < HTTP/2 403
174 < HTTP/2 403
175 < HTTP/2 403
176 < HTTP/2 403
177 < HTTP/2 403
178 < HTTP/2 403
179 < HTTP/2 403
180 < HTTP/2 403
181 < HTTP/2 403
182 < HTTP/2 403
183 < HTTP/2 403
184 < HTTP/2 403
185 < HTTP/2 403
186 < HTTP/2 403
187 < HTTP/2 403
188 < HTTP/2 403
189 < HTTP/2 403
190 < HTTP/2 403
191 < HTTP/2 403
192 < HTTP/2 403
193 < HTTP/2 403
194 < HTTP/2 403
195 < HTTP/2 403
196 < HTTP/2 403
197 < HTTP/2 403
198 < HTTP/2 403
199 < HTTP/2 403
200 < HTTP/2 403
また、実際にアクセスしてみると、このようなページになります。
ダッシュボードで結果を確認
通知
こちらの KB を参考にして、事前に DDoS アラートを構成しておけば、基準を満たした際に以下のようなメール通知を受信することもできました。
検知したルール ID まで含めた詳細な内容のメールとなっているので、助かります。
参考:ログ
ddos_log.json
{
"BotDetectionIDs": [
33554817
],
"BotScore": 1,
"BotScoreSrc": "Heuristics",
"BotTags": [],
"CacheCacheStatus": "unknown",
"CacheReserveUsed": false,
"CacheResponseBytes": 0,
"CacheResponseStatus": 0,
"CacheTieredFill": false,
"ClientASN": 2527,
"ClientCountry": "jp",
"ClientDeviceType": "desktop",
"ClientIP": "x.x.x.x",
"ClientIPClass": "noRecord",
"ClientMTLSAuthCertFingerprint": "",
"ClientMTLSAuthStatus": "unknown",
"ClientRegionCode": "13",
"ClientRequestBytes": 2959,
"ClientRequestHost": "example.com",
"ClientRequestMethod": "GET",
"ClientRequestPath": "/",
"ClientRequestProtocol": "HTTP/2",
"ClientRequestReferer": "",
"ClientRequestScheme": "https",
"ClientRequestSource": "eyeball",
"ClientRequestURI": "/?blockme=npvenJAo9gMlnd5yD37xQ9P2qp3934",
"ClientRequestUserAgent": "curl/7.82.0-DEV",
"ClientSSLCipher": "AEAD-AES128-GCM-SHA256",
"ClientSSLProtocol": "TLSv1.3",
"ClientSrcPort": 51071,
"ClientTCPRTTMs": 5,
"ClientXRequestedWith": "",
"ContentScanObjResults": [],
"ContentScanObjTypes": [],
"EdgeCFConnectingO2O": false,
"EdgeColoCode": "NRT",
"EdgeColoID": 408,
"EdgeEndTimestamp": 1675178658281000000,
"EdgePathingOp": "ban",
"EdgePathingSrc": "protect",
"EdgePathingStatus": "l7ddos",
"EdgeRateLimitAction": "",
"EdgeRateLimitID": 0,
"EdgeRequestHost": "",
"EdgeResponseBodyBytes": 1467,
"EdgeResponseBytes": 2453,
"EdgeResponseCompressionRatio": 1,
"EdgeResponseContentType": "text/html",
"EdgeResponseStatus": 403,
"EdgeServerIP": "",
"EdgeStartTimestamp": 1675178658269000000,
"EdgeTimeToFirstByteMs": 27,
"FirewallMatchesActions": [
"block"
],
"FirewallMatchesRuleIDs": [
"ca3c07df048b4c2c9c9350116f9d3516"
],
"FirewallMatchesSources": [
"l7ddos"
],
"JA3Hash": "09fa2749da64939e9b4053172a8e78dc",
"OriginDNSResponseTimeMs": 0,
"OriginIP": "",
"OriginRequestHeaderSendDurationMs": 0,
"OriginResponseBytes": 0,
"OriginResponseDurationMs": 0,
"OriginResponseHTTPExpires": "",
"OriginResponseHTTPLastModified": "",
"OriginResponseHeaderReceiveDurationMs": 0,
"OriginResponseStatus": 0,
"OriginResponseTime": 0,
"OriginSSLProtocol": "unknown",
"OriginTCPHandshakeDurationMs": 0,
"OriginTLSHandshakeDurationMs": 0,
"ParentRayID": "00",
"RayID": "792374162a26af42",
"SecurityLevel": "unk",
"SmartRouteColoID": 0,
"UpperTierColoID": 0,
"WAFAction": "unknown",
"WAFAttackScore": 87,
"WAFFlags": "0",
"WAFMatchedVar": "",
"WAFProfile": "unknown",
"WAFRCEAttackScore": 88,
"WAFRuleID": "",
"WAFRuleMessage": "",
"WAFSQLiAttackScore": 98,
"WAFXSSAttackScore": 98,
"WorkerCPUTime": 0,
"WorkerStatus": "unknown",
"WorkerSubrequest": false,
"WorkerSubrequestCount": 0,
"WorkerWallTimeUs": 0,
"ZoneID": XXXXXXXXX,
"ZoneName": "example.com"
}