AWS WAF の Bot Control マネージドルールを使ったときに、一部の未検証 Bot を例外として許可してみる

AWS WAF の Bot Control マネージドルールを使ったときに、一部の未検証 Bot を例外として許可してみる

2025.12.09

いわさです。

AWS WAF は Bot Control というマネージドルールがありまして、こいつを使うと AWS がマネージドに Bot のトリアージをしてくれます。
この Bot Control ですが、検査レベルというものがあり Common と Targeted があります。

https://dev.classmethod.jp/articles/waf-managed-bot-targeted-v-2-3/

Targeted にすることでより高度な検出が出来ます。
今回外部からの Bot のアクセスをちょっと抑制したくてこの Bot Control マネージドルールセットの TGT_VolumetricIpTokenAbsent を有効化しました。
このルール、検証済みではない Bot からのリクエストからの連続したリクエストに対してチャレンジを要求するというものです。
AWS WAF の Bot Control では Bot に対して検証済みと未検証の判断を行います。検証済みの Bot はたくさんあるのですが例えば Google のクローラーとかそういった明らかにブロックしたくないでしょ、みたいな Bot はたいてい検証済み Bot になっています。
なのでメジャーでアクセスが期待される Bot に関してはそもそも Bot Control の各ルールの対象にならないことが多いです。

しかし、未検証 Bot をすべて弾けばいいかと実はそうでもなくて、少し慎重に判断する必要があります。
明らかにサイトに予期せぬ負荷をかけてしまう Bot やクローラーもあるのですが、これはまぁええやろ...みたいなものも一部未検証 Bot になっている場合があります。

今回は未検証 Bot の棚卸しと一部例外的に許容させる方法を試してみたのでその検証結果を紹介します。

未検証 Bot たちを調べる

AWS WAF の WebACL を事前に作成しておきます。
Web ACL には一旦 Bot Control マネージドルールを Targeted で追加しておきました。

37ECC389-6020-493E-8496-5BDDE6B5C63E.png

各ルールですが、ここでは Count モードでオーバーライドしています。

AEBBD8AF-88D3-482D-960E-A297B047CCFA.png

そして Web ACL はログ出力を有効化し、CloudWatch Logs へ出力しておきます。
後ほど CloudWatch Logs Insights で色々と分析するためです。

リソースにアタッチしてしばらく(数日)待ちましょう。
うまく外部からアクセスがあればクエリで分析できるようになります。

ここではtoken_absentラベル(awswaf:managed:aws:bot-control:targeted:aggregate:volumetric:ip:token_absent)がついてて、bot:unverified判定されたリクエストを検出してみます。
クエリはこちら。

fields @timestamp
| filter @message like /bot:unverified/ and @message like /volumetric:ip:token_absent/
| parse @message /bot:name:(?<botName>[a-zA-Z0-9_]+)/
| parse @message /bot:category:(?<botCategory>[a-zA-Z0-9_]+)/

とある環境で実行してみたところ次のような結果になりました。
TokenAbsentの判定がされ、かつ未検証な Bot でアクセスがあったものの Bot ごとのリクエスト数をリストアップしたものです。

botName,botCategory,requestCount
dotbot,seo,208300
facebot,social_media,4019
chrome_lighthouse,content_fetcher,2341
semrushbot,seo,1195
slack_images,social_media,279
bytespider,seo,400
chatgpt,ai,75
linkup,content_fetcher,345
linguee,search_engine,4
livelapbot,content_fetcher,6
okhttp,http_library,57
ruby,http_library,3929
libperl,http_library,6567
apache,http_library,47
python,http_library,849
go_http,http_library,1905
whatsapp,social_media,87
docomo,miscellaneous,51
hatena,scraping_framework,706
discordbot,social_media,9
embedly,content_fetcher,7
libhttp,http_library,6
chatgpt_user,ai,4
axios,http_library,27
blexbot,seo,458727
barkrowler,miscellaneous,1670
curl,http_library,140
java,http_library,6
internet_archive,archiver,108
w3c,link_checker,1
feedburner,monitoring,3
serpstatbot,seo,19357
bitly,link_checker,1

負荷をかけてくることで有名なクローラーなども一部含まれていますね。
ただし、一部 Bot は許容しても良さそうなものもあったり、あるいはリクエスト数などからトリアージの優先順位つけても良いと思います。少ないリクエストの Bot は攻撃的でも許容しちゃってもいいんじゃない?という。

例外許可したい Bot を検討したら、例外ルールを作成する

ここの判断は自分で行う必要がありますが、先程の未検証 Bot の中から「これは許しても良いのでは?」という Bot を選びます。
今回ははてなブログのクローラは許可しても良い気がするのでこちらを許可したいと思います。

ちなみにはてなブログのクローラーについては以下でも説明されています。

https://help.hatenablog.com/entry/about-hatenablogbot

ルールの設定

CloudWatch Logs でリクエスト詳細を確認してみます。
以下で Bot 名を指定してリクエスト情報を分析してみましょう。

クエリがこちら。

fields @timestamp
| filter @message like /bot:unverified/ and @message like /volumetric:ip:token_absent/
| parse @message /bot:name:(?<botName>[a-zA-Z0-9_]+)/
| parse @message /bot:category:(?<botCategory>[a-zA-Z0-9_]+)/
| filter botName like "hatena"

