AWS WAF でルールグループのオーバーライドアクションを設定した時の挙動を検証してみた

AWS WAF でルールグループのオーバーライドアクションを設定した時の挙動を検証してみた

2026.01.09

いわさです。

AWS WAF を使うとき、Web ACL のルールをカウントモードで運用することがあります。
誤検知を防ぐ場合に一定期間カウントモードで挙動を確認したい時や、あとはラベル付与だけしてやって後続のルールで複合的に判定する場合などです。

また、AWS WAF にはルールグループというものがあり、複数のルールをグルーピングし Web ACL 側ではそのルールグループを使用することが出来ます。
AWS マネージドルールなどはルールグループに該当しますが、ユーザーがカスタムルールグループを作成することも出来ます。

このルールグループを使ったとき、ルールアクションをカウントモードでオーバーライドできるのですが、個別のルールごとにオーバーライドする場合とルールグループとしてオーバーライドする場合で少し挙動が変わることに気が付きました。
そして、Web ACL にルールグループを追加する時、ルールグループに対するカウントアクションのオーバーライドは初期設定で可能なのですが、個別のルールのオーバーライドは追加後の再設定が必要です。

4B42D71C-5C04-48FB-B2D0-36B1E619E936.png

検証した内容を共有します。

ルールグループを作成

新規ルールグループに次の3つのルールを作成しました。

13FB3104-5CDB-446C-B7F4-E97164824DD4.png

ひとつめのルールはhogeヘッダーにaaaという値が設定されている場合にALLOWアクションを実行します。

9BA91CC2-9E6D-49E6-A7D2-3DB818DE83B3.png

ふたつめのルールはfugaヘッダーにaaaという値が設定されている場合はCOUNTアクションを実行しつつカスタムラベルを付与します。

66555343-70DA-4309-AEAF-F94E8BF57142.png

みっつめのルールはpiyoヘッダーにbbbという値が設定されている場合にBLOCKアクションを実行します。

image.png

このルールグループを Web ACL に設定し、CloudFront ディストリビューションに関連付けしました。

DE6C2161-511D-4770-B20B-2F74697F029B.png

リクエストを送信してみる

ではここで CloudFront ディストリビューションへリクエストを送信し、その際のレスポンスと Web ACL が出力するログを確認してみましょう。
すべてのルールに該当するようにリクエストを送信してみます。

% curl https://hogecf.tak1wa.com/ -H "hoge:aaa" -H "fuga:aaa" -H "piyo:aaa" -I
HTTP/2 200 
content-type: text/html
content-length: 4
date: Thu, 08 Jan 2026 21:21:19 GMT
last-modified: Fri, 08 Aug 2025 19:51:57 GMT
etag: "ea703e7aa1efda0064eaa507d9e8ab7e"
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 5f5be34f5f7e4bb19334d6ed8ab76338.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P8
x-amz-cf-id: fKBvvdCpVP_WzdVI7I0VcX1XdXzxScdxN56ibbQArrYeapNJxcehKA==

レスポンスとしては優先度でいうとルール1に該当するはずなので許可されていますね。ここは期待どおりです。
この時、ログには以下のように出力されます。

{
    "timestamp": 1767907445280,
    "formatVersion": 1,
    "webaclId": "arn:aws:wafv2:us-east-1:123456789012:global/webacl/hoge0108cf/0ef9563b-f9b1-4b5a-a6aa-5d4c16dfd1e7",
    "terminatingRuleId": "hoge0108rule",
    "terminatingRuleType": "GROUP",
    "action": "ALLOW",
    "terminatingRuleMatchDetails": [],
    "httpSourceName": "CF",
    "httpSourceId": "E3RJ0R1LD03T78",
    "ruleGroupList": [
        {
            "ruleGroupId": "arn:aws:wafv2:us-east-1:123456789012:global/rulegroup/hoge0108rule/2871a7c5-940d-45ce-9335-d34f52ec79df",
            "terminatingRule": {
                "ruleId": "hoge-rule1",
                "action": "ALLOW",
                "ruleMatchDetails": null
            },
            "nonTerminatingMatchingRules": [],
            "excludedRules": null,
            "customerConfig": null
        }
    ],
    "rateBasedRuleList": [],
    "nonTerminatingMatchingRules": [],
    "requestHeadersInserted": null,
    "responseCodeSent": null,
    "httpRequest": {
        "clientIp": "203.0.113.1",
        "country": "JP",
        "headers": [
            {
                "name": "host",
                "value": "hogecf.tak1wa.com"
            },
            {
                "name": "user-agent",
                "value": "curl/8.13.0"
            },
            {
                "name": "accept",
                "value": "*/*"
            },
            {
                "name": "hoge",
                "value": "aaa"
            },
            {
                "name": "fuga",
                "value": "aaa"
            },
            {
                "name": "piyo",
                "value": "aaa"
            }
        ],
        "uri": "/",
        "args": "",
        "httpVersion": "HTTP/2.0",
        "httpMethod": "HEAD",
        "requestId": "utKr_Ie-dspOf_ZvaZbcF-Bb6-dUnQXKQAQYkysZwG8HDuD5jboFPw==",
        "fragment": "",
        "scheme": "https",
        "host": "hogecf.tak1wa.com"
    },
    "ja3Fingerprint": "446fb8bd613d17e5d44bd3b288ac94ca",
    "ja4Fingerprint": "t13d3012h2_1d37bd780c83_882d495ac381"
}

