GoogleCloudPlatform / terraform-google-cloud-armor

Deploy Cloud Armor security policy
https://registry.terraform.io/modules/GoogleCloudPlatform/cloud-armor/google
Apache License 2.0
37 stars 30 forks source link

Question about applying multiple rate limiting rules #137

Open samlevy3 opened 1 month ago

samlevy3 commented 1 month ago

Hello!

I had a question about whether it was possible to apply multiple rate limiting rules for requests to the same path (/example) (want to limit on IP and separately limit on JA3 signature).

Specifying two rules doesn't seem to work because if I did something like this:

// RULE #1 
"throttle_ip" = {
    action        = "throttle"
    priority      = 13
    match {
        expr {
            expression = "request.path.matches('/example')"
        }
    } 

    rate_limit_options = {
        conform_action                       = "allow"
        exceed_action                        = "deny(429)"
        rate_limit_http_request_count        = 10
        rate_limit_http_request_interval_sec = 60
        enforce_on_key                       = "IP"
    }
}

// RULE #2
"throttle_fingerprint" = {
    action        = "throttle"
    priority      = 14
    match {
        expr {
            expression = "request.path.matches('/example')"
        }
    } 

    rate_limit_options = {
        conform_action                       = "allow"
        exceed_action                        = "deny(429)"
        rate_limit_http_request_count        = 10
        rate_limit_http_request_interval_sec = 600
        enforce_on_key                       = "TLS_JA3_FINGERPRINT"
    }
}

Then all requests would match the first rule (priority 13) and would either be denied or allowed by that rule. As a result, the only throttling applied would be by IP and it would never throttle by fingerprint (At least that is my understanding).

I then saw an option to rate limit on multiple keys using enforce_on_key_configs (https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_security_policy#enforce_on_key_configs).

However, the documentation says "If specified, any combination of enforce_on_key_type/enforce_on_key_name is treated as the key on which rate limit threshold/action is enforced". I found the word choice of any combination vague because I couldn't tell if it was JUST the unique combination of keys or if it essentially created multiple unique keys to rate limit through different combinations of the keys provided.

For example,

```tf
"throttle_on_ip_and_fingerprint" = {
    action        = "throttle"
    priority      = 13
    match {
        expr {
            expression = "request.path.matches('/example')"
        }
    } 

    rate_limit_options = {
        conform_action                       = "allow"
        exceed_action                        = "deny(429)"
        rate_limit_http_request_count        = 10
        rate_limit_http_request_interval_sec = 60
        enforce_on_key_configs               = [
            {
                enforce_on_key_type: "IP"
            },
            {
                enforce_on_key_type: "TLS_JA3_FINGERPRINT"
            },
        ]
    }
}

I was hoping this would throttle on IP or on TLS_JA3_FINGERPRINT (whichever limit was reached first) but to me it seems more likely that it would throttle on the unique combination of the two. Is that correct? And if so, is there another way to rate limit the same requests using both IP and TLS_JA3_FINGERPRINT?

imrannayer commented 1 month ago

@samlevy3 According to this doc it is unique combination of both keys.

samlevy3 commented 1 month ago

@imrannayer So there is no way to throttle based on IP and also on TLS_JA3_FINGERPRINT?

imrannayer commented 1 month ago

@samlevy3 I am not sure about it. Can u plz open a support ticket for it? Support can help u.