ヘッダーやラベルを判定することで、どういうユーザーエージェントでアクセスされて、AWS WAF で判断されたあとにどういうラベルが付与されているのか把握することが出来ます。
以下は別の Bot の例ですが、dotbot であれば、次のようなユーザーエージェントが設定されてその後ラベルが付与されているわけです。

11EC6C73-D29D-4319-9FED-4B1669EEB834.png

297DE8F4-5733-45C8-8709-9C69313B1993.png

ほとんどの場合はユーザーエージェントを偽装してやることで AWS WAF からは Bot 判定してくれます。
今回試したいはてなブログのクローラーであれば、ユーザーエージェントはHatenaBlog-bot/0.02 (+https://help.hatenablog.com/entry/about-hatenablogbot)で、ラベルはawswaf:managed:aws:bot-control:bot:name:hatenaです。

ということで Bot Control よりも優先度が後のカスタムルールを作成し、そこでラベル判定ルールを作成しましょう。
次のような感じです。

61D84705-E1B9-43F6-A63A-CD450EC02945.png

これでアクションをブロックやチャレンジにしてやれば、未検証の Bot のうちはてなブログクローラー以外はそのアクションが作動するわけです。

試す

ではユーザーエージェントを偽装して試してみましょう。
cURL でヘッダー指定するだけで良いです。

はてなブログクローラーのユーザーエージェントを指定した場合はエラーにならないですね。

% curl https://hogecf.tak1wa.com/ -I -H "User-Agent: HatenaBlog-bot/0.02 (+https://help.hatenablog.com/entry/about-hatenablogbot)"
HTTP/2 200 
content-type: text/html
content-length: 4
date: Tue, 09 Dec 2025 10:03:06 GMT
last-modified: Fri, 08 Aug 2025 19:51:57 GMT
etag: "ea703e7aa1efda0064eaa507d9e8ab7e"
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 522bb839fb85af56b914e6e0ae70ec5a.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P8
x-amz-cf-id: obIs1rOcmD7iJ57I1YNUwlqlFsPKirs6r2VHSjxqUWORR773KpGVjg==

% curl https://hogecf.tak1wa.com/ -I -H "User-Agent: HatenaBlog-bot/0.02 (+https://help.hatenablog.com/entry/about-hatenablogbot)"
HTTP/2 200 
content-type: text/html
content-length: 4
date: Tue, 09 Dec 2025 10:03:07 GMT
last-modified: Fri, 08 Aug 2025 19:51:57 GMT
etag: "ea703e7aa1efda0064eaa507d9e8ab7e"
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 22f4d5764b849574537f093da26a1c12.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P8
x-amz-cf-id: HuAgb-MSdhy46RGXgYBL8STj1E_IBM5VbkRs9lkokao-mFLa-P3qoA==

CloudWatch Logs Insights でログを確認してみると、うまくはてなブログクローラーだと判定してくれています。良さげです。

03DC88CC-AEEF-4C4F-B0CB-B49B2965F266.png

一方で、例外許可に設定していない facebot (Facebookのクローラー)だとどうでしょうか。

% curl https://hogecf.tak1wa.com/ -I -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/601.2.4 (KHTML, like Gecko) Version/9.0.1 Safari/601.2.4 facebookexternalhit/1.1 Facebot Twitterbot/"
HTTP/2 200 
content-type: text/html
content-length: 4
date: Tue, 09 Dec 2025 10:02:02 GMT
last-modified: Fri, 08 Aug 2025 19:51:57 GMT
etag: "ea703e7aa1efda0064eaa507d9e8ab7e"
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 522bb839fb85af56b914e6e0ae70ec5a.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P8
x-amz-cf-id: jwxsScXeDSRdFcB9It8rm47i20unI9vwgte2KmfccNacMUFYdLVO4Q==

% curl https://hogecf.tak1wa.com/ -I -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/601.2.4 (KHTML, like Gecko) Version/9.0.1 Safari/601.2.4 facebookexternalhit/1.1 Facebot Twitterbot/"
HTTP/2 403 
server: CloudFront
date: Tue, 09 Dec 2025 10:02:02 GMT
content-type: text/html
content-length: 919
x-cache: Error from cloudfront
via: 1.1 8a416a9aa7ab03fb13d0b337bc55d61e.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P8
x-amz-cf-id: NcZrDzw8WmxYbfJzrQTN2HlnyddsshN1A7bswPfisNW6S8EtMRut4A==

こちらは連続したリクエストを送ったときに TokenAbsent のトークン判定が行われてラベル付与されていますね。
そしてカスタムルールで例外許可されていないのでそのままブロック(あるいはチャレンジ)されています。良い感じです。

さいごに

本日は AWS WAF の Bot Control マネージドルールを使ったときに、一部の未検証 Bot を例外として許可してみました。

とりあえずユーザーエージェントを偽装してテストが出来たのと、カスタムルールで未検証 Bot の例外許可が出来たので良かったです。
ユーザーエージェントでルール上で判定するのはちょっと面倒そうだったのでラベル判定が無難な気がしますね。

これを応用して複数の未検証 Bot を例外許可したかったのですが、次のルールだとうまく動かなかったのでもう少し試してみたいと思います。

CABF98D0-AB9C-435A-AA62-38D2511C0855.png

この記事をシェアする

FacebookHatena blogX

関連記事