ruleGroupListに注目して頂きたいのですが、ルール1だけ評価されていることが確認出来ます。
カスタムラベルも付与されていないですね。
ルールグループの仕様としてALLOWBLOCKなどの終了アクションの判定を行った場合、ルールグループ内のルール評価はそこで終わり、Web ACL に終了結果を返します。そのためルール1でALLOW判定したのでルール2とルール3は評価されませんでした。

では今度はルール1だけ該当しないようにしてみましょう。

% curl https://hogecf.tak1wa.com/ -H "hoge:bbb" -H "fuga:aaa" -H "piyo:aaa" -I
HTTP/2 403 
server: CloudFront
date: Thu, 08 Jan 2026 21:22:31 GMT
content-type: text/html
content-length: 919
x-cache: Error from cloudfront
via: 1.1 d71be4bfe4bfffa929ab4fc99222c3ba.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P8
x-amz-cf-id: M7eeCcih5nbEaWlTF1VzoodmjTLTxn0UfnCYIrAzavB-T_Pv4uSmPQ==

レスポンスとしてはルール3に該当して拒否されました。これも期待どおりです。
この時のログは以下です。

{
    "timestamp": 1767907351343,
    "formatVersion": 1,
    "webaclId": "arn:aws:wafv2:us-east-1:123456789012:global/webacl/hoge0108cf/0ef9563b-f9b1-4b5a-a6aa-5d4c16dfd1e7",
    "terminatingRuleId": "hoge0108rule",
    "terminatingRuleType": "GROUP",
    "action": "BLOCK",
    "terminatingRuleMatchDetails": [],
    "httpSourceName": "CF",
    "httpSourceId": "E3RJ0R1LD03T78",
    "ruleGroupList": [
        {
            "ruleGroupId": "arn:aws:wafv2:us-east-1:123456789012:global/rulegroup/hoge0108rule/2871a7c5-940d-45ce-9335-d34f52ec79df",
            "terminatingRule": {
                "ruleId": "hoge-rule3",
                "action": "BLOCK",
                "ruleMatchDetails": null
            },
            "nonTerminatingMatchingRules": [
                {
                    "ruleId": "hoge-rule2",
                    "action": "COUNT",
                    "ruleMatchDetails": []
                }
            ],
            "excludedRules": null,
            "customerConfig": null
        }
    ],
    "rateBasedRuleList": [],
    "nonTerminatingMatchingRules": [],
    "requestHeadersInserted": [
        {
            "name": "x-amzn-waf-hoge",
            "value": "hoge-rule2"
        }
    ],
    "responseCodeSent": null,
    "httpRequest": {
        "clientIp": "203.0.113.1",
        "country": "JP",
        "headers": [
            {
                "name": "host",
                "value": "hogecf.tak1wa.com"
            },
            {
                "name": "user-agent",
                "value": "curl/8.13.0"
            },
            {
                "name": "accept",
                "value": "*/*"
            },
            {
                "name": "hoge",
                "value": "bbb"
            },
            {
                "name": "fuga",
                "value": "aaa"
            },
            {
                "name": "piyo",
                "value": "aaa"
            }
        ],
        "uri": "/",
        "args": "",
        "httpVersion": "HTTP/2.0",
        "httpMethod": "HEAD",
        "requestId": "M7eeCcih5nbEaWlTF1VzoodmjTLTxn0UfnCYIrAzavB-T_Pv4uSmPQ==",
        "fragment": "",
        "scheme": "https",
        "host": "hogecf.tak1wa.com"
    },
    "labels": [
        {
            "name": "awswaf:123456789012:rulegroup:hoge0108rule:iwasa:hoge"
        }
    ],
    "ja3Fingerprint": "446fb8bd613d17e5d44bd3b288ac94ca",
    "ja4Fingerprint": "t13d3012h2_1d37bd780c83_882d495ac381"
}

