ratelimit icon indicating copy to clipboard operation
ratelimit copied to clipboard

Unlimited rate limit not working

Open abhi93104 opened this issue 2 years ago • 1 comments

What did I expect? If the unlimited condition is matched then the rate limit should not be applied.

I have 2 entries in the rate limit config:

  descriptors:
       - key: remote_address
        value: 182.156.218.11
        rate_limit:
          unlimited: true
      - key: PATH
        value: "/v2/dummy"
        descriptors:
          - key: remote_address
            rate_limit:
              unit: second
              requests_per_unit: 5

When I send more than 5 requests with URL: /v2/dummy from my IP: 182.156.218.11 it applies a rate limit on this URL and gets response 429.

Logs

time="2022-09-23T15:45:47Z" level=debug msg="got descriptor: (PATH=/v2/dummy),(remote_address=182.156.218.11)"
time="2022-09-23T15:45:47Z" level=debug msg="starting get limit lookup"
time="2022-09-23T15:45:47Z" level=debug msg="looking up key: PATH_/v2/dummy"
time="2022-09-23T15:45:47Z" level=debug msg="iterating to next level"
time="2022-09-23T15:45:47Z" level=debug msg="looking up key: remote_address_182.156.218.11"
time="2022-09-23T15:45:47Z" level=debug msg="looking up key: remote_address"
time="2022-09-23T15:45:47Z" level=debug msg="found rate limit: remote_address"
time="2022-09-23T15:45:47Z" level=debug msg="applying limit: 5 requests per MINUTE, shadow_mode: false"

time="2022-09-23T15:45:47Z" level=debug msg="got descriptor: (remote_address=182.156.218.11)"
time="2022-09-23T15:45:47Z" level=debug msg="starting get limit lookup"
time="2022-09-23T15:45:47Z" level=debug msg="looking up key: remote_address_182.156.218.11"
time="2022-09-23T15:45:47Z" level=debug msg="found rate limit: remote_address_182.156.218.11"
time="2022-09-23T15:45:47Z" level=debug msg="descriptor is unlimited, not passing to the cache"

time="2022-09-23T15:45:47Z" level=debug msg="starting cache lookup"
time="2022-09-23T15:45:47Z" level=debug msg="looking up cache key: edge_proxy_per_ip_PATH_/v2/dummy_remote_address_182.156.218.11_1663947900"
time="2022-09-23T15:45:47Z" level=debug msg="cache key: edge_proxy_per_ip_PATH_/v2/dummy_remote_address_182.156.218.11_1663947900 current: 6"
time="2022-09-23T15:45:47Z" level=debug msg="returning normal response"
time="2022-09-23T15:45:47Z" level=debug msg="[gostats] flushing time ratelimit_server.ShouldRateLimit.response_time: 1.000000"

abhi93104 avatar Sep 23 '22 16:09 abhi93104

Envoy filter I m using :

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: filter-ratelimit-svc
  namespace: default
spec:
  workloadSelector:
    labels:
      istio: ingressgateway-istio-default
  configPatches:
    - applyTo: VIRTUAL_HOST
      match:
        context: GATEWAY
        routeConfiguration:
          vhost:
            name: ""
            route:
              action: ANY
      patch:
        operation: MERGE
        # Applies the rate limit rules.
        value:
          rate_limits:
            - actions:
              - metadata:
                  descriptor_key: "PATH"
                  metadata_key:
                    key: example
                    path:
                    - key: uri
              - remote_address: {}
            - actions:
              - remote_address: {}



---


apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: filter-ratelimit
  namespace: default
spec:
  workloadSelector:
    # select by label in the same namespace
    labels:
      istio: ingressgateway-istio-default
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: GATEWAY
        listener:
          filterChain:
            filter:
              name: 'envoy.filters.network.http_connection_manager'
              subFilter:
                name: 'envoy.filters.http.router'
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.filters.http.header_to_metadata
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config
            request_rules:
            - header: ':path'
              on_header_present:
                # use an arbitary name for the namespace
                # will be used later to extract descriptor value
                metadata_namespace: example
                # use an arbitary key for the metadata
                # will be used later to extract descriptor value
                key: uri
                regex_value_rewrite:
                  pattern:
                    # regex matcher
                    google_re2: {}
                    # truncates parameters from path
                    regex: '^(\/[\/\d\w-]+)\??.*$'
                  substitution: '\1'
    # The Envoy config you want to modify
    - applyTo: HTTP_FILTER
      match:
        context: GATEWAY
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
              subFilter:
                name: "envoy.filters.http.router"
      patch:
        operation: INSERT_BEFORE
        # Adds the Envoy Rate Limit Filter in HTTP filter chain.
        value:
          name: envoy.filters.http.ratelimit
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
            # domain can be anything! Match it to the ratelimter service config
            domain: edge_proxy_per_ip
            failure_mode_deny: true
            timeout: 10s
            rate_limit_service:
              grpc_service:
                envoy_grpc:
                  cluster_name: outbound|8081||istio-ratelimit.default.svc.cluster.local
                  authority: istio-ratelimit.default.svc.cluster.local
              transport_api_version: V3


