AWS WAF でアクセス数が一定回数を超えた IP アドレスを自動的にブラックリストに追加させる方法
困っていた内容
自社サービスの特定の URL に対して、数日間で数百の IP アドレスから大量の不正アクセスを受けています。 攻撃元 IP アドレスを自動的にブラックリストに追加させる方法がありましたら教えてください。
どう対応すればいいの?
AWS WAF の レートベースのルール を設定してください。
より細かい制御を行いたい場合は、AWS WAF セキュリティオートメーションの導入をご検討ください。
AWS WAF のレートベースルールとは
AWS WAF のレートベースのルールを設定すると、AWS WAF が発信元 IP アドレスのリクエスト数をカウントし、設定したしきい値を超えるリクエスト数が確認された際に対象の IP を自動でブロックできます。
現在は 5 分間あたり 100 リクエスト を最小しきい値として指定可能です。
以下にて作成手順を紹介します。
Web ACL とレートベースルールの作成
WAF のコンソール画面に移動し、「Create web ACL」をクリックします。
Web ACLの詳細を入力していきます。まずは Web ACL 名、CloudWatch メトリクス名を入力します。
今回はオレゴンリージョンの ALB に紐付けるため、リソースタイプに「Regional resources」を選択し、リージョンも「US West(Oregon)」を選択しました。
次に関連付けるリソースの設定を行います。「Add AWS resources」を選択します。
「Application Load Balancer」を選択した後、紐付けたい ALB のチェックボックスを選択し、「Add」をクリックします。そして「Next」をクリックしてください。
次にルールを設定していきます。「Add my own rules and rule groups」を選択します。
ルールタイプ として「Rule Builder」を選択します。
次にルール名を入力し、タイプは「Rate-based rule」を選択します。
5分間に100アクセス以上あった場合に制限を加えたいため、レート制限値として 100 を入力します。
レート制限をかける IP アドレスの対象として 「Source IP address」を選択しました。
今回は「/admin」配下にのみレートベースルールで制限をかけたいため、「Only consider requests that match the criteria in a rule statement」を選択します。
次に条件設定をします。条件に一致した場合にのみ機能させるため「matches the statement」を選択してください。
検査対象を「URI path」とし、マッチタイプを「Start with string」とします。
そしてマッチ対象となる String として「/admin」を入力しました。
次にアクションで「Block」を選択して、「Add rule」をクリックします。
すると、今回のルール作成で使用されるキャパシティが表示されます。このルールの場合は「4」ですね。
ルールにマッチしないリクエストに対する Web ACL のデフォルトアクションを「Allow」として「Next」をクリックします。
次にルールの優先度を設定できますが、今回はルールが1つしかないためそのままにして「Next」をクリックします。
次にメトリクスの設定です。必要であればこのルールに対応する CloudWatch メトリクス名を変更できます。
また、このルールにマッチするリクエストのサンプルを WAF コンソールに表示させるオプションがあるので、「Enable sampled requests」を選んで有効化させておきます。
最後はレビュー画面となりますので、問題がなければ「Create web ACL」をクリックします。
Web ACL が作成できましたので、さっそくレートベースルールが問題なく作動するかテストします。
テストする
東京リージョンに EC2 インスタンスを起動し、SSH で接続して WAF と連携づけたオレゴンリージョンの ALB に対して curl コマンドを実行します。
そして以下のように 200 OK が返ってくることを確認しました。
$ curl -I http://ttttt-403999499.us-west-2.elb.amazonaws.com/admin/ HTTP/1.1 200 OK Date: Thu, 20 May 2021 17:43:16 GMT Content-Type: text/html;charset=ISO-8859-1 Connection: keep-alive Server: Apache/2.4.46 () Upgrade: h2,h2c
次に対象の ALB に ApacheBench を使用してリクエストを200回送ります。
1回目の結果は以下となり、アクセスはブロックされませんでした。
$ ab -n 200 -c 1 http://ttttt-403999499.us-west-2.elb.amazonaws.com/admin/ (略) Complete requests: 200 Failed requests: 0 Total transferred: 209851 bytes
1回目の結果が出てすぐに、2回目のコマンド実行を行うと187回のリクエストが遮断されました。
$ ab -n 200 -c 1 http://ttttt-403999499.us-west-2.elb.amazonaws.com/admin/ (略) Complete requests: 200 Failed requests: 187 (Connect: 0, Receive: 0, Length: 187, Exceptions: 0) Non-2xx responses: 187
3回目は全てのアクセスがブロックされました!
$ ab -n 200 -c 1 http://ttttt-403999499.us-west-2.elb.amazonaws.com/admin/ (略) Complete requests: 200 Failed requests: 0 Non-2xx responses: 200
再度 curl コマンドを実行し、403エラーが返ってくることを確認しました。
$ curl -I http://ttttt-403999499.us-west-2.elb.amazonaws.com/admin/ HTTP/1.1 403 Forbidden Server: awselb/2.0 Date: Thu, 20 May 2021 17:50:11 GMT Content-Type: text/html Content-Length: 118 Connection: keep-alive
AWS CLI の get-rate-based-statement-managed-keys コマンドでレートベースルールによってブロックされた IP アドレスを確認できます。
ALB に Web ACL をセットしたので REGIONAL でスコープを設定し、Web ACL 名、Web ACL ID、ルール名を入れて実行します。
現在ブロック状態にある東京リージョンの EC2 インスタンスの IP が無事確認できました。
$ aws wafv2 get-rate-based-statement-managed-keys \ --scope REGIONAL \ --web-acl-name waf0512 \ --web-acl-id b0171f79-7455-4533-94fd-e2463392512f \ --rule-name Rate-based-rule-with-address { "ManagedKeysIPV4": { "IPAddressVersion": "IPV4", "Addresses": [ "13.113.177.16/32" ] }, "ManagedKeysIPV6": { "IPAddressVersion": "IPV6", "Addresses": [] } }
一定時間が経過した後に get-rate-based-statement-managed-keys
コマンドを再度実行したところ、IP アドレスがブロックリストから解除されていました。
追記
レートベースルールでブロックされた IP アドレスを永続的にブロックする方法についてのお問い合わせを何件か頂きました。以下の弊社ブログをご参考に設定をお試しください。
おわりに
AWS WAF のレートベースルールの設定方法についてのお問い合わせを受けることが何度かありましたため、ブログにしてみました。 AWS WAF セキュリティオートメーションについての紹介も書きたかったのですが、長くなってしまったのでまたの機会にします。