今度はルール2とルール3に該当していますが、ルール2がCOUNTアクションのため非終了ルールとなり、後続のルール3が評価されています。
このように終了ルールと非終了ルールの概念があることを認識しておきます。

カウントモードでオーバーライドする

Web ACL でルールグループを使う場合、アクションをCOUNTでオーバーライドすることが出来ます。
俗に言う「COUNTモードで運用」というやつです。
このCOUNTでのオーバーライド、ルールグループ自体のオーバーライドも出来ますし、ルールグループ内のルールごとにオーバーライドも出来ます。

個別のルールをオーバーライドする場合と、ルールグループをオーバーライドする場合、それぞれどういう挙動になるのでしょうか。

個別のルールをオーバーライドする場合

まず個別のルールをオーバーライドする場合を試してみましょう。

645F360F-444B-42BE-91E4-FE326CBF8DFC.png

ルール1に該当するリクエストを送信した時、先程はルール1のみ評価されましたが、前述のとおりカウントでオーバーライドすることで非終了ルールとなり、後続のルールも評価されていることがログから確認出来ます。
ルール2のカスタムラベルも設定されていますね。

{
    "timestamp": 1767907562629,
    "formatVersion": 1,
    "webaclId": "arn:aws:wafv2:us-east-1:123456789012:global/webacl/hoge0108cf/0ef9563b-f9b1-4b5a-a6aa-5d4c16dfd1e7",
    "terminatingRuleId": "Default_Action",
    "terminatingRuleType": "REGULAR",
    "action": "ALLOW",
    "terminatingRuleMatchDetails": [],
    "httpSourceName": "CF",
    "httpSourceId": "E3RJ0R1LD03T78",
    "ruleGroupList": [
        {
            "ruleGroupId": "arn:aws:wafv2:us-east-1:123456789012:global/rulegroup/hoge0108rule/2871a7c5-940d-45ce-9335-d34f52ec79df",
            "terminatingRule": null,
            "nonTerminatingMatchingRules": [
                {
                    "ruleId": "hoge-rule1",
                    "action": "COUNT",
                    "overriddenAction": "ALLOW",
                    "ruleMatchDetails": []
                },
                {
                    "ruleId": "hoge-rule2",
                    "action": "COUNT",
                    "overriddenAction": "COUNT",
                    "ruleMatchDetails": []
                },
                {
                    "ruleId": "hoge-rule3",
                    "action": "COUNT",
                    "overriddenAction": "BLOCK",
                    "ruleMatchDetails": []
                }
            ],
            "excludedRules": null,
            "customerConfig": null
        }
    ],
    "rateBasedRuleList": [],
    "nonTerminatingMatchingRules": [],
    "requestHeadersInserted": null,
    "responseCodeSent": null,
    "httpRequest": {
        "clientIp": "203.0.113.1",
        "country": "JP",
        "headers": [
            {
                "name": "host",
                "value": "hogecf.tak1wa.com"
            },
            {
                "name": "user-agent",
                "value": "curl/8.13.0"
            },
            {
                "name": "accept",
                "value": "*/*"
            },
            {
                "name": "hoge",
                "value": "aaa"
            },
            {
                "name": "fuga",
                "value": "aaa"
            },
            {
                "name": "piyo",
                "value": "aaa"
            }
        ],
        "uri": "/",
        "args": "",
        "httpVersion": "HTTP/2.0",
        "httpMethod": "HEAD",
        "requestId": "gh9a-PIyoiaO4Oc7ARm8YuOPdMy4KseRKwdDz5yORTNFuzKY3k9Csg==",
        "fragment": "",
        "scheme": "https",
        "host": "hogecf.tak1wa.com"
    },
    "labels": [
        {
            "name": "awswaf:123456789012:rulegroup:hoge0108rule:iwasa:hoge"
        }
    ],
    "ja3Fingerprint": "446fb8bd613d17e5d44bd3b288ac94ca",
    "ja4Fingerprint": "t13d3012h2_1d37bd780c83_882d495ac381"
}

