Proxy Protocol
This listener filter adds support for HAProxy Proxy Protocol.
In this mode, the downstream connection is assumed to come from a proxy which places the original coordinates (IP, PORT) into a connection-string. Envoy then extracts these and uses them as the remote address.
In Proxy Protocol v2 there exists the concept of extensions (TLV) tags that are optional. If the type of the TLV is added to the filter’s configuration, the TLV will be emitted as dynamic metadata or filter state with user-specified key.
TLV Storage Options
The filter supports two storage locations for TLV values, controlled by the tlv_location setting:
- DYNAMIC_METADATA (default)
TLV values are stored in dynamic metadata under the
envoy.filters.listener.proxy_protocolnamespace. This allows access via DynamicMetadataInput in RBAC and other matchers.- FILTER_STATE
TLV values are stored in filter state as a single map-like object under the key
envoy.network.proxy_protocol.tlv. Individual TLV values can be accessed in two ways:Via CEL expressions:
filter_state["envoy.network.proxy_protocol.tlv"]["my_key"]Via FilterStateInput with the
fieldparameter, which enables direct field-level access in RBAC and other matchers without needing CEL expressions:
listener_filters: - name: envoy.filters.listener.proxy_protocol typed_config: "@type": type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol tlv_location: FILTER_STATE rules: - tlv_type: 0xEA on_tlv_present: key: "aws_vpce_id"
With this configuration, you can match on individual TLV values directly in RBAC using the
fieldparameter onFilterStateInput:matcher: matcher_tree: input: name: filter_state typed_config: "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.FilterStateInput key: "envoy.network.proxy_protocol.tlv" field: "aws_vpce_id" exact_match_map: map: "vpce-12345678": action: name: allow
This implementation supports both version 1 and version 2, it automatically determines on a per-connection basis which of the two versions is present.
Note
If the filter is enabled, the Proxy Protocol must be present on the connection (either version 1 or version 2). The standard does not allow parsing to determine if it is present or not. However, the filter can be configured to allow the connection to be accepted without the Proxy Protocol header (against the standard). See allow_requests_without_proxy_protocol.
If there is a protocol error or an unsupported address family (e.g. AF_UNIX) the connection will be closed and an error thrown.
This filter should be configured with the type URL
type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol.
Statistics
This filter emits the following general statistics, rooted at proxy_proto.[<stat_prefix>.]
Name |
Type |
Description |
|---|---|---|
not_found_disallowed |
Counter |
Total number of connections that don’t contain the PROXY protocol header and are rejected. |
not_found_allowed |
Counter |
Total number of connections that don’t contain the PROXY protocol header, but are allowed due to allow_requests_without_proxy_protocol. |
The filter also emits the statistics rooted at proxy_proto.[<stat_prefix>.]versions.<version>
for each matched PROXY protocol version. Proxy protocol versions include v1 and v2.
Name |
Type |
Description |
|---|---|---|
found |
Counter |
Total number of connections where the PROXY protocol header was found and parsed correctly. |
disallowed |
Counter |
Total number of |
error |
Counter |
Total number of connections where the PROXY protocol header was malformed (and the connection was rejected). |
The filter also emits the following legacy statistics, rooted at its own scope and not including the stat_prefix:
Name |
Type |
Description |
|---|---|---|
downstream_cx_proxy_proto_error |
Counter |
Total number of connections with proxy protocol errors, i.e. |
Attention
Prefer using the more-detailed non-legacy statistics above.