Rate limiting websocket connections not working

Hello!

I’ve been trying to apply rate-limiting for a service that clients connect to via WebSocket connections.

Following the guide: https://istio.io/latest/docs/tasks/policy-enforcement/rate-limit/#local-rate-limit. At first, I thought that the rate-limiting wasn’t working because I applied it to the wrong port. On then forward I proceeded to limit to port 0 (which limited the connections on all ports as far as I understood how it works) but the WebSocket connections weren’t limited. I couldn’t find any documentation around envoy nor Istio around websocket filters or any examples of how to handle this use case.

P.S. Circuit breaking isn’t a possible solution since I want to rate-limit the burst of traffic type of scenarios to the service.

Here’s the config that I use.

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: service-name
spec:
  workloadSelector:
    labels:
      app: service-name
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: SIDECAR_INBOUND
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.filters.http.local_ratelimit
          typed_config:
            "@type": type.googleapis.com/udpa.type.v1.TypedStruct
            type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
            value:
              stat_prefix: http_local_rate_limiter
    - applyTo: HTTP_ROUTE
      match:  
        context: SIDECAR_INBOUND
        routeConfiguration:
          portNumber: 0

      patch:
        operation: MERGE
        value:
          typed_per_filter_config:
            envoy.filters.http.local_ratelimit:
              "@type": type.googleapis.com/udpa.type.v1.TypedStruct
              type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
              value:
                stat_prefix: http_local_rate_limiter
                token_bucket:
                  max_tokens: 10
                  tokens_per_fill: 1
                  fill_interval: 9000s
                filter_enabled:
                  runtime_key: local_rate_limit_enabled
                  default_value:
                    numerator: 100
                    denominator: HUNDRED
                filter_enforced:
                  runtime_key: local_rate_limit_enforced
                  default_value:
                    numerator: 100
                    denominator: HUNDRED
                response_headers_to_add:
                  - append: true
                    header:
                      key: x-local-rate-limit
                      value: 'true'

The non-specific config also doesn’t seem to limit the websocket connections.

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: a-service
spec:
  workloadSelector:
    labels:
      app: a-service
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: SIDECAR_INBOUND
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.filters.http.local_ratelimit
          typed_config:
            "@type": type.googleapis.com/udpa.type.v1.TypedStruct
            type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
            value:
              stat_prefix: http_local_rate_limiter
              token_bucket:
                max_tokens: 10
                tokens_per_fill: 10
                fill_interval: 30s
              filter_enabled:
                runtime_key: local_rate_limit_enabled
                default_value:
                  numerator: 100
                  denominator: HUNDRED
              filter_enforced:
                runtime_key: local_rate_limit_enforced
                default_value:
                  numerator: 100
                  denominator: HUNDRED
              response_headers_to_add:
                - append: false
                  header:
                    key: x-local-rate-limit
                    value: 'true'

Any tips and or help is appreciated!

Best,
Risto

This is now Resolved.

The issue I ran into is that the websocket ports didn’t have the HTTP prefix in the port name.