概要
AWS WAFv2を実際に使って検証したので、その際につまずいたところや考慮したほうがいいところなどまとめます。
今回はレートベースのルールを使ってリクエストの発生元の IP アドレスが同一のものからリクエストが閾値以上になったらブロックする設定にしました。 レートベースのルールは、5分間あたり100リクエストから閾値に設定することが可能となっているので、低頻度のクローラー対策にも対応できます。 aws.amazon.com
構成
今回はWAFをCloudfrontにアタッチする想定で検証しました。 AWSリソースは、Terraformでコード管理します。
Terraform
Terraformコードサンプルはこちらです。WAF Classicのときよりシンプルに設定が書けるようになっています。
今回はCloudfrontにWAFをアタッチするので、aws_wafv2_web_acl
リソースのprovider設定をprovider = aws.east
するのを忘れないようにしましょう。
忘れがちなのですが、WAFのログ設定をするときも同じくproviderはaws.eastにする必要があるので注意です。
つまずいたところ
デフォルトのアクションをBlockにしたままだった
本当に些細な部分を見落としていました。WebACLのアクションは、WAFをアタッチしたときのデフォルトのアクションとルール上のアクションは分けて設定するのですが、デフォルトアクションをBlockにしたままCloudfrontにアタッチしてしまったので、反映完了後ページ閲覧ができず403エラーが返ってくるようになっていました。
デフォルトのアクションがBlockのままだとルールが適用されない場合にアクセスがブロックされる設定になっているので、デフォルトアクションはAllow
でルール上でBlock
アクションを選択する必要があります。
考慮したほうがいいこと
既に運用中のサービスに適用する場合は、まずCountアクションで様子見する
運用中のサービスが急に閲覧できなくなるといった恐ろしい事象をひかないためにも、一度デフォルトアクションはAllow
、ルール上のアクションはCount
にして様子見したほうがいいと思います。WAFのリソース反映直後は、ルールが実際に適用されるまでにタイムラグがあるらしいので一旦寝かしておくと良さそうです。
1日程度様子見すると、ルールにひっかかったIPアドレスがSampledRequestで確認できるので、これらが問題なクローラーかどうか確認できると思います。(WebACLのルールでsampled_requests_enabled
を有効にすれば確認できます)
AWS CLIを使ってカウントされたざっと取り出すこともできます。
※CLI使う時もregionオプションで--region us-east-1
を指定する必要があります
aws wafv2 get-sampled-requests --web-acl-arn <arn> --rule-metric-name <rule-name> --scope CLOUDFRONT --time-window StartTime=yyyy-mm-ddThh:mmZ,EndTime=yyyy-mm-ddThh:mmZ --max-items 500 --region us-east-1 | jq -r .SampledRequests[].Request.ClientIP | sort | uniq > ip.txt
低閾値しきい値に設定する場合は、正規のクローラーがブロックされないか確認する
既にサービスを運用中であれば、Googlebotからのリクエストがサイトに来ていると思うので、収集しているログからGooglebotの頻度がどの程度が念の為に確認しておくと良いと思います。
公式ドキュメントにUserAgentの文字列が記載されているので、ログ検索すればある程度Googlebotからどれくらいの頻度でリクエストが来ているのか、設定しようとしているルールの閾値にひっかからないか確認しておきましょう。 developers.google.com
閾値にもタイムラグがある
WebACLのルールの検証をする際に、何回目からリクエストブロックされ403エラーがでるのか検証したのですが、閾値きっかりにブロックされることはありませんでした。
1秒間隔でリクエストを同一IPから送り続けたところ、約30-50回程度閾値から上回った値で403エラーが返りました。1秒間隔より短い頻度でリクエストを送ると閾値から約100回程度上回った値でないとブロックされなかったので、高頻度になるとタイムラグが大きくなる可能性がありそうです。
おわり!