terminatingRulenullになり、すべてのルールがnonTerminatingMatchingRulesになっていますね。
そしてそれぞれのルールにactionoverriddenActionが出力されています。
actionは今回上書きされた結果で、overriddenActionは上書きされた本来のアクションを示している感じですね。なるほど。

ルールグループをオーバーライドする

続いてルールグループをオーバーライドする場合も確認してみます。

B5271D83-3DB3-4BF7-883F-0D16D95B3C74.png

ルール1に該当するリクエストの場合のログは次のようになりました。

{
    "timestamp": 1767908206384,
    "formatVersion": 1,
    "webaclId": "arn:aws:wafv2:us-east-1:123456789012:global/webacl/hoge0108cf/0ef9563b-f9b1-4b5a-a6aa-5d4c16dfd1e7",
    "terminatingRuleId": "Default_Action",
    "terminatingRuleType": "REGULAR",
    "action": "ALLOW",
    "terminatingRuleMatchDetails": [],
    "httpSourceName": "CF",
    "httpSourceId": "E3RJ0R1LD03T78",
    "ruleGroupList": [
        {
            "ruleGroupId": "arn:aws:wafv2:us-east-1:123456789012:global/rulegroup/hoge0108rule/2871a7c5-940d-45ce-9335-d34f52ec79df",
            "terminatingRule": {
                "ruleId": "hoge-rule1",
                "action": "ALLOW",
                "ruleMatchDetails": null
            },
            "nonTerminatingMatchingRules": [],
            "excludedRules": null,
            "customerConfig": null
        }
    ],
    "rateBasedRuleList": [],
    "nonTerminatingMatchingRules": [
        {
            "ruleId": "hoge0108rule",
            "action": "COUNT",
            "ruleMatchDetails": []
        }
    ],
    "requestHeadersInserted": null,
    "responseCodeSent": null,
    "httpRequest": {
        "clientIp": "203.0.113.1",
        "country": "JP",
        "headers": [
            {
                "name": "host",
                "value": "hogecf.tak1wa.com"
            },
            {
                "name": "user-agent",
                "value": "curl/8.13.0"
            },
            {
                "name": "accept",
                "value": "*/*"
            },
            {
                "name": "hoge",
                "value": "aaa"
            },
            {
                "name": "fuga",
                "value": "aaa"
            },
            {
                "name": "piyo",
                "value": "aaa"
            }
        ],
        "uri": "/",
        "args": "",
        "httpVersion": "HTTP/2.0",
        "httpMethod": "HEAD",
        "requestId": "8rlpGVnghrINXasoRzDljz-1UsMBZYpFh0pIYGnsbPN9yoHIoFO7bQ==",
        "fragment": "",
        "scheme": "https",
        "host": "hogecf.tak1wa.com"
    },
    "ja3Fingerprint": "446fb8bd613d17e5d44bd3b288ac94ca",
    "ja4Fingerprint": "t13d3012h2_1d37bd780c83_882d495ac381"
}

ルール1のみ評価されており、ルール2とルール3の評価は行われていませんね。カスタムラベルも付与されていませんでした。
nonTerminatingMatchingRulesも設定されていません。

ルール1に該当せずに、ルール2とルール3に該当するリクエストの場合はどうなるでしょうか。

% curl https://hogecf.tak1wa.com/ -H "hoge:bbb" -H "fuga:aaa" -H "piyo:aaa" -I
HTTP/2 200 
content-type: text/html
content-length: 4
date: Thu, 08 Jan 2026 21:37:04 GMT
last-modified: Fri, 08 Aug 2025 19:51:57 GMT
etag: "ea703e7aa1efda0064eaa507d9e8ab7e"
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 947d3063108323e010d752708d6a69bc.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P8
x-amz-cf-id: SJ_4C12deB68UfNwTgpTTkO_1X1fq1H5f0T5BKPSQdCkb3EdXbrkmw==

レスポンスとしてはカウントモードに設定したためか、拒否ではなく許可されていますね。
ログは次のようになりました。

