How can I set an envoy local rate limit, on all the paths starting with a given path?
eg: I want to enforce the same rate limit on the URLs starting with : /swagger-ui/...
I've tried a couple of things, including passing a regex in the path: ^/swagger-ui/.*$ but nothing seems to work.
Thanks
My envoy yaml file looks like this:
static_resources:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: AUTO
stat_prefix: ingress_http
http_filters:
- name: envoy.filters.http.local_ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
stat_prefix: http_local_rate_limiter
local_rate_limit_per_downstream_connection: false
filter_enabled:
runtime_key: test_enabled
default_value:
numerator: 100
denominator: HUNDRED
filter_enforced:
runtime_key: test_enforced
default_value:
numerator: 100
denominator: HUNDRED
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match: { prefix: "/"}
route:
cluster: middleware
timeout: { seconds: 120 }
rate_limits:
- actions: # any actions in here
- request_headers:
header_name: ":path"
descriptor_key: path
typed_per_filter_config:
envoy.filters.http.local_ratelimit:
"@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
stat_prefix: test
token_bucket:
max_tokens: 300
tokens_per_fill: 1
fill_interval: 600s
filter_enabled:
runtime_key: test_enabled
default_value:
numerator: 100
denominator: HUNDRED
filter_enforced:
runtime_key: test_enforced
default_value:
numerator: 100
denominator: HUNDRED
descriptors:
- entries:
- key: path
value: /swagger-ui/
token_bucket:
max_tokens: 15
tokens_per_fill: 1
fill_interval: 600s
- entries:
- key: path
value: /user/create
token_bucket:
max_tokens: 3
tokens_per_fill: 1
fill_interval: 600s
clusters:
- name: middleware
connect_timeout: 1s
type: STRICT_DNS
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: middleware
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: middleware
port_value: 8080
admin:
access_log_path: "/dev/null"
address:
socket_address:
address: 0.0.0.0
port_value: 8001
You need to define two routes (in route_config.virtual_hosts[0].routes
):
/swagger-ui/*
(prefix: /swagger-ui/
)/
)Then, configure the local rate limit to only apply to the first route (paths starting with /swagger-ui/
).
Here is a working configuration:
static_resources:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
http_filters:
- name: envoy.filters.http.local_ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
stat_prefix: http_local_rate_limiter
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/swagger-ui/" }
route: { cluster: middleware }
typed_per_filter_config:
envoy.filters.http.local_ratelimit:
"@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
stat_prefix: http_local_rate_limiter
token_bucket:
max_tokens: 10
tokens_per_fill: 1
fill_interval: 10s
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'
- match: { prefix: "/" }
route: { cluster: middleware }
clusters:
- name: middleware
connect_timeout: 1s
type: STRICT_DNS
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: middleware
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: middleware
port_value: 8080
You can configure the rate limit values according to your needs.
The config above is inspired from the official documentation: https://github.com/envoyproxy/envoy/blob/9347baf/docs/root/configuration/http/http_filters/_include/local-rate-limit-route-specific-configuration.yaml.