abhi93104 avatar Sep 26 '22 06:09 abhi93104

Hi @abhi93104

Did you try, the "Replace" feature? Feature: https://github.com/envoyproxy/ratelimit/tree/0b2f4d5fb04bf55e1873e2c5e2bb28da67c0643f#replaces Example: https://github.com/envoyproxy/ratelimit/tree/0b2f4d5fb04bf55e1873e2c5e2bb28da67c0643f#example-7

Could you check with the following rate limit configuration?

descriptors:
  - key: remote_address
    value: 182.156.218.11
    rate_limit:
      unlimited: true
      replaces:
        - name: foo_limit
  - key: PATH
    value: "/v2/dummy"
    descriptors:
      - key: remote_address
        rate_limit:
          name: foo_limit
          unit: second
          requests_per_unit: 5

renuka-fernando avatar Oct 21 '22 11:10 renuka-fernando

In your case, both limits are getting applied, i.e. both unlimited and 5 per sec. When multiple limits are applied, the policy that denies the request will always win.

renuka-fernando avatar Oct 21 '22 12:10 renuka-fernando

In your case, both limits are getting applied, i.e. both unlimited and 5 per sec. When multiple limits are applied, the policy that denies the request will always win.

Yes, you are right but that should not happen because unlimited is a special case if we have limits like request_per_limit: 5 and request_per_limit: 10, then the rate limit should apply after 5 as you mentioned. But in the case of unlimited, unlimited should always win. Otherwise what is the point of "unlimited" ratelimit?

abhi93104 avatar Nov 16 '22 07:11 abhi93104

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or "no stalebot" or other activity occurs. Thank you for your contributions.

github-actions[bot] avatar Dec 16 '22 08:12 github-actions[bot]

i agree with @abhi93104 . unlimited should alway win..

kkcmadhu avatar Dec 16 '22 17:12 kkcmadhu

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or "no stalebot" or other activity occurs. Thank you for your contributions.

github-actions[bot] avatar Jan 16 '23 00:01 github-actions[bot]

Hi, @renuka-fernando Checking is there is any update on this issue.

abhi93104 avatar Jan 16 '23 06:01 abhi93104

cc @mattklein123

renuka-fernando avatar Jan 17 '23 03:01 renuka-fernando

Let me know if the fix is required, I will love to contribute also.

abhi93104 avatar Jan 17 '23 03:01 abhi93104

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or "no stalebot" or other activity occurs. Thank you for your contributions.

github-actions[bot] avatar Feb 16 '23 04:02 github-actions[bot]

Yes, you are right but that should not happen because unlimited is a special case

+2 to this.

RaiAnandKr avatar Feb 18 '23 07:02 RaiAnandKr

Hey @abhi93104 I have a question (and it's a bit digressing from the original issue but feels like you are trying to achieve that too with the 'PATH' key in rate limit config so I will shoot). If I want only requests with "GET" method to be rate limited (or request with a certain "PATH"), is there any way to configure "EnvoyFilter" resource so that envoy just doesn't send requests with "PUT" method to rate limit service for e.g.? I wanted to avoid the RTT to the RLS completely. We can achieve this in the rate limit config for sure but curious if we can do this on an EnvoyFilter level and you are aware of it.

RaiAnandKr avatar Feb 18 '23 07:02 RaiAnandKr

I guess, You can filter/conditinally apply rate limit based of http methods header. 

Sent from Yahoo Mail on Android

On Sat, 18 Feb 2023 at 12:46 pm, Anand @.***> wrote:

Hey @abhi93104 I have a question (and it's a bit digressing from the original issue but feels like you are trying to achieve that too with the 'PATH' key in rate limit config so I will shoot). If I want only requests with "GET" method to be rate limited (or request with a certain "PATH"), is there any way to configure "EnvoyFilter" resource so that envoy just doesn't send requests with "PUT" method to rate limit service? I wanted to avoid the RTT to the RLS. We can achieve this in the rate limit config for sure but curious if we can do this on an EnvoyFilter level.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

kkcmadhu avatar Feb 18 '23 16:02 kkcmadhu

I guess, You can filter/conditinally apply rate limit based of http methods header.

oh I see what you mean now (https://www.envoyproxy.io/docs/envoy/v1.14.5/api-v2/api/v2/route/route_components.proto#envoy-api-msg-route-ratelimit-action-headervaluematch). Thanks, that helps.

RaiAnandKr avatar Feb 20 '23 06:02 RaiAnandKr

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or "no stalebot" or other activity occurs. Thank you for your contributions.

github-actions[bot] avatar Mar 22 '23 08:03 github-actions[bot]

This issue has been automatically closed because it has not had activity in the last 37 days. If this issue is still valid, please ping a maintainer and ask them to label it as "help wanted" or "no stalebot". Thank you for your contributions.

github-actions[bot] avatar Mar 29 '23 08:03 github-actions[bot]