{
    "timestamp": 1767908223839,
    "formatVersion": 1,
    "webaclId": "arn:aws:wafv2:us-east-1:123456789012:global/webacl/hoge0108cf/0ef9563b-f9b1-4b5a-a6aa-5d4c16dfd1e7",
    "terminatingRuleId": "Default_Action",
    "terminatingRuleType": "REGULAR",
    "action": "ALLOW",
    "terminatingRuleMatchDetails": [],
    "httpSourceName": "CF",
    "httpSourceId": "E3RJ0R1LD03T78",
    "ruleGroupList": [
        {
            "ruleGroupId": "arn:aws:wafv2:us-east-1:123456789012:global/rulegroup/hoge0108rule/2871a7c5-940d-45ce-9335-d34f52ec79df",
            "terminatingRule": {
                "ruleId": "hoge-rule3",
                "action": "BLOCK",
                "ruleMatchDetails": null
            },
            "nonTerminatingMatchingRules": [
                {
                    "ruleId": "hoge-rule2",
                    "action": "COUNT",
                    "ruleMatchDetails": []
                }
            ],
            "excludedRules": null,
            "customerConfig": null
        }
    ],
    "rateBasedRuleList": [],
    "nonTerminatingMatchingRules": [
        {
            "ruleId": "hoge0108rule",
            "action": "COUNT",
            "ruleMatchDetails": []
        }
    ],
    "requestHeadersInserted": null,
    "responseCodeSent": null,
    "httpRequest": {
        "clientIp": "203.0.113.1",
        "country": "JP",
        "headers": [
            {
                "name": "host",
                "value": "hogecf.tak1wa.com"
            },
            {
                "name": "user-agent",
                "value": "curl/8.13.0"
            },
            {
                "name": "accept",
                "value": "*/*"
            },
            {
                "name": "hoge",
                "value": "bbb"
            },
            {
                "name": "fuga",
                "value": "aaa"
            },
            {
                "name": "piyo",
                "value": "aaa"
            }
        ],
        "uri": "/",
        "args": "",
        "httpVersion": "HTTP/2.0",
        "httpMethod": "HEAD",
        "requestId": "SJ_4C12deB68UfNwTgpTTkO_1X1fq1H5f0T5BKPSQdCkb3EdXbrkmw==",
        "fragment": "",
        "scheme": "https",
        "host": "hogecf.tak1wa.com"
    },
    "labels": [
        {
            "name": "awswaf:123456789012:rulegroup:hoge0108rule:iwasa:hoge"
        }
    ],
    "ja3Fingerprint": "446fb8bd613d17e5d44bd3b288ac94ca",
    "ja4Fingerprint": "t13d3012h2_1d37bd780c83_882d495ac381"
}

以下のドキュメントの次のような記述があります。

これは、AWS WAF によるルールグループ自体の評価方法を変更しないため、ルールグループ内のルールをテストするための適切なオプションではありません。これは、ルールグループの評価から保護パック (ウェブ ACL) に返される結果の AWS WAF による処理方法にのみ影響します。ルールグループ内のルールをテストする場合は、前述のセクションで説明したオプション ルールグループのルールアクションの上書き を使用します。

https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-rule-group-override-options.html

何を言ってるのか最初よくわからなかったのですが、ルールグループの中の個別のルールをひとつづつテストしたい場合は前述の個別ルールのオーバーライドを使いましょうという感じっぽいですね。
ルールグループ全体をオーバーライドしてしまうと、終了ルールで中断されてしまい優先度の低いルールのテストに支障が出る場合があるためでしょうか。

普通にルールグループ自体のアクションで終了させたくない(誤検知を防ぐ)という場合であればこのルールグループのオーバーライドで良さそうだなと思いました。

さいごに

本日は AWS WAF でルールグループのオーバーライドアクションを設定した時の挙動を検証してみました。

ルールグループの開発中に Web ACL に設定して個別のルールをひとつづつテストしたい場合など、終了アクションによるルールグループ評価の中断を回避する必要がある場合は個別ルールのオーバーライドを使いましょう。
それ以外の場合、例えばルールグループを追加するが誤検知でブロックされないようにしたい場合はルールグループのオーバーライド機能で良さそうです。

この記事をシェアする

FacebookHatena blogX

関連記事