Trying to get Local rate limit for a service, by user IP working.
Have tried Global rate limit, which have got working, however this gets applied to the entire mesh whereas I am trying to rate limit an individual service.
This is my EnvoyFilter config:
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: ingressgateway-settings
namespace: istio-system
spec:
configPatches:
- applyTo: NETWORK_FILTER
match:
listener:
filterChain:
filter:
name: "envoy.http_connection_manager"
patch:
operation: MERGE
value:
name: envoy.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
skip_xff_append: false
use_remote_address: true
xff_num_trusted_hops: 1
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: test-local-ratelimit-svc
namespace: applications
spec:
workloadSelector:
labels:
app: test
configPatches:
- applyTo: HTTP_FILTER
listener:
filterChain:
filter:
name: "envoy.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:
vhost:
name: "inbound|http|3000"
patch:
operation: MERGE
value:
route:
rate_limits:
- actions:
- remote_address: {}
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
descriptors:
- entries:
- key: remote_address
token_bucket:
max_tokens: 5
tokens_per_fill: 5
fill_interval: 60s
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'
token_bucket:
max_tokens: 100
tokens_per_fill: 100
fill_interval: 60s
This produces the following logs in the envoy-proxy:
warning envoy config gRPC config for type.googleapis.com/envoy.config.listener.v3.Listener rejected: Error adding/updating listener(s) virtualInbound: Proto constraint validation failed (LocalRateLimitValidationError.Descriptors[i]: ["embedded message failed validation"] | caused by LocalRateLimitDescriptorValidationError.Entries[i]: ["embedded message failed validation"] | caused by EntryValidationError.Value: ["value length must be at least " '\x01' " runes"]): stat_prefix: "http_local_rate_limiter"
Have tried adding a value, for my IP to test if it would be blocked.
descriptors:
- entries:
- key: remote_address
value: xxx.xxx.xxx.xxx
token_bucket:
max_tokens: 5
tokens_per_fill: 5
fill_interval: 60s
However this results only in the default requests of 100, not the 5 trying to be applied. Thinking maybe the remote_address of my IP is not being passed all the way through the mesh (have had this working on global setup)