envoyproxy/envoy

Local rate limiting using descriptors not taking effect

Open

#14.851 geöffnet am 28. Jan. 2021

Auf GitHub ansehen
 (7 Kommentare) (0 Reaktionen) (0 zugewiesene Personen)C++ (5.373 Forks)batch import
area/ratelimithelp wanted

Repository-Metriken

Stars
 (27.997 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 8T) (378 gemergte PRs in 30 T)

Beschreibung

Description: We have an envoy route_config configured to provide a local rate limit of 1 token per minute, with a refill value of 1.

Using actions and descriptors, we are attempting to configure a higher rate limit when a request has a header of x-product which matches the value in the descriptor. This rate limit is set to 10 tokens per minute with a refill value of 10. Regardless of whether the header is present on the request, the local rate limit is applied, not the token_bucket settings in the descriptor.

We would expect for the descriptor token_bucket rate limit to be applied, not the one on the route.

Repro steps: We are running Envoy on Centos7, using version 1.18 and the configuration file provided below.

The request we are using to test the descriptor rate limit is curl -vv -k https://192.168.193.22:7443/ -H "x-product: product123"

Config:

    "static_resources": {
        "listeners": [
            {
                "name": "listener_secure",
                "address": {
                    "socket_address": {
                        "address": "0.0.0.0",
                        "port_value": 7443
                    }
                },
                "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.wasm",
                                            "typed_config": {
                                                "@type": "type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm",
                                                "config": {
                                                    "name": "my_plugin",
                                                    "root_id": "my_root_id",
                                                    "vm_config": {
                                                        "vm_id": "my_vm_id",
                                                        "runtime": "envoy.wasm.runtime.v8",
                                                        "code": {
                                                            "local": {
                                                                "filename": "/usr/lib/test/wasm/filters/http_key_validation/main.go.wasm"
                                                            }
                                                        },
                                                        "allow_precompiled": true
                                                    }
                                                }
                                            }
                                        },
                                        {
                                            "name": "envoy.filters.http.local_ratelimit",
                                            "typed_config": {
                                                "@type": "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit",
                                                "stat_prefix": "local_rate_limit"
                                            }
                                        },                                        
                                        {
                                            "name": "envoy.filters.http.router"
                                        }
                                    ],
                                    "route_config": {
                                        "name": "local_route",
                                        "virtual_hosts": [
                                            {
                                                "name": "local_service",
                                                "domains": ["*"],
                                                "routes": [
                                                    {
                                                        "match": {
                                                            "prefix": "/"
                                                        },
                                                        "route": {
                                                            "cluster": "service_api"
                                                        },                                                        
                                                        "typed_per_filter_config": {
                                                            "envoy.filters.http.local_ratelimit": {
                                                                "@type": "type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit",
                                                                "stat_prefix": "local_rate_limit",
                                                                "token_bucket": {
                                                                    "max_tokens": 1,
                                                                    "tokens_per_fill": 1,
                                                                    "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"
                                                                    }
                                                                },
                                                                "descriptors": [
                                                                    {
                                                                        "entries": [
                                                                            {
                                                                                "key": "client_product",
                                                                                "value": "product123"
                                                                            }
                                                                        ],
                                                                        "token_bucket": {
                                                                            "max_tokens": 5,
                                                                            "tokens_per_fill": 5,
                                                                            "fill_interval": "60s"
                                                                        }
                                                                    },
                                                                    {
                                                                        "entries": [
                                                                            {
                                                                                "key": "client_product",
                                                                                "value": "productXyz"
                                                                            }
                                                                        ],
                                                                        "token_bucket": {
                                                                            "max_tokens": 7,
                                                                            "tokens_per_fill": 7,
                                                                            "fill_interval": "60s"
                                                                        }
                                                                    }
                                                                ],
                                                                "response_headers_to_add": [
                                                                    {
                                                                        "append": false,
                                                                        "header": {
                                                                            "key": "x-local-rate-limit",
                                                                            "value": "true"
                                                                        }
                                                                    }
                                                                ],
                                                                "stage": 0
                                                            }
                                                        }
                                                    }
                                                ],
                                                "rate_limits": [
                                                    {
                                                        "stage": 0,
                                                        "actions": [
                                                            {
                                                                "request_headers": {
                                                                    "header_name": "x-product",
                                                                    "descriptor_key": "client_product"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                ]
                                            }
                                        ]
                                    },
                                    "access_log": [
                                        {
                                            "name": "envoy.access_loggers.file",
                                            "typed_config": {
                                                "@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog",
                                                "path": "/dev/stdout",
                                                "log_format": {
                                                    "text_format": "[%START_TIME%][access_log] {\"method\":\"%REQ(:METHOD)%\",\"path\":\"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%\",\"protocol\":\"%PROTOCOL%\",\"responseCode\":\"%RESPONSE_CODE%\",\"responseFlags\":\"%RESPONSE_FLAGS%\",\"bytesReceived\":\"%BYTES_RECEIVED%\",\"bytesSent\":\"%BYTES_SENT%\", \"duration\": \"%DURATION%\", \"upstreamServiceTime\": \"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%\",\"xForwardedFor\": \"%REQ(X-FORWARDED-FOR)%\",\"userAgent\": \"%REQ(USER-AGENT)%\",\"correlationId\": \"%REQ(X-REQUEST-ID)%\",\"authority\": \"%REQ(:AUTHORITY)%\",\"upstreamHost\": \"%UPSTREAM_HOST%\"}\n"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        ],
                        "transport_socket": {
                            "name": "envoy.transport_sockets.tls",
                            "typed_config": {
                                "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
                                "common_tls_context": {
                                    "tls_certificates": [
                                        {
                                            "certificate_chain": {
                                                "filename": "/mnt/secure/ssl/service.crt"
                                            },
                                            "private_key": {
                                                "filename": "/mnt/secure/ssl/service.key"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                ]
            }
        ],
        "clusters": [
            {
                "name": "service_api",
                "connect_timeout": "30s",
                "type": "LOGICAL_DNS",
                "dns_lookup_family": "V4_ONLY",
                "load_assignment": {
                    "cluster_name": "service_api_management",
                    "endpoints": [
                        {
                            "lb_endpoints": [
                                {
                                    "endpoint": {
                                        "address": {
                                            "socket_address": {
                                                "address": "httpbin.org",
                                                "port_value": 80
                                            }
                                        }
                                    }
                                }
                            ]
                        }
                    ]
                }
            }
        ]
    },
    "admin": {
        "access_log_path": "/dev/null",
        "address": {
            "socket_address": {
                "address": "0.0.0.0",
                "port_value": 9901
            }
        }
    }
}

Contributor Guide