From 6a372234f4d67cac20b1d2efabbfebc838e5d78f Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Tue, 2 Nov 2021 12:08:47 -0700 Subject: [PATCH 01/16] [wip] Add filter chain match predicate order Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener.proto | 36 +++++- .../listener/v3/listener_components.proto | 114 +++++++++++++++++- 2 files changed, 148 insertions(+), 2 deletions(-) diff --git a/api/envoy/config/listener/v3/listener.proto b/api/envoy/config/listener/v3/listener.proto index f065ff67160b..d194151a8732 100644 --- a/api/envoy/config/listener/v3/listener.proto +++ b/api/envoy/config/listener/v3/listener.proto @@ -35,7 +35,7 @@ message ListenerCollection { repeated xds.core.v3.CollectionEntry entries = 1; } -// [#next-free-field: 31] +// [#next-free-field: 32] message Listener { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Listener"; @@ -119,6 +119,40 @@ message Listener { // :ref:`FAQ entry `. repeated FilterChain filter_chains = 3; + // A list of filter chain matching predicate extension type URLs specifying + // the order of selection for the most specific filter chain. At each step, + // the predicate is evaluated for each filter chain. If the predicate returns + // false, the filter chain is eliminated from subsequent consideration. If + // the predicate returns true, but there is a more specific match, it is also + // eliminated. + // + // For example, for SNI ``www.example.com`` the filter chain with the + // predicate ```*.example.com``` remains and the filter chain with the + // predicate ```*.com``` is eliminated, assuming there is no filter chain + // with the exact SNI match. In general, the order of specificity is domain + // specific as defined by the predicate extension. + // + // In case, there is more than one filter chain candidates remaining after + // the process completes, the first of the filter chains in the order of + // their declaration is selected. + // + // If left unspecified, the following default matching order is applied: + // 1. :ref:`DestinationPort `. + // 2. :ref:`DestinationIP `. + // 3. :ref:`SNI `. + // 4. :ref:`TransportProtocol `. + // 5. :ref:`ApplicationProtocol `. + // 6. :ref:`DirectSourceIP `. + // 7. :ref:`SourceType `. + // 8. :ref:`SourceIP `. + // 9. :ref:`SourcePort `. + // + // Filter chain match conditions that are not in the matching order list are + // ignored. Filter chains without a match condition for the specificed + // predicate type URL are assumed to match all. + // [#not-implemented-hide:] + repeated string matching_order = 31; + // If a connection is redirected using *iptables*, the port on which the proxy // receives it might be different from the original destination address. When this flag is set to // true, the listener hands off redirected connections to the listener associated with the diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index e737b14b1745..52b8c90f075d 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -93,7 +93,7 @@ message Filter { // listed at the end, because that's how we want to list them in the docs. // // [#comment:TODO(PiotrSikora): Add support for configurable precedence of the rules] -// [#next-free-field: 14] +// [#next-free-field: 15] message FilterChainMatch { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.listener.FilterChainMatch"; @@ -109,6 +109,113 @@ message FilterChainMatch { EXTERNAL = 2; } + // Matches filter chains by the destination port. + message DestinationPort { + // Optional destination port to consider when use_original_dst is set on the + // listener in determining a filter chain match. + google.protobuf.UInt32Value destination_port = 1 + [(validate.rules).uint32 = {lte: 65535 gte: 1}]; + } + + // Matches filter chains by the destination IP address. + message DestinationIP { + // If non-empty, an IP address and prefix length to match addresses when the + // listener is bound to 0.0.0.0/:: or when use_original_dst is specified. + repeated core.v3.CidrRange prefix_ranges = 1; + } + + // Matches filter chains by the directly connected source IP address (this + // will only be different from the source IP address when using a listener + // filter that overrides the source address, such as the :ref:`Proxy Protocol + // listener filter `). + message DirectSourceIP { + // The criteria is satisfied if the directly connected source IP address of the downstream + // connection is contained in at least one of the specified subnets. If the parameter is not + // specified or the list is empty, the directly connected source IP address is ignored. + repeated core.v3.CidrRange direct_source_prefix_ranges = 1; + } + + // Matches filter chains by the connection source IP type. + message SourceType { + // Specifies the connection source IP match type. Can be any, local or external network. + ConnectionSourceType source_type = 1 [(validate.rules).enum = {defined_only: true}]; + } + + // Matches filter chains by the source IP address. + message SourceIP { + // The criteria is satisfied if the source IP address of the downstream + // connection is contained in at least one of the specified subnets. If the + // parameter is not specified or the list is empty, the source IP address is + // ignored. + repeated core.v3.CidrRange source_prefix_ranges = 1; + } + + // Matches filter chains by the source port. + message SourcePort { + // The criteria is satisfied if the source port of the downstream connection + // is contained in at least one of the specified ports. If the parameter is + // not specified, the source port is ignored. + repeated uint32 source_ports = 1 + [(validate.rules).repeated = {items {uint32 {lte: 65535 gte: 1}}}]; + } + + // Matches filter chains by the server name indication. + message SNI { + // If non-empty, a list of server names (e.g. SNI for TLS protocol) to consider when determining + // a filter chain match. Those values will be compared against the server names of a new + // connection, when detected by one of the listener filters. + // + // The server name will be matched against all wildcard domains, i.e. ``www.example.com`` + // will be first matched against ``www.example.com``, then ``*.example.com``, then ``*.com``. + // + // Note that partial wildcards are not supported, and values like ``*w.example.com`` are invalid. + // + // .. attention:: + // + // See the :ref:`FAQ entry ` on how to configure SNI for more + // information. + repeated string server_names = 1; + } + + // Matches filter chains by the transport protocol. + message TransportProtocol { + // If non-empty, a transport protocol to consider when determining a filter chain match. + // This value will be compared against the transport protocol of a new connection, when + // it's detected by one of the listener filters. + // + // Suggested values include: + // + // * ``raw_buffer`` - default, used when no transport protocol is detected, + // * ``tls`` - set by :ref:`envoy.filters.listener.tls_inspector ` + // when TLS protocol is detected. + string transport_protocol = 1; + } + + // Matches filter chains by the application protocol (e.g. ALPN for TLS protocol). + // [#next-free-field: 11] + message ApplicationProtocol { + // If non-empty, a list of application protocols (e.g. ALPN for TLS protocol) to consider when + // determining a filter chain match. Those values will be compared against the application + // protocols of a new connection, when detected by one of the listener filters. + // + // Suggested values include: + // + // * ``http/1.1`` - set by :ref:`envoy.filters.listener.tls_inspector + // `, + // * ``h2`` - set by :ref:`envoy.filters.listener.tls_inspector ` + // + // .. attention:: + // + // Currently, only :ref:`TLS Inspector ` provides + // application protocol detection based on the requested + // `ALPN `_ values. + // + // However, the use of ALPN is pretty much limited to the HTTP/2 traffic on the Internet, + // and matching on values other than ``h2`` is going to lead to a lot of false negatives, + // unless all connecting clients are known to use ALPN. + repeated string application_protocols = 10; + } + reserved 1; // Optional destination port to consider when use_original_dst is set on the @@ -193,6 +300,11 @@ message FilterChainMatch { // and matching on values other than ``h2`` is going to lead to a lot of false negatives, // unless all connecting clients are known to use ALPN. repeated string application_protocols = 10; + + // Specifies the filter chain matching predicates to be used in the matching order. + // Each predicate extension must be specified at most once. + // [#not-implemented-hide:] + repeated core.v3.TypedExtensionConfig predicates = 14; } // A filter chain wraps a set of match criteria, an option TLS context, a set of filters, and From 8aa165f444d6253888189d2107480a619cec9230 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Tue, 2 Nov 2021 14:26:40 -0700 Subject: [PATCH 02/16] spelling Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener.proto | 2 +- api/envoy/config/listener/v3/listener_components.proto | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/api/envoy/config/listener/v3/listener.proto b/api/envoy/config/listener/v3/listener.proto index d194151a8732..52559b2b9e6c 100644 --- a/api/envoy/config/listener/v3/listener.proto +++ b/api/envoy/config/listener/v3/listener.proto @@ -148,7 +148,7 @@ message Listener { // 9. :ref:`SourcePort `. // // Filter chain match conditions that are not in the matching order list are - // ignored. Filter chains without a match condition for the specificed + // ignored. Filter chains without a match condition for the specified // predicate type URL are assumed to match all. // [#not-implemented-hide:] repeated string matching_order = 31; diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index 52b8c90f075d..893697a87f72 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -301,8 +301,11 @@ message FilterChainMatch { // unless all connecting clients are known to use ALPN. repeated string application_protocols = 10; - // Specifies the filter chain matching predicates to be used in the matching order. - // Each predicate extension must be specified at most once. + // Specifies the filter chain matching predicates to be used in the matching + // order. Each predicate extension must be specified at most once. For + // backwards compatibility, the existing fields in the filter chain match, if + // specified, are converted to their corresponding filter chain matching + // predicates in this list. // [#not-implemented-hide:] repeated core.v3.TypedExtensionConfig predicates = 14; } From cfdb93af146ccc9ebf2d18b5cd283b1bbe20ece1 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Fri, 5 Nov 2021 10:45:54 -0700 Subject: [PATCH 03/16] review Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener.proto | 36 +---------- .../listener/v3/listener_components.proto | 59 +++++++++++++++++-- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/api/envoy/config/listener/v3/listener.proto b/api/envoy/config/listener/v3/listener.proto index 52559b2b9e6c..f065ff67160b 100644 --- a/api/envoy/config/listener/v3/listener.proto +++ b/api/envoy/config/listener/v3/listener.proto @@ -35,7 +35,7 @@ message ListenerCollection { repeated xds.core.v3.CollectionEntry entries = 1; } -// [#next-free-field: 32] +// [#next-free-field: 31] message Listener { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Listener"; @@ -119,40 +119,6 @@ message Listener { // :ref:`FAQ entry `. repeated FilterChain filter_chains = 3; - // A list of filter chain matching predicate extension type URLs specifying - // the order of selection for the most specific filter chain. At each step, - // the predicate is evaluated for each filter chain. If the predicate returns - // false, the filter chain is eliminated from subsequent consideration. If - // the predicate returns true, but there is a more specific match, it is also - // eliminated. - // - // For example, for SNI ``www.example.com`` the filter chain with the - // predicate ```*.example.com``` remains and the filter chain with the - // predicate ```*.com``` is eliminated, assuming there is no filter chain - // with the exact SNI match. In general, the order of specificity is domain - // specific as defined by the predicate extension. - // - // In case, there is more than one filter chain candidates remaining after - // the process completes, the first of the filter chains in the order of - // their declaration is selected. - // - // If left unspecified, the following default matching order is applied: - // 1. :ref:`DestinationPort `. - // 2. :ref:`DestinationIP `. - // 3. :ref:`SNI `. - // 4. :ref:`TransportProtocol `. - // 5. :ref:`ApplicationProtocol `. - // 6. :ref:`DirectSourceIP `. - // 7. :ref:`SourceType `. - // 8. :ref:`SourceIP `. - // 9. :ref:`SourcePort `. - // - // Filter chain match conditions that are not in the matching order list are - // ignored. Filter chains without a match condition for the specified - // predicate type URL are assumed to match all. - // [#not-implemented-hide:] - repeated string matching_order = 31; - // If a connection is redirected using *iptables*, the port on which the proxy // receives it might be different from the original destination address. When this flag is set to // true, the listener hands off redirected connections to the listener associated with the diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index 893697a87f72..090808bf314f 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -216,6 +216,21 @@ message FilterChainMatch { repeated string application_protocols = 10; } + // Individual filter chain match predicate. + message FilterChainMatchPredicate { + // The typed config for the match predicate extension. The type URL will be + // used to identify the extension. In the case that the type URL is + // *xds.type.v3.TypedStruct* (or, for historical reasons, + // *udpa.type.v1.TypedStruct*), the inner type URL of *TypedStruct* will be + // utilized. See the :ref:`extension configuration overview + // ` for further details. + google.protobuf.Any typed_config = 1 [(validate.rules).any = {required: true}]; + + // Flag to continue matching if this match is a wildcard match and there is a + // more specific match. + bool fallthrough = 2; + } + reserved 1; // Optional destination port to consider when use_original_dst is set on the @@ -301,13 +316,45 @@ message FilterChainMatch { // unless all connecting clients are known to use ALPN. repeated string application_protocols = 10; - // Specifies the filter chain matching predicates to be used in the matching - // order. Each predicate extension must be specified at most once. For - // backwards compatibility, the existing fields in the filter chain match, if - // specified, are converted to their corresponding filter chain matching - // predicates in this list. + // A list of filter chain matching predicate extensions specifying the order + // of selection for the most specific filter chain. The filter chains in a + // single listener must have the identical order of predicate extension type + // URLs. For backwards compatibility, if the existing fields in the filter + // chain match are specified, the fields are converted to their corresponding + // filter chain matching predicates in the following default matching order: + // 1. :ref:`DestinationPort `. + // 2. :ref:`DestinationIP `. + // 3. :ref:`SNI `. + // 4. :ref:`TransportProtocol `. + // 5. :ref:`ApplicationProtocol `. + // 6. :ref:`DirectSourceIP `. + // 7. :ref:`SourceType `. + // 8. :ref:`SourceIP `. + // 9. :ref:`SourcePort `. + // + // At each step, the predicate is evaluated for each filter chain. If the + // predicate returns false, the filter chain is eliminated from subsequent + // consideration. If the predicate returns true, then the decision is based + // on the ``fallthrough`` flag. If there is another more specific match for + // the same predicate and the flag is not set, then the less specific match + // is eliminated. If the flag is set, then it remains as a candidate for the + // next step. + // + // For example, consider SNI ``www.example.com``and two filter chains with + // the predicates ```*.example.com``` and ```*.com```. If ``fallthrough`` + // flag is not set then only the filter chain ```*.example.com``` matches. If + // ``fallthrough`` flag is set on ```*.com```, then both filter chains match. + // In general, the order of specificity is domain specific as defined by the + // predicate extension. The flag should be set when matching on multiple + // properties in order for a default chain to apply without explicit specific + // matching of the first properties in the list. + // + // In case, there is more than one filter chain candidates remaining after + // the process completes, the first of the filter chains in the order of + // their declaration is selected. + // // [#not-implemented-hide:] - repeated core.v3.TypedExtensionConfig predicates = 14; + repeated FilterChainMatchPredicate predicates = 14; } // A filter chain wraps a set of match criteria, an option TLS context, a set of filters, and From a13ed92033aabe824af36ea484085c04884466df Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Fri, 5 Nov 2021 10:52:33 -0700 Subject: [PATCH 04/16] review Signed-off-by: Kuat Yessenov --- .../config/listener/v3/listener_components.proto | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index 090808bf314f..680600b9f6c9 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -110,17 +110,22 @@ message FilterChainMatch { } // Matches filter chains by the destination port. + // [#next-free-field: 6] message DestinationPort { // Optional destination port to consider when use_original_dst is set on the // listener in determining a filter chain match. google.protobuf.UInt32Value destination_port = 1 [(validate.rules).uint32 = {lte: 65535 gte: 1}]; + + // Match destination port by range. + type.v3.Int32Range destination_port_range = 5; } // Matches filter chains by the destination IP address. message DestinationIP { // If non-empty, an IP address and prefix length to match addresses when the // listener is bound to 0.0.0.0/:: or when use_original_dst is specified. + // Empty list matches all. repeated core.v3.CidrRange prefix_ranges = 1; } @@ -130,8 +135,8 @@ message FilterChainMatch { // listener filter `). message DirectSourceIP { // The criteria is satisfied if the directly connected source IP address of the downstream - // connection is contained in at least one of the specified subnets. If the parameter is not - // specified or the list is empty, the directly connected source IP address is ignored. + // connection is contained in at least one of the specified subnets. If the list is empty, + // the directly connected source IP address is ignored. repeated core.v3.CidrRange direct_source_prefix_ranges = 1; } @@ -144,8 +149,7 @@ message FilterChainMatch { // Matches filter chains by the source IP address. message SourceIP { // The criteria is satisfied if the source IP address of the downstream - // connection is contained in at least one of the specified subnets. If the - // parameter is not specified or the list is empty, the source IP address is + // connection is contained in at least one of the specified subnets. If the list is empty, the source IP address is // ignored. repeated core.v3.CidrRange source_prefix_ranges = 1; } @@ -192,7 +196,6 @@ message FilterChainMatch { } // Matches filter chains by the application protocol (e.g. ALPN for TLS protocol). - // [#next-free-field: 11] message ApplicationProtocol { // If non-empty, a list of application protocols (e.g. ALPN for TLS protocol) to consider when // determining a filter chain match. Those values will be compared against the application @@ -213,7 +216,7 @@ message FilterChainMatch { // However, the use of ALPN is pretty much limited to the HTTP/2 traffic on the Internet, // and matching on values other than ``h2`` is going to lead to a lot of false negatives, // unless all connecting clients are known to use ALPN. - repeated string application_protocols = 10; + repeated string application_protocols = 1; } // Individual filter chain match predicate. From 2228fef36e9f6a766868f0c1163047b65c334709 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 8 Nov 2021 14:19:05 -0800 Subject: [PATCH 05/16] review Signed-off-by: Kuat Yessenov --- .../listener/v3/listener_components.proto | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index 680600b9f6c9..3df69a8bfbbc 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -110,15 +110,14 @@ message FilterChainMatch { } // Matches filter chains by the destination port. - // [#next-free-field: 6] message DestinationPort { // Optional destination port to consider when use_original_dst is set on the // listener in determining a filter chain match. google.protobuf.UInt32Value destination_port = 1 [(validate.rules).uint32 = {lte: 65535 gte: 1}]; - // Match destination port by range. - type.v3.Int32Range destination_port_range = 5; + // Match destination port by ranges. + repeated type.v3.Int32Range destination_port_ranges = 2; } // Matches filter chains by the destination IP address. @@ -157,10 +156,9 @@ message FilterChainMatch { // Matches filter chains by the source port. message SourcePort { // The criteria is satisfied if the source port of the downstream connection - // is contained in at least one of the specified ports. If the parameter is + // is contained in at least one of the specified port ranges. If the parameter is // not specified, the source port is ignored. - repeated uint32 source_ports = 1 - [(validate.rules).repeated = {items {uint32 {lte: 65535 gte: 1}}}]; + repeated type.v3.Int32Range source_port_ranges = 1; } // Matches filter chains by the server name indication. @@ -341,17 +339,25 @@ message FilterChainMatch { // on the ``fallthrough`` flag. If there is another more specific match for // the same predicate and the flag is not set, then the less specific match // is eliminated. If the flag is set, then it remains as a candidate for the - // next step. - // - // For example, consider SNI ``www.example.com``and two filter chains with - // the predicates ```*.example.com``` and ```*.com```. If ``fallthrough`` - // flag is not set then only the filter chain ```*.example.com``` matches. If - // ``fallthrough`` flag is set on ```*.com```, then both filter chains match. - // In general, the order of specificity is domain specific as defined by the + // next step. In general, the order of specificity is domain specific to the // predicate extension. The flag should be set when matching on multiple // properties in order for a default chain to apply without explicit specific // matching of the first properties in the list. // + // As an example, consider a filter chain ``FC1`` matching plaintext HTTP + // traffic on destination port 80, and another pass-through filter chain + // ``FC2`` for the rest of the traffic. The first chain match condition can + // be expressed with the transport protocol match on ``raw_buffer``, the + // application protocol match on ``http/1.1`` and ``h2``, and the destination + // port match on 80, in this order. If the second filter chain match does not + // specify ``fallthrough`` for any of its empty predicates, then for the + // plaintext non-HTTP traffic, ``FC2`` is not selected because it is + // eliminated at the first step as being less specific than ``FC1`` on the + // transport protocol match ``raw_buffer``. Therefore, ``FC2`` should specify + // ``fallthrough`` flag for both the transport protocol and the application + // protocol match predicates, in order to match plaintext non-HTTP traffic as + // well as plaintext HTTP traffic on ports other than 80. + // // In case, there is more than one filter chain candidates remaining after // the process completes, the first of the filter chains in the order of // their declaration is selected. From f45bc06742890f598b3d1efd760c8e3d978baaef Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 15 Nov 2021 14:12:25 -0800 Subject: [PATCH 06/16] review Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/BUILD | 1 + api/envoy/config/listener/v3/listener.proto | 40 ++- .../listener/v3/listener_components.proto | 277 +++++++++--------- 3 files changed, 172 insertions(+), 146 deletions(-) diff --git a/api/envoy/config/listener/v3/BUILD b/api/envoy/config/listener/v3/BUILD index c2d6c133a73a..fc2ebb5ae174 100644 --- a/api/envoy/config/listener/v3/BUILD +++ b/api/envoy/config/listener/v3/BUILD @@ -8,6 +8,7 @@ api_proto_package( deps = [ "//envoy/annotations:pkg", "//envoy/config/accesslog/v3:pkg", + "//envoy/config/common/matcher/v3:pkg", "//envoy/config/core/v3:pkg", "//envoy/type/v3:pkg", "@com_github_cncf_udpa//udpa/annotations:pkg", diff --git a/api/envoy/config/listener/v3/listener.proto b/api/envoy/config/listener/v3/listener.proto index f065ff67160b..fb0490130eba 100644 --- a/api/envoy/config/listener/v3/listener.proto +++ b/api/envoy/config/listener/v3/listener.proto @@ -3,8 +3,10 @@ syntax = "proto3"; package envoy.config.listener.v3; import "envoy/config/accesslog/v3/accesslog.proto"; +import "envoy/config/common/matcher/v3/matcher.proto"; import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/base.proto"; +import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/socket_option.proto"; import "envoy/config/listener/v3/api_listener.proto"; import "envoy/config/listener/v3/listener_components.proto"; @@ -35,7 +37,7 @@ message ListenerCollection { repeated xds.core.v3.CollectionEntry entries = 1; } -// [#next-free-field: 31] +// [#next-free-field: 33] message Listener { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Listener"; @@ -93,6 +95,23 @@ message Listener { message InternalListenerConfig { } + // Filter chain with a name. + message NamedFilterChain { + // Filter chain name. + string name = 1 [(validate.rules).string = {min_len: 1}]; + + oneof config_type { + // Filter chain configuration. + FilterChain filter_chain = 2; + + // Configuration source specifier for an extension configuration discovery + // service. In case of a failure and without the default configuration, the + // connection is rejected. + // [#not-implemented-hide:] + core.v3.ExtensionConfigSource config_discovery = 3; + } + } + reserved 14, 23; // The unique name by which this listener is known. If no name is provided, @@ -119,6 +138,25 @@ message Listener { // :ref:`FAQ entry `. repeated FilterChain filter_chains = 3; + // A filter chain matcher resolving the filter chain name based on the connection properties. + // The following inputs are supported by the matcher: + // + // 1. :ref:`DestinationPort `. + // 2. :ref:`DestinationIP `. + // 3. :ref:`SNI `. + // 4. :ref:`TransportProtocol `. + // 5. :ref:`ApplicationProtocol `. + // 6. :ref:`DirectSourceIP `. + // 7. :ref:`SourceType `. + // 8. :ref:`SourceIP `. + // 9. :ref:`SourcePort `. + // [#not-implemented-hide:] + repeated common.matcher.v3.Matcher filter_chain_matcher = 31; + + // Filter chains. + // [#not-implemented-hide:] + repeated NamedFilterChain named_filter_chains = 32; + // If a connection is redirected using *iptables*, the port on which the proxy // receives it might be different from the original destination address. When this flag is set to // true, the listener hands off redirected connections to the listener associated with the diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index 3df69a8bfbbc..881810cc08d6 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package envoy.config.listener.v3; +import "envoy/config/common/matcher/v3/matcher.proto"; import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/extension.proto"; @@ -93,7 +94,7 @@ message Filter { // listed at the end, because that's how we want to list them in the docs. // // [#comment:TODO(PiotrSikora): Add support for configurable precedence of the rules] -// [#next-free-field: 15] +// [#next-free-field: 14] message FilterChainMatch { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.listener.FilterChainMatch"; @@ -110,126 +111,160 @@ message FilterChainMatch { } // Matches filter chains by the destination port. - message DestinationPort { - // Optional destination port to consider when use_original_dst is set on the - // listener in determining a filter chain match. - google.protobuf.UInt32Value destination_port = 1 - [(validate.rules).uint32 = {lte: 65535 gte: 1}]; - - // Match destination port by ranges. - repeated type.v3.Int32Range destination_port_ranges = 2; + message DestinationPortInput { } // Matches filter chains by the destination IP address. - message DestinationIP { - // If non-empty, an IP address and prefix length to match addresses when the - // listener is bound to 0.0.0.0/:: or when use_original_dst is specified. - // Empty list matches all. - repeated core.v3.CidrRange prefix_ranges = 1; + message DestinationIPInput { + } + + // Matches filter chains by the source IP address. + message SourceIPInput { } // Matches filter chains by the directly connected source IP address (this // will only be different from the source IP address when using a listener // filter that overrides the source address, such as the :ref:`Proxy Protocol // listener filter `). - message DirectSourceIP { - // The criteria is satisfied if the directly connected source IP address of the downstream - // connection is contained in at least one of the specified subnets. If the list is empty, - // the directly connected source IP address is ignored. - repeated core.v3.CidrRange direct_source_prefix_ranges = 1; + message DirectSourceIPInput { + } + + // Matches filter chains by the source port. + message SourcePortInput { } // Matches filter chains by the connection source IP type. - message SourceType { - // Specifies the connection source IP match type. Can be any, local or external network. - ConnectionSourceType source_type = 1 [(validate.rules).enum = {defined_only: true}]; + // Specifies the connection source IP match type. The values include: + // + // * ``any`` - any connection source, + // * ``local`` - matches a connection originating from the same host, + // * ``external`` - matches a connection originating from a different host + message SourceTypeInput { } - // Matches filter chains by the source IP address. - message SourceIP { - // The criteria is satisfied if the source IP address of the downstream - // connection is contained in at least one of the specified subnets. If the list is empty, the source IP address is - // ignored. - repeated core.v3.CidrRange source_prefix_ranges = 1; + // Matches filter chains by the server names of a new connection, when detected by one of the listener filters. + message SNIInput { } - // Matches filter chains by the source port. - message SourcePort { - // The criteria is satisfied if the source port of the downstream connection - // is contained in at least one of the specified port ranges. If the parameter is - // not specified, the source port is ignored. - repeated type.v3.Int32Range source_port_ranges = 1; + // Matches filter chains by the transport protocol. + // This value will be compared against the transport protocol of a new connection, when + // it's detected by one of the listener filters. + // + // Suggested values include: + // + // * ``raw_buffer`` - default, used when no transport protocol is detected, + // * ``tls`` - set by :ref:`envoy.filters.listener.tls_inspector ` + // when TLS protocol is detected. + message TransportProtocolInput { } - // Matches filter chains by the server name indication. - message SNI { - // If non-empty, a list of server names (e.g. SNI for TLS protocol) to consider when determining - // a filter chain match. Those values will be compared against the server names of a new - // connection, when detected by one of the listener filters. - // - // The server name will be matched against all wildcard domains, i.e. ``www.example.com`` - // will be first matched against ``www.example.com``, then ``*.example.com``, then ``*.com``. - // - // Note that partial wildcards are not supported, and values like ``*w.example.com`` are invalid. - // - // .. attention:: - // - // See the :ref:`FAQ entry ` on how to configure SNI for more - // information. - repeated string server_names = 1; + // Matches filter chains by the application protocol (e.g. ALPN for TLS protocol). + // This values will be compared against the application + // protocols of a new connection, when detected by one of the listener filters. + // + // Suggested values include: + // + // * ``http/1.1`` - set by :ref:`envoy.filters.listener.tls_inspector + // `, + // * ``h2`` - set by :ref:`envoy.filters.listener.tls_inspector ` + // + // .. attention:: + // + // Currently, only :ref:`TLS Inspector ` provides + // application protocol detection based on the requested + // `ALPN `_ values. + // + // However, the use of ALPN is pretty much limited to the HTTP/2 traffic on the Internet, + // and matching on values other than ``h2`` is going to lead to a lot of false negatives, + // unless all connecting clients are known to use ALPN. + message ApplicationProtocolInput { } - // Matches filter chains by the transport protocol. - message TransportProtocol { - // If non-empty, a transport protocol to consider when determining a filter chain match. - // This value will be compared against the transport protocol of a new connection, when - // it's detected by one of the listener filters. - // - // Suggested values include: - // - // * ``raw_buffer`` - default, used when no transport protocol is detected, - // * ``tls`` - set by :ref:`envoy.filters.listener.tls_inspector ` - // when TLS protocol is detected. - string transport_protocol = 1; + // Matches a specific port against a set of possibly overlapping port ranges. + message PortMatcher { + // Specifies an optional list of port ranges and a match action. + message PortRangeMatcher { + // Optional set of port ranges. An empty set matches any port. + repeated type.v3.Int32Range ranges = 1; + + // Match action to apply when the port is within one of the port ranges. + common.matcher.v3.Matcher.OnMatch on_match = 2; + + // Indicates whether this match option should be considered if there is a + // matcher for the specific port value. For example, consider a matcher + // for the port range [1, 1000] applied to a specific port 80. If there + // is another matcher for the specific port 80 that fully matches, then + // the specific port matcher is selected. However, if the specific port + // matcher does not fully match, then the behavior depends on whether the + // range matcher [1, 1000] is exclusive. Exclusive port matchers do not + // apply when there is a more specific port match. Non-exclusive port + // matchers may apply when the nested match conditions are satisfied for + // the range matcher but not for the specific port value nested matcher. + // + // The order of range matchers is important since it dictates the order + // of matching in case of overlapping port ranges. + bool exclusive = 3; + } + + // Match port by value. Takes precedence over matching by the port ranges. + map port_map = 1; + + // Match port by port ranges. + repeated PortRangeMatcher range_matchers = 2; } - // Matches filter chains by the application protocol (e.g. ALPN for TLS protocol). - message ApplicationProtocol { - // If non-empty, a list of application protocols (e.g. ALPN for TLS protocol) to consider when - // determining a filter chain match. Those values will be compared against the application - // protocols of a new connection, when detected by one of the listener filters. - // - // Suggested values include: - // - // * ``http/1.1`` - set by :ref:`envoy.filters.listener.tls_inspector - // `, - // * ``h2`` - set by :ref:`envoy.filters.listener.tls_inspector ` - // - // .. attention:: - // - // Currently, only :ref:`TLS Inspector ` provides - // application protocol detection based on the requested - // `ALPN `_ values. - // - // However, the use of ALPN is pretty much limited to the HTTP/2 traffic on the Internet, - // and matching on values other than ``h2`` is going to lead to a lot of false negatives, - // unless all connecting clients are known to use ALPN. - repeated string application_protocols = 1; + // Matches a specific IP address against a set of possibly overlapping subnets. + message IPMatcher { + // Specifies an optional list of IP address ranges and a match action. + message IPRangeMatcher { + // Optional set of CIDR ranges. An empty set matches any IP address. + repeated core.v3.CidrRange ranges = 1; + + // Match action to apply when the IP address is within one of the CIDR ranges. + common.matcher.v3.Matcher.OnMatch on_match = 2; + + // Indicates whether this match option should be considered if there is a + // more specific matcher. Exclusive matchers are not selected whenever a + // more specific matcher exists (e.g. matcher with a longer prefix) even + // when the more specific matcher fails its nested match condition. + // Non-exclusive matchers are considered if the more specific matcher + // exists but its nested match condition does not entirely match. + // Non-exclusive matchers are selected in the order of their specificity + // first (longest prefix first), then the order of declaration next. + bool exclusive = 3; + } + + // Match IP address by CIDR ranges. + repeated IPRangeMatcher range_matchers = 1; } - // Individual filter chain match predicate. - message FilterChainMatchPredicate { - // The typed config for the match predicate extension. The type URL will be - // used to identify the extension. In the case that the type URL is - // *xds.type.v3.TypedStruct* (or, for historical reasons, - // *udpa.type.v1.TypedStruct*), the inner type URL of *TypedStruct* will be - // utilized. See the :ref:`extension configuration overview - // ` for further details. - google.protobuf.Any typed_config = 1 [(validate.rules).any = {required: true}]; - - // Flag to continue matching if this match is a wildcard match and there is a - // more specific match. - bool fallthrough = 2; + // Matches a specific server name against of a set of possibly overlapping wildcard domains. + message ServerNameMatcher { + // Specifies an optional list of wildcard domains and a match action. + // The server name will be matched against all wildcard domains, i.e. ``www.example.com`` + // will be first matched against ``www.example.com``, then ``*.example.com``, then ``*.com``. + // + // Note that partial wildcards are not supported, and values like ``*w.example.com`` are invalid. + message DomainMatcher { + // Optional set of wildcard domains. An empty set matches any server name. + repeated string server_names = 1; + + // Match action to apply when the server name matches. + common.matcher.v3.Matcher.OnMatch on_match = 2; + + // Indicates whether this match option should be considered if there is a + // more specific matcher. Exclusive matches are not selected whenever a + // more specific matcher exists even when the more specific matcher fails + // to match its nested match condition. For example, an exclusive matcher + // for ```*.com``` does not match ``www.example.com``` if there is a + // matcher for ```*.example.com```. Matchers are selected in the order of + // their specificity first (longest suffix first), then + // the order of declaration next. + bool exclusive = 3; + } + + // Match server name by wildcard domains. + repeated DomainMatcher domain_matchers = 1; } reserved 1; @@ -316,54 +351,6 @@ message FilterChainMatch { // and matching on values other than ``h2`` is going to lead to a lot of false negatives, // unless all connecting clients are known to use ALPN. repeated string application_protocols = 10; - - // A list of filter chain matching predicate extensions specifying the order - // of selection for the most specific filter chain. The filter chains in a - // single listener must have the identical order of predicate extension type - // URLs. For backwards compatibility, if the existing fields in the filter - // chain match are specified, the fields are converted to their corresponding - // filter chain matching predicates in the following default matching order: - // 1. :ref:`DestinationPort `. - // 2. :ref:`DestinationIP `. - // 3. :ref:`SNI `. - // 4. :ref:`TransportProtocol `. - // 5. :ref:`ApplicationProtocol `. - // 6. :ref:`DirectSourceIP `. - // 7. :ref:`SourceType `. - // 8. :ref:`SourceIP `. - // 9. :ref:`SourcePort `. - // - // At each step, the predicate is evaluated for each filter chain. If the - // predicate returns false, the filter chain is eliminated from subsequent - // consideration. If the predicate returns true, then the decision is based - // on the ``fallthrough`` flag. If there is another more specific match for - // the same predicate and the flag is not set, then the less specific match - // is eliminated. If the flag is set, then it remains as a candidate for the - // next step. In general, the order of specificity is domain specific to the - // predicate extension. The flag should be set when matching on multiple - // properties in order for a default chain to apply without explicit specific - // matching of the first properties in the list. - // - // As an example, consider a filter chain ``FC1`` matching plaintext HTTP - // traffic on destination port 80, and another pass-through filter chain - // ``FC2`` for the rest of the traffic. The first chain match condition can - // be expressed with the transport protocol match on ``raw_buffer``, the - // application protocol match on ``http/1.1`` and ``h2``, and the destination - // port match on 80, in this order. If the second filter chain match does not - // specify ``fallthrough`` for any of its empty predicates, then for the - // plaintext non-HTTP traffic, ``FC2`` is not selected because it is - // eliminated at the first step as being less specific than ``FC1`` on the - // transport protocol match ``raw_buffer``. Therefore, ``FC2`` should specify - // ``fallthrough`` flag for both the transport protocol and the application - // protocol match predicates, in order to match plaintext non-HTTP traffic as - // well as plaintext HTTP traffic on ports other than 80. - // - // In case, there is more than one filter chain candidates remaining after - // the process completes, the first of the filter chains in the order of - // their declaration is selected. - // - // [#not-implemented-hide:] - repeated FilterChainMatchPredicate predicates = 14; } // A filter chain wraps a set of match criteria, an option TLS context, a set of filters, and From 937f7a86f00282da49ff7090a21177d6c9e454f1 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Wed, 17 Nov 2021 13:39:24 -0800 Subject: [PATCH 07/16] review Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/BUILD | 2 +- api/envoy/config/listener/v3/listener.proto | 47 +-- .../listener/v3/listener_components.proto | 317 +++++++++--------- 3 files changed, 177 insertions(+), 189 deletions(-) diff --git a/api/envoy/config/listener/v3/BUILD b/api/envoy/config/listener/v3/BUILD index fc2ebb5ae174..75f6e10c7e4f 100644 --- a/api/envoy/config/listener/v3/BUILD +++ b/api/envoy/config/listener/v3/BUILD @@ -8,10 +8,10 @@ api_proto_package( deps = [ "//envoy/annotations:pkg", "//envoy/config/accesslog/v3:pkg", - "//envoy/config/common/matcher/v3:pkg", "//envoy/config/core/v3:pkg", "//envoy/type/v3:pkg", "@com_github_cncf_udpa//udpa/annotations:pkg", "@com_github_cncf_udpa//xds/core/v3:pkg", + "@com_github_cncf_udpa//xds/type/matcher/v3:pkg", ], ) diff --git a/api/envoy/config/listener/v3/listener.proto b/api/envoy/config/listener/v3/listener.proto index fb0490130eba..fc4b16e1814b 100644 --- a/api/envoy/config/listener/v3/listener.proto +++ b/api/envoy/config/listener/v3/listener.proto @@ -3,7 +3,6 @@ syntax = "proto3"; package envoy.config.listener.v3; import "envoy/config/accesslog/v3/accesslog.proto"; -import "envoy/config/common/matcher/v3/matcher.proto"; import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/extension.proto"; @@ -16,6 +15,7 @@ import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; import "xds/core/v3/collection_entry.proto"; +import "xds/type/matcher/v3/matcher.proto"; import "envoy/annotations/deprecation.proto"; import "udpa/annotations/security.proto"; @@ -95,23 +95,6 @@ message Listener { message InternalListenerConfig { } - // Filter chain with a name. - message NamedFilterChain { - // Filter chain name. - string name = 1 [(validate.rules).string = {min_len: 1}]; - - oneof config_type { - // Filter chain configuration. - FilterChain filter_chain = 2; - - // Configuration source specifier for an extension configuration discovery - // service. In case of a failure and without the default configuration, the - // connection is rejected. - // [#not-implemented-hide:] - core.v3.ExtensionConfigSource config_discovery = 3; - } - } - reserved 14, 23; // The unique name by which this listener is known. If no name is provided, @@ -141,21 +124,25 @@ message Listener { // A filter chain matcher resolving the filter chain name based on the connection properties. // The following inputs are supported by the matcher: // - // 1. :ref:`DestinationPort `. - // 2. :ref:`DestinationIP `. - // 3. :ref:`SNI `. - // 4. :ref:`TransportProtocol `. - // 5. :ref:`ApplicationProtocol `. - // 6. :ref:`DirectSourceIP `. - // 7. :ref:`SourceType `. - // 8. :ref:`SourceIP `. - // 9. :ref:`SourcePort `. + // 1. :ref:`DestinationPort `. + // 2. :ref:`DestinationIP `. + // 3. :ref:`SNI `. + // 4. :ref:`TransportProtocol `. + // 5. :ref:`ApplicationProtocol `. + // 6. :ref:`DirectSourceIP `. + // 7. :ref:`SourceType `. + // 8. :ref:`SourceIP `. + // 9. :ref:`SourcePort `. + // + // If specified, all :ref:`filter_chains ` must + // have a non-empty :ref:`name ` and empty :ref:`filter_chain_match `. // [#not-implemented-hide:] - repeated common.matcher.v3.Matcher filter_chain_matcher = 31; + repeated xds.type.matcher.v3.Matcher filter_chain_matcher = 31; - // Filter chains. + // Defines the discovery service configuration for filter chains indexed by the filter chain name. + // The set of filter chain names must be disjoint from the filter chain names in the field :ref:`filter_chains `. // [#not-implemented-hide:] - repeated NamedFilterChain named_filter_chains = 32; + map filter_chain_discovery = 32; // If a connection is redirected using *iptables*, the port on which the proxy // receives it might be different from the original destination address. When this flag is set to diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index 881810cc08d6..ad8024036998 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -2,7 +2,6 @@ syntax = "proto3"; package envoy.config.listener.v3; -import "envoy/config/common/matcher/v3/matcher.proto"; import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/extension.proto"; @@ -12,6 +11,8 @@ import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; +import "xds/type/matcher/v3/matcher.proto"; + import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; @@ -110,163 +111,6 @@ message FilterChainMatch { EXTERNAL = 2; } - // Matches filter chains by the destination port. - message DestinationPortInput { - } - - // Matches filter chains by the destination IP address. - message DestinationIPInput { - } - - // Matches filter chains by the source IP address. - message SourceIPInput { - } - - // Matches filter chains by the directly connected source IP address (this - // will only be different from the source IP address when using a listener - // filter that overrides the source address, such as the :ref:`Proxy Protocol - // listener filter `). - message DirectSourceIPInput { - } - - // Matches filter chains by the source port. - message SourcePortInput { - } - - // Matches filter chains by the connection source IP type. - // Specifies the connection source IP match type. The values include: - // - // * ``any`` - any connection source, - // * ``local`` - matches a connection originating from the same host, - // * ``external`` - matches a connection originating from a different host - message SourceTypeInput { - } - - // Matches filter chains by the server names of a new connection, when detected by one of the listener filters. - message SNIInput { - } - - // Matches filter chains by the transport protocol. - // This value will be compared against the transport protocol of a new connection, when - // it's detected by one of the listener filters. - // - // Suggested values include: - // - // * ``raw_buffer`` - default, used when no transport protocol is detected, - // * ``tls`` - set by :ref:`envoy.filters.listener.tls_inspector ` - // when TLS protocol is detected. - message TransportProtocolInput { - } - - // Matches filter chains by the application protocol (e.g. ALPN for TLS protocol). - // This values will be compared against the application - // protocols of a new connection, when detected by one of the listener filters. - // - // Suggested values include: - // - // * ``http/1.1`` - set by :ref:`envoy.filters.listener.tls_inspector - // `, - // * ``h2`` - set by :ref:`envoy.filters.listener.tls_inspector ` - // - // .. attention:: - // - // Currently, only :ref:`TLS Inspector ` provides - // application protocol detection based on the requested - // `ALPN `_ values. - // - // However, the use of ALPN is pretty much limited to the HTTP/2 traffic on the Internet, - // and matching on values other than ``h2`` is going to lead to a lot of false negatives, - // unless all connecting clients are known to use ALPN. - message ApplicationProtocolInput { - } - - // Matches a specific port against a set of possibly overlapping port ranges. - message PortMatcher { - // Specifies an optional list of port ranges and a match action. - message PortRangeMatcher { - // Optional set of port ranges. An empty set matches any port. - repeated type.v3.Int32Range ranges = 1; - - // Match action to apply when the port is within one of the port ranges. - common.matcher.v3.Matcher.OnMatch on_match = 2; - - // Indicates whether this match option should be considered if there is a - // matcher for the specific port value. For example, consider a matcher - // for the port range [1, 1000] applied to a specific port 80. If there - // is another matcher for the specific port 80 that fully matches, then - // the specific port matcher is selected. However, if the specific port - // matcher does not fully match, then the behavior depends on whether the - // range matcher [1, 1000] is exclusive. Exclusive port matchers do not - // apply when there is a more specific port match. Non-exclusive port - // matchers may apply when the nested match conditions are satisfied for - // the range matcher but not for the specific port value nested matcher. - // - // The order of range matchers is important since it dictates the order - // of matching in case of overlapping port ranges. - bool exclusive = 3; - } - - // Match port by value. Takes precedence over matching by the port ranges. - map port_map = 1; - - // Match port by port ranges. - repeated PortRangeMatcher range_matchers = 2; - } - - // Matches a specific IP address against a set of possibly overlapping subnets. - message IPMatcher { - // Specifies an optional list of IP address ranges and a match action. - message IPRangeMatcher { - // Optional set of CIDR ranges. An empty set matches any IP address. - repeated core.v3.CidrRange ranges = 1; - - // Match action to apply when the IP address is within one of the CIDR ranges. - common.matcher.v3.Matcher.OnMatch on_match = 2; - - // Indicates whether this match option should be considered if there is a - // more specific matcher. Exclusive matchers are not selected whenever a - // more specific matcher exists (e.g. matcher with a longer prefix) even - // when the more specific matcher fails its nested match condition. - // Non-exclusive matchers are considered if the more specific matcher - // exists but its nested match condition does not entirely match. - // Non-exclusive matchers are selected in the order of their specificity - // first (longest prefix first), then the order of declaration next. - bool exclusive = 3; - } - - // Match IP address by CIDR ranges. - repeated IPRangeMatcher range_matchers = 1; - } - - // Matches a specific server name against of a set of possibly overlapping wildcard domains. - message ServerNameMatcher { - // Specifies an optional list of wildcard domains and a match action. - // The server name will be matched against all wildcard domains, i.e. ``www.example.com`` - // will be first matched against ``www.example.com``, then ``*.example.com``, then ``*.com``. - // - // Note that partial wildcards are not supported, and values like ``*w.example.com`` are invalid. - message DomainMatcher { - // Optional set of wildcard domains. An empty set matches any server name. - repeated string server_names = 1; - - // Match action to apply when the server name matches. - common.matcher.v3.Matcher.OnMatch on_match = 2; - - // Indicates whether this match option should be considered if there is a - // more specific matcher. Exclusive matches are not selected whenever a - // more specific matcher exists even when the more specific matcher fails - // to match its nested match condition. For example, an exclusive matcher - // for ```*.com``` does not match ``www.example.com``` if there is a - // matcher for ```*.example.com```. Matchers are selected in the order of - // their specificity first (longest suffix first), then - // the order of declaration next. - bool exclusive = 3; - } - - // Match server name by wildcard domains. - repeated DomainMatcher domain_matchers = 1; - } - reserved 1; // Optional destination port to consider when use_original_dst is set on the @@ -515,3 +359,160 @@ message ListenerFilter { // for further examples. ListenerFilterChainMatchPredicate filter_disabled = 4; } + +// Matcher input that allows matching connections by by the destination port. +message DestinationPortInput { +} + +// Matcher input that allows matching connections by by the destination IP address. +message DestinationIPInput { +} + +// Matcher input that allows matching connections by by the source IP address. +message SourceIPInput { +} + +// Matcher input that allows matching connections by by the directly connected source IP address (this +// will only be different from the source IP address when using a listener +// filter that overrides the source address, such as the :ref:`Proxy Protocol +// listener filter `). +message DirectSourceIPInput { +} + +// Matcher input that allows matching connections by by the source port. +message SourcePortInput { +} + +// Matcher input that allows matching connections by by the connection source IP type. +// Specifies the connection source IP match type. The values include: +// +// * ``any`` - any connection source, +// * ``local`` - matches a connection originating from the same host, +// * ``external`` - matches a connection originating from a different host +message SourceTypeInput { +} + +// Matcher input that allows matching connections by by the server names of a new connection, when detected by one of the listener filters. +message SNIInput { +} + +// Matcher input that allows matching connections by by the transport protocol. +// This value will be compared against the transport protocol of a new connection, when +// it's detected by one of the listener filters. +// +// Suggested values include: +// +// * ``raw_buffer`` - default, used when no transport protocol is detected, +// * ``tls`` - set by :ref:`envoy.filters.listener.tls_inspector ` +// when TLS protocol is detected. +message TransportProtocolInput { +} + +// Matcher input that allows matching connections by by the application protocol (e.g. ALPN for TLS protocol). +// This values will be compared against the application +// protocols of a new connection, when detected by one of the listener filters. +// +// Suggested values include: +// +// * ``http/1.1`` - set by :ref:`envoy.filters.listener.tls_inspector +// `, +// * ``h2`` - set by :ref:`envoy.filters.listener.tls_inspector ` +// +// .. attention:: +// +// Currently, only :ref:`TLS Inspector ` provides +// application protocol detection based on the requested +// `ALPN `_ values. +// +// However, the use of ALPN is pretty much limited to the HTTP/2 traffic on the Internet, +// and matching on values other than ``h2`` is going to lead to a lot of false negatives, +// unless all connecting clients are known to use ALPN. +message ApplicationProtocolInput { +} + +// Matches a specific port against a set of possibly overlapping port ranges. +message PortMatcher { + // Specifies an optional list of port ranges and a match action. + message PortRangeMatcher { + // Optional set of port ranges. An empty set matches any port. + repeated type.v3.Int32Range ranges = 1; + + // Match action to apply when the port is within one of the port ranges. + xds.type.matcher.v3.Matcher.OnMatch on_match = 2; + + // Indicates whether this match option should be considered if there is a + // matcher for the specific port value. For example, consider a matcher + // for the port range [1, 1000] applied to a specific port 80. If there + // is another matcher for the specific port 80 that fully matches, then + // the specific port matcher is selected. However, if the specific port + // matcher does not fully match, then the behavior depends on whether the + // range matcher [1, 1000] is exclusive. Exclusive port matchers do not + // apply when there is a more specific port match. Non-exclusive port + // matchers may apply when the nested match conditions are satisfied for + // the range matcher but not for the specific port value nested matcher. + // + // The order of range matchers is important since it dictates the order + // of matching in case of overlapping port ranges. + bool exclusive = 3; + } + + // Match port by value. Takes precedence over matching by the port ranges. + map port_map = 1; + + // Match port by port ranges. + repeated PortRangeMatcher range_matchers = 2; +} + +// Matches a specific IP address against a set of possibly overlapping subnets. +message IPMatcher { + // Specifies an optional list of IP address ranges and a match action. + message IPRangeMatcher { + // Optional set of CIDR ranges. An empty set matches any IP address. + repeated core.v3.CidrRange ranges = 1; + + // Match action to apply when the IP address is within one of the CIDR ranges. + xds.type.matcher.v3.Matcher.OnMatch on_match = 2; + + // Indicates whether this match option should be considered if there is a + // more specific matcher. Exclusive matchers are not selected whenever a + // more specific matcher exists (e.g. matcher with a longer prefix) even + // when the more specific matcher fails its nested match condition. + // Non-exclusive matchers are considered if the more specific matcher + // exists but its nested match condition does not entirely match. + // Non-exclusive matchers are selected in the order of their specificity + // first (longest prefix first), then the order of declaration next. + bool exclusive = 3; + } + + // Match IP address by CIDR ranges. + repeated IPRangeMatcher range_matchers = 1; +} + +// Matches a specific server name against of a set of possibly overlapping wildcard domains. +message ServerNameMatcher { + // Specifies an optional list of wildcard domains and a match action. + // The server name will be matched against all wildcard domains, i.e. ``www.example.com`` + // will be first matched against ``www.example.com``, then ``*.example.com``, then ``*.com``. + // + // Note that partial wildcards are not supported, and values like ``*w.example.com`` are invalid. + message DomainMatcher { + // Optional set of wildcard domains. An empty set matches any server name. + repeated string server_names = 1; + + // Match action to apply when the server name matches. + xds.type.matcher.v3.Matcher.OnMatch on_match = 2; + + // Indicates whether this match option should be considered if there is a + // more specific matcher. Exclusive matches are not selected whenever a + // more specific matcher exists even when the more specific matcher fails + // to match its nested match condition. For example, an exclusive matcher + // for ```*.com``` does not match ``www.example.com``` if there is a + // matcher for ```*.example.com```. Matchers are selected in the order of + // their specificity first (longest suffix first), then + // the order of declaration next. + bool exclusive = 3; + } + + // Match server name by wildcard domains. + repeated DomainMatcher domain_matchers = 1; +} From 9fd0f34ffdbdedd59bbc93a9335b8114378b952b Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Wed, 17 Nov 2021 13:44:39 -0800 Subject: [PATCH 08/16] review Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener_components.proto | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index ad8024036998..cc03f3a9737d 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -415,12 +415,13 @@ message TransportProtocolInput { // Suggested values include: // // * ``http/1.1`` - set by :ref:`envoy.filters.listener.tls_inspector -// `, -// * ``h2`` - set by :ref:`envoy.filters.listener.tls_inspector ` +// ` and :ref:`envoy.filters.listener.http_inspector +// `, +// * ``h2`` - set by :ref:`envoy.filters.listener.tls_inspector ` and :ref:`envoy.filters.listener.http_inspector ` // // .. attention:: // -// Currently, only :ref:`TLS Inspector ` provides +// Currently, :ref:`TLS Inspector ` provides // application protocol detection based on the requested // `ALPN `_ values. // From 595eb183ba3b2590f9ce8f20188b2f8343a79f3c Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 22 Nov 2021 08:00:38 -0800 Subject: [PATCH 09/16] add move note Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener_components.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index cc03f3a9737d..48e29ec68507 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -432,6 +432,7 @@ message ApplicationProtocolInput { } // Matches a specific port against a set of possibly overlapping port ranges. +// TODO(kuat) Move to cncf/xds. message PortMatcher { // Specifies an optional list of port ranges and a match action. message PortRangeMatcher { @@ -465,6 +466,7 @@ message PortMatcher { } // Matches a specific IP address against a set of possibly overlapping subnets. +// TODO(kuat) Move to cncf/xds. message IPMatcher { // Specifies an optional list of IP address ranges and a match action. message IPRangeMatcher { @@ -490,6 +492,7 @@ message IPMatcher { } // Matches a specific server name against of a set of possibly overlapping wildcard domains. +// TODO(kuat) Move to cncf/xds. message ServerNameMatcher { // Specifies an optional list of wildcard domains and a match action. // The server name will be matched against all wildcard domains, i.e. ``www.example.com`` From 262d0842a936e84a790edf754ffc19c638391f77 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 29 Nov 2021 14:12:19 -0800 Subject: [PATCH 10/16] merge Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/envoy/config/listener/v3/listener.proto b/api/envoy/config/listener/v3/listener.proto index 03f1a122123b..8f0f5fd099de 100644 --- a/api/envoy/config/listener/v3/listener.proto +++ b/api/envoy/config/listener/v3/listener.proto @@ -37,7 +37,7 @@ message ListenerCollection { repeated xds.core.v3.CollectionEntry entries = 1; } -// [#next-free-field: 33] +// [#next-free-field: 34] message Listener { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Listener"; From 76e5040af6e743e6f20186e47f101742af5ae361 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Wed, 1 Dec 2021 13:46:11 -0800 Subject: [PATCH 11/16] more review Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener.proto | 44 ++++++++++++++++--- .../listener/v3/listener_components.proto | 24 +++------- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/api/envoy/config/listener/v3/listener.proto b/api/envoy/config/listener/v3/listener.proto index 8f0f5fd099de..4d41bc6b998c 100644 --- a/api/envoy/config/listener/v3/listener.proto +++ b/api/envoy/config/listener/v3/listener.proto @@ -5,7 +5,6 @@ package envoy.config.listener.v3; import "envoy/config/accesslog/v3/accesslog.proto"; import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/base.proto"; -import "envoy/config/core/v3/extension.proto"; import "envoy/config/core/v3/socket_option.proto"; import "envoy/config/listener/v3/api_listener.proto"; import "envoy/config/listener/v3/listener_components.proto"; @@ -37,7 +36,7 @@ message ListenerCollection { repeated xds.core.v3.CollectionEntry entries = 1; } -// [#next-free-field: 34] +// [#next-free-field: 33] message Listener { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Listener"; @@ -136,13 +135,44 @@ message Listener { // // If specified, all :ref:`filter_chains ` must // have a non-empty :ref:`name ` and empty :ref:`filter_chain_match `. - // [#not-implemented-hide:] - repeated xds.type.matcher.v3.Matcher filter_chain_matcher = 32; + // + // Example 1: Match port 80 for chain "http", port 443 and SNI "*.server.com" for chain "server" or SNI "*.com" for chain "https". - // Defines the discovery service configuration for filter chains indexed by the filter chain name. - // The set of filter chain names must be disjoint from the filter chain names in the field :ref:`filter_chains `. + // .. code-block:: yaml + // + // filter_chain_matcher: + // matcher_tree: + // input: + // typed_config: + // "@type": type.googleapis.com/envoy.config.listener.v3.DestinationPortInput + // exact_match_map: + // map: + // "80": + // action: + // name: http + // "443": + // matcher: + // matcher_tree: + // input: + // typed_config: + // "@type": type.googleapis.com/envoy.config.listener.v3.SNIInput + // custom_match: + // typed_config: + // "@type": type.googleapis.com/envoy.config.listener.v3.ServerNameMatcher + // domain_matchers: + // - server_names: ["*.server.com"] + // on_match: + // action: + // name: server + // - server_names: ["*.com"] + // on_match: + // action: + // name: https + // + // The example above requires that filter chains named "http", "server", and "https" are present in :ref:`filter_chains ` field. + // // [#not-implemented-hide:] - map filter_chain_discovery = 33; + repeated xds.type.matcher.v3.Matcher filter_chain_matcher = 32; // If a connection is redirected using *iptables*, the port on which the proxy // receives it might be different from the original destination address. When this flag is set to diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index 48e29ec68507..53d3d829015f 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -223,6 +223,9 @@ message FilterChain { reserved "tls_context"; // The criteria to use when matching a connection to this filter chain. + // Note: :ref:`filter_chain_matcher + // ` + // supersedes this field. FilterChainMatch filter_chain_match = 1; // A list of individual network filters that make up the filter chain for @@ -260,6 +263,9 @@ message FilterChain { // establishment, the connection is summarily closed. google.protobuf.Duration transport_socket_connect_timeout = 9; + // Note: :ref:`filter_chain_matcher + // ` + // requires that filter chains are uniquely named. // [#not-implemented-hide:] The unique name (or empty) by which this filter chain is known. If no // name is provided, Envoy will allocate an internal UUID for the filter chain. If the filter // chain is to be dynamically updated or removed via FCDS a unique name must be provided. @@ -441,26 +447,8 @@ message PortMatcher { // Match action to apply when the port is within one of the port ranges. xds.type.matcher.v3.Matcher.OnMatch on_match = 2; - - // Indicates whether this match option should be considered if there is a - // matcher for the specific port value. For example, consider a matcher - // for the port range [1, 1000] applied to a specific port 80. If there - // is another matcher for the specific port 80 that fully matches, then - // the specific port matcher is selected. However, if the specific port - // matcher does not fully match, then the behavior depends on whether the - // range matcher [1, 1000] is exclusive. Exclusive port matchers do not - // apply when there is a more specific port match. Non-exclusive port - // matchers may apply when the nested match conditions are satisfied for - // the range matcher but not for the specific port value nested matcher. - // - // The order of range matchers is important since it dictates the order - // of matching in case of overlapping port ranges. - bool exclusive = 3; } - // Match port by value. Takes precedence over matching by the port ranges. - map port_map = 1; - // Match port by port ranges. repeated PortRangeMatcher range_matchers = 2; } From 3b92ec5dad0ee87cb9b2607b705867256c8f085f Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Wed, 1 Dec 2021 13:47:14 -0800 Subject: [PATCH 12/16] typo Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener_components.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index 53d3d829015f..b9ac10c382dc 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -415,7 +415,7 @@ message TransportProtocolInput { } // Matcher input that allows matching connections by by the application protocol (e.g. ALPN for TLS protocol). -// This values will be compared against the application +// This value will be compared against the application // protocols of a new connection, when detected by one of the listener filters. // // Suggested values include: From ddeeaf9e6006354d957cc27674ea2e9b38f25d0d Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Wed, 15 Dec 2021 10:46:24 -0800 Subject: [PATCH 13/16] update Signed-off-by: Kuat Yessenov --- .../listener/v3/listener_components.proto | 35 ++----------------- tools/spelling/spelling_dictionary.txt | 1 + 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index dc9b96161559..be099ff2f9f4 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -224,9 +224,6 @@ message FilterChain { reserved "tls_context"; // The criteria to use when matching a connection to this filter chain. - // Note: :ref:`filter_chain_matcher - // ` - // supersedes this field. FilterChainMatch filter_chain_match = 1; // A list of individual network filters that make up the filter chain for @@ -264,12 +261,12 @@ message FilterChain { // establishment, the connection is summarily closed. google.protobuf.Duration transport_socket_connect_timeout = 9; - // Note: :ref:`filter_chain_matcher - // ` - // requires that filter chains are uniquely named. // [#not-implemented-hide:] The unique name (or empty) by which this filter chain is known. If no // name is provided, Envoy will allocate an internal UUID for the filter chain. If the filter // chain is to be dynamically updated or removed via FCDS a unique name must be provided. + // Note: :ref:`filter_chain_matcher + // ` + // requires that filter chains are uniquely named. string name = 7; // [#not-implemented-hide:] The configuration to specify whether the filter chain will be built on-demand. @@ -454,32 +451,6 @@ message PortMatcher { repeated PortRangeMatcher range_matchers = 2; } -// Matches a specific IP address against a set of possibly overlapping subnets. -// TODO(kuat) Move to cncf/xds. -message IPMatcher { - // Specifies an optional list of IP address ranges and a match action. - message IPRangeMatcher { - // Optional set of CIDR ranges. An empty set matches any IP address. - repeated core.v3.CidrRange ranges = 1; - - // Match action to apply when the IP address is within one of the CIDR ranges. - xds.type.matcher.v3.Matcher.OnMatch on_match = 2; - - // Indicates whether this match option should be considered if there is a - // more specific matcher. Exclusive matchers are not selected whenever a - // more specific matcher exists (e.g. matcher with a longer prefix) even - // when the more specific matcher fails its nested match condition. - // Non-exclusive matchers are considered if the more specific matcher - // exists but its nested match condition does not entirely match. - // Non-exclusive matchers are selected in the order of their specificity - // first (longest prefix first), then the order of declaration next. - bool exclusive = 3; - } - - // Match IP address by CIDR ranges. - repeated IPRangeMatcher range_matchers = 1; -} - // Matches a specific server name against of a set of possibly overlapping wildcard domains. // TODO(kuat) Move to cncf/xds. message ServerNameMatcher { diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index aa402263a170..5d3ff8392374 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -521,6 +521,7 @@ cloneable cloneability cmd cmsghdr +cncf codebase codec codecs From e981df6f7331643def807ae1536c5cfe9ffa609e Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Tue, 1 Feb 2022 15:48:05 -0800 Subject: [PATCH 14/16] review Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener.proto | 52 ++++---- .../listener/v3/listener_components.proto | 119 ------------------ tools/spelling/spelling_dictionary.txt | 1 - 3 files changed, 29 insertions(+), 143 deletions(-) diff --git a/api/envoy/config/listener/v3/listener.proto b/api/envoy/config/listener/v3/listener.proto index de6bdc177c0c..f2049b32faea 100644 --- a/api/envoy/config/listener/v3/listener.proto +++ b/api/envoy/config/listener/v3/listener.proto @@ -121,31 +121,27 @@ message Listener { // :ref:`FAQ entry `. repeated FilterChain filter_chains = 3; - // A filter chain matcher resolving the filter chain name based on the connection properties. - // The following inputs are supported by the matcher: + // Unified matcher resolving the filter chain name from the network properties. This matcher is used as a replacement + // for the per-filter chain match condition + // `filter_chain_match `. + // If specified, all :ref:`filter_chains ` must + // have non-empty and unique :ref:`name ` fields and omit + // `filter_chain_match ` field. // - // 1. :ref:`DestinationPort `. - // 2. :ref:`DestinationIP `. - // 3. :ref:`SNI `. - // 4. :ref:`TransportProtocol `. - // 5. :ref:`ApplicationProtocol `. - // 6. :ref:`DirectSourceIP `. - // 7. :ref:`SourceType `. - // 8. :ref:`SourceIP `. - // 9. :ref:`SourcePort `. + // Example 1: The following matcher selects three filter chains as follows: // - // If specified, all :ref:`filter_chains ` must - // have a non-empty :ref:`name ` and empty :ref:`filter_chain_match `. + // * if the destination port is 80, then the filter chain "http" is selected; + // * if the destination port is 443 and the source IP is in the range 192.0.0.0/2, then the filter chain "internal" is selected; + // * otherwise, if the destination port is 443, then the filter chain "https" is selected; + // * otherwise, the default filter chain is selected (or the connection is rejected without the default filter chain). // - // Example 1: Match port 80 for chain "http", port 443 and SNI "*.server.com" for chain "server" or SNI "*.com" for chain "https". - // .. code-block:: yaml // // filter_chain_matcher: // matcher_tree: // input: // typed_config: - // "@type": type.googleapis.com/envoy.config.listener.v3.DestinationPortInput + // "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DestinationPortInput // exact_match_map: // map: // "80": @@ -156,21 +152,31 @@ message Listener { // matcher_tree: // input: // typed_config: - // "@type": type.googleapis.com/envoy.config.listener.v3.SNIInput + // "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput // custom_match: // typed_config: - // "@type": type.googleapis.com/envoy.config.listener.v3.ServerNameMatcher - // domain_matchers: - // - server_names: ["*.server.com"] + // "@type": type.googleapis.com/xds.type.matcher.v3.IPMatcher + // range_matchers: + // - ranges: + // - address_prefix: 192.0.0.0 + // prefix_len: 2 // on_match: // action: - // name: server - // - server_names: ["*.com"] + // name: internal + // - ranges: + // - address_prefix: 0.0.0.0 // on_match: // action: // name: https // - // The example above requires that filter chains named "http", "server", and "https" are present in :ref:`filter_chains ` field. + // + // .. note:: + // + // Once matched, each connection is permanently bound to its filter chain. + // If the matcher changes but the filter chain remains the same, the + // connections bound to the filter chain are not drained. If, however, the + // filter chain is removed or structurally modified, then the drain for its + // connections is initiated. // // [#not-implemented-hide:] repeated xds.type.matcher.v3.Matcher filter_chain_matcher = 32; diff --git a/api/envoy/config/listener/v3/listener_components.proto b/api/envoy/config/listener/v3/listener_components.proto index be099ff2f9f4..535d18140546 100644 --- a/api/envoy/config/listener/v3/listener_components.proto +++ b/api/envoy/config/listener/v3/listener_components.proto @@ -11,8 +11,6 @@ import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; -import "xds/type/matcher/v3/matcher.proto"; - import "envoy/annotations/deprecation.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; @@ -363,120 +361,3 @@ message ListenerFilter { // for further examples. ListenerFilterChainMatchPredicate filter_disabled = 4; } - -// Matcher input that allows matching connections by by the destination port. -message DestinationPortInput { -} - -// Matcher input that allows matching connections by by the destination IP address. -message DestinationIPInput { -} - -// Matcher input that allows matching connections by by the source IP address. -message SourceIPInput { -} - -// Matcher input that allows matching connections by by the directly connected source IP address (this -// will only be different from the source IP address when using a listener -// filter that overrides the source address, such as the :ref:`Proxy Protocol -// listener filter `). -message DirectSourceIPInput { -} - -// Matcher input that allows matching connections by by the source port. -message SourcePortInput { -} - -// Matcher input that allows matching connections by by the connection source IP type. -// Specifies the connection source IP match type. The values include: -// -// * ``any`` - any connection source, -// * ``local`` - matches a connection originating from the same host, -// * ``external`` - matches a connection originating from a different host -message SourceTypeInput { -} - -// Matcher input that allows matching connections by by the server names of a new connection, when detected by one of the listener filters. -message SNIInput { -} - -// Matcher input that allows matching connections by by the transport protocol. -// This value will be compared against the transport protocol of a new connection, when -// it's detected by one of the listener filters. -// -// Suggested values include: -// -// * ``raw_buffer`` - default, used when no transport protocol is detected, -// * ``tls`` - set by :ref:`envoy.filters.listener.tls_inspector ` -// when TLS protocol is detected. -message TransportProtocolInput { -} - -// Matcher input that allows matching connections by by the application protocol (e.g. ALPN for TLS protocol). -// This value will be compared against the application -// protocols of a new connection, when detected by one of the listener filters. -// -// Suggested values include: -// -// * ``http/1.1`` - set by :ref:`envoy.filters.listener.tls_inspector -// ` and :ref:`envoy.filters.listener.http_inspector -// `, -// * ``h2`` - set by :ref:`envoy.filters.listener.tls_inspector ` and :ref:`envoy.filters.listener.http_inspector ` -// -// .. attention:: -// -// Currently, :ref:`TLS Inspector ` provides -// application protocol detection based on the requested -// `ALPN `_ values. -// -// However, the use of ALPN is pretty much limited to the HTTP/2 traffic on the Internet, -// and matching on values other than ``h2`` is going to lead to a lot of false negatives, -// unless all connecting clients are known to use ALPN. -message ApplicationProtocolInput { -} - -// Matches a specific port against a set of possibly overlapping port ranges. -// TODO(kuat) Move to cncf/xds. -message PortMatcher { - // Specifies an optional list of port ranges and a match action. - message PortRangeMatcher { - // Optional set of port ranges. An empty set matches any port. - repeated type.v3.Int32Range ranges = 1; - - // Match action to apply when the port is within one of the port ranges. - xds.type.matcher.v3.Matcher.OnMatch on_match = 2; - } - - // Match port by port ranges. - repeated PortRangeMatcher range_matchers = 2; -} - -// Matches a specific server name against of a set of possibly overlapping wildcard domains. -// TODO(kuat) Move to cncf/xds. -message ServerNameMatcher { - // Specifies an optional list of wildcard domains and a match action. - // The server name will be matched against all wildcard domains, i.e. ``www.example.com`` - // will be first matched against ``www.example.com``, then ``*.example.com``, then ``*.com``. - // - // Note that partial wildcards are not supported, and values like ``*w.example.com`` are invalid. - message DomainMatcher { - // Optional set of wildcard domains. An empty set matches any server name. - repeated string server_names = 1; - - // Match action to apply when the server name matches. - xds.type.matcher.v3.Matcher.OnMatch on_match = 2; - - // Indicates whether this match option should be considered if there is a - // more specific matcher. Exclusive matches are not selected whenever a - // more specific matcher exists even when the more specific matcher fails - // to match its nested match condition. For example, an exclusive matcher - // for ```*.com``` does not match ``www.example.com``` if there is a - // matcher for ```*.example.com```. Matchers are selected in the order of - // their specificity first (longest suffix first), then - // the order of declaration next. - bool exclusive = 3; - } - - // Match server name by wildcard domains. - repeated DomainMatcher domain_matchers = 1; -} diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index 38787c687e37..80223b742b94 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -522,7 +522,6 @@ cloneable cloneability cmd cmsghdr -cncf codebase codec codecs From 0185225dd2f2aa3c04ace3fe9a88873594ba80c6 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Thu, 17 Feb 2022 16:05:48 -0800 Subject: [PATCH 15/16] try validation Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener.proto | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/envoy/config/listener/v3/listener.proto b/api/envoy/config/listener/v3/listener.proto index f2049b32faea..790fa625bb76 100644 --- a/api/envoy/config/listener/v3/listener.proto +++ b/api/envoy/config/listener/v3/listener.proto @@ -135,7 +135,8 @@ message Listener { // * otherwise, if the destination port is 443, then the filter chain "https" is selected; // * otherwise, the default filter chain is selected (or the connection is rejected without the default filter chain). // - // .. code-block:: yaml + // .. validated-code-block:: yaml + // :type-name: envoy.config.listener.v3.Listener // // filter_chain_matcher: // matcher_tree: @@ -179,7 +180,7 @@ message Listener { // connections is initiated. // // [#not-implemented-hide:] - repeated xds.type.matcher.v3.Matcher filter_chain_matcher = 32; + xds.type.matcher.v3.Matcher filter_chain_matcher = 32; // If a connection is redirected using *iptables*, the port on which the proxy // receives it might be different from the original destination address. When this flag is set to From d1c8f753da17fcff7a6e8567680d65d547ec6d2e Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Wed, 23 Feb 2022 14:07:37 -0500 Subject: [PATCH 16/16] verify example Signed-off-by: Kuat Yessenov --- api/envoy/config/listener/v3/listener.proto | 75 +++++++++++---------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/api/envoy/config/listener/v3/listener.proto b/api/envoy/config/listener/v3/listener.proto index 790fa625bb76..e1da21b518d4 100644 --- a/api/envoy/config/listener/v3/listener.proto +++ b/api/envoy/config/listener/v3/listener.proto @@ -121,6 +121,7 @@ message Listener { // :ref:`FAQ entry `. repeated FilterChain filter_chains = 3; + // [#not-implemented-hide:] // Unified matcher resolving the filter chain name from the network properties. This matcher is used as a replacement // for the per-filter chain match condition // `filter_chain_match `. @@ -138,38 +139,46 @@ message Listener { // .. validated-code-block:: yaml // :type-name: envoy.config.listener.v3.Listener // - // filter_chain_matcher: - // matcher_tree: - // input: - // typed_config: - // "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DestinationPortInput - // exact_match_map: - // map: - // "80": - // action: - // name: http - // "443": - // matcher: - // matcher_tree: - // input: - // typed_config: - // "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput - // custom_match: - // typed_config: - // "@type": type.googleapis.com/xds.type.matcher.v3.IPMatcher - // range_matchers: - // - ranges: - // - address_prefix: 192.0.0.0 - // prefix_len: 2 - // on_match: - // action: - // name: internal - // - ranges: - // - address_prefix: 0.0.0.0 - // on_match: - // action: - // name: https - // + // filter_chain_matcher: + // matcher_tree: + // input: + // typed_config: + // "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DestinationPortInput + // exact_match_map: + // map: + // "80": + // action: + // name: http + // typed_config: + // "@type": type.googleapis.com/google.protobuf.StringValue + // value: http + // "443": + // matcher: + // matcher_tree: + // input: + // typed_config: + // "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput + // custom_match: + // typed_config: + // "@type": type.googleapis.com/xds.type.matcher.v3.IPMatcher + // range_matchers: + // - ranges: + // - address_prefix: 192.0.0.0 + // prefix_len: 2 + // on_match: + // action: + // name: internal + // typed_config: + // "@type": type.googleapis.com/google.protobuf.StringValue + // value: internal + // - ranges: + // - address_prefix: 0.0.0.0 + // on_match: + // action: + // name: https + // typed_config: + // "@type": type.googleapis.com/google.protobuf.StringValue + // value: https // // .. note:: // @@ -178,8 +187,6 @@ message Listener { // connections bound to the filter chain are not drained. If, however, the // filter chain is removed or structurally modified, then the drain for its // connections is initiated. - // - // [#not-implemented-hide:] xds.type.matcher.v3.Matcher filter_chain_matcher = 32; // If a connection is redirected using *iptables*, the port on which the proxy