【目次】
1. はじめに
今回は AWS WAF の二つのアップデート情報を解説していきます。
https://docs.aws.amazon.com/waf/latest/developerguide/waf-captcha-and-challenge.html
一つ目は、これまであった CAPTCHA アクションに加えて、Challenge アクションが追加されました。
CAPTCHA アクションの詳細については以下のブログでご確認していただきたいのですが、bot 対策などで有効な人間かどうかを判定するようなパズルを提供してくれるアクションになります。
今回追加された Challenge アクションは、サイト利用ユーザーに対してなんらかの入力や選択を求めずにバックグラウンドで bot の判定をしてくれるアクションとなります。
https://www.wafcharm.com/jp/blog/aws-waf-captcha-action-available-ja/
https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-type-geo-match.html
二つ目は、国別制限のルールでさらに詳細な地域コードが利用できるようになりました。
簡単なイメージですとアメリカを指定する際に州単位でも指定できるといったこととなります。
2. Challenge アクション の設定方法と挙動
ルールの作成画面で Action を選択する際に Challenge が存在することが確認できます。
チャレンジの設定にはトークンの使用できる期間も設定され、デフォルトでは 300 秒が設定されます。
期間の変更も可能です。
実際に Challenge が実行されているか確認するため、curl でアクセスしてみます。
$ curl -v https://XXXXXXXXXXXX.us-east-1.amazonaws.com/test/login * Trying 52.72.XXX.XXX... * TCP_NODELAY set * Connected to hgk1gtihdb.execute-api.us-east-1.amazonaws.com (52.72.XXX.XXX) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/cert.pem CApath: none * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 * ALPN, server accepted to use h2 * Server certificate: * subject: CN=*.execute-api.us-east-1.amazonaws.com * start date: Jun 22 00:00:00 2022 GMT * expire date: Jul 21 23:59:59 2023 GMT * subjectAltName: host "XXXXXXXXXXXX.us-east-1.amazonaws.com" matched cert's "*.execute-api.us-east-1.amazonaws.com" * issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon * SSL certificate verify ok. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x7fb37f808200) > GET /test/login HTTP/2 > Host: XXXXXXXXXXXX.us-east-1.amazonaws.com > User-Agent: curl/7.64.1 > Accept: */* > * Connection state changed (MAX_CONCURRENT_STREAMS == 128)! < HTTP/2 202 < date: Fri, 28 Oct 2022 02:05:45 GMT < content-type: application/json < content-length: 0 < x-amzn-requestid: 5c558c9b-0cad-467c-b564-d13a814448ff < x-amzn-errortype: ForbiddenException < x-amz-apigw-id: asXXEESboAMFpQg= < cache-control: no-store, max-age=0 < x-amzn-waf-action: challenge < * Connection #0 to host XXXXXXXXXXXX.us-east-1.amazonaws.com left intact * Closing connection 0
Challenge アクションが実行され、HTTP ステータスコード 202 が返されていることがわかりました。
Challenge の仕組みは Accept ヘッダに text/html 入れると script 返り、それを評価することで判定しているようです。
そのため、Challenge アクションは GET text/htmlリクエストに対してのみ使用してくださいといった注意事項もありました。
https://docs.aws.amazon.com/waf/latest/developerguide/waf-captcha-and-challenge-how-it-works.html
https://docs.aws.amazon.com/waf/latest/developerguide/waf-captcha-and-challenge-best-practices.html
3. 国別制限のルールで詳細な地域コードの設定方法
国/地域コードは ISO 3166-2 が利用されるということです。
https://en.wikipedia.org/wiki/ISO_3166-2
日本でいうと以下のように県の単位で制御が可能なようです。東京を表すと JP-13 ということになります。
https://en.wikipedia.org/wiki/Prefectures_of_Japan
ルールの設定方法はこれまでの国別制限ルールのようにそのままアクションを指定するわけではなく、一度ラベルを取得した後に、ラベルで判定することで利用できます。
ラベルの利用例
https://www.wafcharm.com/jp/blog/aws-waf-label-usage-ja/
国別制限ルールの場合
- 特定の国にマッチする条件に対してアクションを指定するのみで完了(ルール1)
地域コードで判定したい場合
- 特定の国にマッチする条件に対してCOUNTアクションのルールを作成(ルール1)
- 上記ルールで生成されたラベルを利用してラベルマッチ条件でアクションを指定(ルール2)
JSON 形式で比較してみましょう。
国別制限ルールの場合
ルール1(アメリカをBLOCK)
{ "Name": "geo", "Priority": 0, "Action": { "Block": {} }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "geo" }, "Statement": { "GeoMatchStatement": { "CountryCodes": [ "US" ] } } }
地域コードで判定したい場合
ルール1(アメリカのラベルを取得。アクションはCOUNT)
{ "Name": "geo", "Priority": 0, "Action": { "Count": {} }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "geo" }, "Statement": { "GeoMatchStatement": { "CountryCodes": [ "US" ] } } }
ルール2(アメリカのラベルを利用して、オレゴン州とワシントン州以外をBLOCK)
{ "Name": "blockUSButNotOROrWA", "Priority": 11, "Statement": { "AndStatement": { "Statements": [ { "LabelMatchStatement": { "Scope": "LABEL", "Key": "awswaf:clientip:geo:country:US" } }, { "NotStatement": { "Statement": { "OrStatement": { "Statements": [ { "LabelMatchStatement": { "Scope": "LABEL", "Key": "awswaf:clientip:geo:region:US-OR" } }, { "LabelMatchStatement": { "Scope": "LABEL", "Key": "awswaf:clientip:geo:region:US-WA" } } ] } } } } ] } }, "Action": { "Block": {} }, "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "blockUSButNotOROrWA" } }
地域コードで指定したい場合は、一度ラベルを取得するためのルールが必要と考えれば、その後の利用方法は特に難しくはないかと思います。
4. WafCharm ルールでの利用方法
現在のところ、二つの機能を利用したデフォルトのルールの作成予定はございません。
5. おわりに
Challenge アクションはログインページへ設定することで、利用ユーザーへ過度な負担を強いることなく、不要なアクセスを減らすことが期待できるのではないでしょうか。
地域別での制限については日本では利用イメージがあまり思いつきませんが、アメリカなどであれば州ごとでの制限といった機能も有効な状況があるかもしれません。