From 2be9bdd9fb1050a92286c577da53aa0fdbd8cc83 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 27 Jan 2021 20:47:14 -0500 Subject: [PATCH 001/100] HCM: add support for IP detection extensions This is a follow-up to: https://github.com/envoyproxy/envoy/pull/14432#issuecomment-758004199 After that PR, it's no longer possible (unless you do a dynamic_cast) to set the remote address from a filter. This is something that we need to do because we have specialized logic for this (XFF doesn't work for us). So this adds an extension point which will allow us to push that logic down to ConnectionManagerUtility::mutateRequestHeaders() where it belongs. Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 12 ++- .../v4alpha/http_connection_manager.proto | 15 +++- docs/root/version_history/current.rst | 1 + .../v3/http_connection_manager.proto | 12 ++- .../v4alpha/http_connection_manager.proto | 15 +++- include/envoy/http/BUILD | 9 +++ include/envoy/http/ip_detection_extension.h | 49 ++++++++++++ source/common/http/BUILD | 1 + source/common/http/conn_manager_config.h | 6 ++ source/common/http/conn_manager_utility.cc | 75 ++++++++++++------- source/common/http/conn_manager_utility.h | 2 + .../network/http_connection_manager/BUILD | 1 + .../network/http_connection_manager/config.cc | 12 +++ .../network/http_connection_manager/config.h | 5 ++ source/server/admin/admin.h | 1 + 15 files changed, 183 insertions(+), 33 deletions(-) create mode 100644 include/envoy/http/ip_detection_extension.h diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 395c6b67f032..c41eb8c3c947 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -35,7 +35,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 43] +// [#next-free-field: 44] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"; @@ -583,6 +583,11 @@ message HttpConnectionManager { // *not* the deprecated but similarly named :ref:`stream_error_on_invalid_http_messaging // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; + + // The configuration of the IP detection extension. + // + // If not set, Envoy uses the default remote IP detection. + IPDetectionExtension ip_detection_extension = 43; } // The configuration to customize local reply returned by Envoy. @@ -851,3 +856,8 @@ message RequestIDExtension { // Request ID extension specific configuration. google.protobuf.Any typed_config = 1; } + +message IPDetectionExtension { + // IP detection extension specific configuration. + google.protobuf.Any typed_config = 1; +} diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 6afb11505cee..885ea2260338 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -34,7 +34,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 43] +// [#next-free-field: 44] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"; @@ -581,6 +581,11 @@ message HttpConnectionManager { // *not* the deprecated but similarly named :ref:`stream_error_on_invalid_http_messaging // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; + + // The configuration of the IP detection extension. + // + // If not set, Envoy uses the default remote IP detection. + IPDetectionExtension ip_detection_extension = 43; } // The configuration to customize local reply returned by Envoy. @@ -856,3 +861,11 @@ message RequestIDExtension { // Request ID extension specific configuration. google.protobuf.Any typed_config = 1; } + +message IPDetectionExtension { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.filters.network.http_connection_manager.v3.IPDetectionExtension"; + + // IP detection extension specific configuration. + google.protobuf.Any typed_config = 1; +} diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index e2e3a5ed6e85..fd55dbfb078c 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -54,6 +54,7 @@ New Features * access log: added the :ref:`formatters ` extension point for custom formatters (command operators). * access log: support command operator: %REQUEST_HEADERS_BYTES%, %RESPONSE_HEADERS_BYTES% and %RESPONSE_TRAILERS_BYTES%. * dispatcher: supports a stack of `Envoy::ScopeTrackedObject` instead of a single tracked object. This will allow Envoy to dump more debug information on crash. +* http: added support for IP detection extensions. * http: added support for :ref:`:ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. * http: change frame flood and abuse checks to the upstream HTTP/2 codec to ON by default. It can be disabled by setting the `envoy.reloadable_features.upstream_http2_flood_checks` runtime key to false. * overload: add support for scaling :ref:`transport connection timeouts`. This can be used to reduce the TLS handshake timeout in response to overload. diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 844313e1ef97..fb813d6ae37b 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -35,7 +35,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 43] +// [#next-free-field: 44] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"; @@ -586,6 +586,11 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; + // The configuration of the IP detection extension. + // + // If not set, Envoy uses the default remote IP detection. + IPDetectionExtension ip_detection_extension = 43; + google.protobuf.Duration hidden_envoy_deprecated_idle_timeout = 11 [deprecated = true, (envoy.annotations.disallowed_by_default) = true]; } @@ -856,3 +861,8 @@ message RequestIDExtension { // Request ID extension specific configuration. google.protobuf.Any typed_config = 1; } + +message IPDetectionExtension { + // IP detection extension specific configuration. + google.protobuf.Any typed_config = 1; +} diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 6afb11505cee..885ea2260338 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -34,7 +34,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 43] +// [#next-free-field: 44] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"; @@ -581,6 +581,11 @@ message HttpConnectionManager { // *not* the deprecated but similarly named :ref:`stream_error_on_invalid_http_messaging // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; + + // The configuration of the IP detection extension. + // + // If not set, Envoy uses the default remote IP detection. + IPDetectionExtension ip_detection_extension = 43; } // The configuration to customize local reply returned by Envoy. @@ -856,3 +861,11 @@ message RequestIDExtension { // Request ID extension specific configuration. google.protobuf.Any typed_config = 1; } + +message IPDetectionExtension { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.filters.network.http_connection_manager.v3.IPDetectionExtension"; + + // IP detection extension specific configuration. + google.protobuf.Any typed_config = 1; +} diff --git a/include/envoy/http/BUILD b/include/envoy/http/BUILD index a350d27f3e61..04eb4102a442 100644 --- a/include/envoy/http/BUILD +++ b/include/envoy/http/BUILD @@ -140,3 +140,12 @@ envoy_cc_library( ":header_map_interface", ], ) + +envoy_cc_library( + name = "ip_detection_extension_interface", + hdrs = ["ip_detection_extension.h"], + deps = [ + ":header_map_interface", + "//include/envoy/config:typed_config_interface", + ], +) diff --git a/include/envoy/http/ip_detection_extension.h b/include/envoy/http/ip_detection_extension.h new file mode 100644 index 000000000000..694d52bf5b3a --- /dev/null +++ b/include/envoy/http/ip_detection_extension.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include + +#include "envoy/common/pure.h" +#include "envoy/http/header_map.h" + +namespace Envoy { +namespace Http { + +/** + * Interface class for IP detection extensions. + */ +class IPDetectionExtension { +public: + virtual ~IPDetectionExtension() = default; + + /** + * Detect the final remote address if any. + * + * @param request_headers supplies the incoming request headers. + */ + virtual Network::Address::InstanceConstSharedPtr + detect(Http::RequestHeaderMap& request_headers) PURE; +}; + +using IPDetectionExtensionSharedPtr = std::shared_ptr; + +/* + * A factory for creating IP detection extensions. + */ +class IPDetectionExtensionFactory : public Envoy::Config::TypedFactory { +public: + ~IPDetectionExtensionFactory() override = default; + + /** + * Creates a particular Extension implementation. + * + * @param config supplies the configuration for the IP detection extension. + * @return IPDetectionExtensionSharedPtr the extension instance. + */ + virtual IPDetectionExtensionSharedPtr createExtension(const Protobuf::Message& config) const PURE; +}; + +using IPDetectionExtensionFactoryPtr = std::unique_ptr; + +} // namespace Http +} // namespace Envoy diff --git a/source/common/http/BUILD b/source/common/http/BUILD index 44cb4ef68b76..194f31959e55 100644 --- a/source/common/http/BUILD +++ b/source/common/http/BUILD @@ -155,6 +155,7 @@ envoy_cc_library( ":date_provider_lib", "//include/envoy/config:config_provider_interface", "//include/envoy/http:filter_interface", + "//include/envoy/http:ip_detection_extension_interface", "//include/envoy/http:request_id_extension_interface", "//include/envoy/router:rds_interface", "//source/common/local_reply:local_reply_lib", diff --git a/source/common/http/conn_manager_config.h b/source/common/http/conn_manager_config.h index 026cb2b5171a..79eaa65a185b 100644 --- a/source/common/http/conn_manager_config.h +++ b/source/common/http/conn_manager_config.h @@ -3,6 +3,7 @@ #include "envoy/config/config_provider.h" #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h" #include "envoy/http/filter.h" +#include "envoy/http/ip_detection_extension.h" #include "envoy/http/request_id_extension.h" #include "envoy/router/rds.h" #include "envoy/stats/scope.h" @@ -466,6 +467,11 @@ class ConnectionManagerConfig { * @return LocalReply configuration which supplies mapping for local reply generated by Envoy. */ virtual const LocalReply::LocalReply& localReply() const PURE; + + /** + * @return IPDetectionExtensionSharedPtr The IP detection extension if available. + */ + virtual IPDetectionExtensionSharedPtr ipDetectionExtension() PURE; }; } // namespace Http } // namespace Envoy diff --git a/source/common/http/conn_manager_utility.cc b/source/common/http/conn_manager_utility.cc index db2c8a7d3353..3fd46b660d2d 100644 --- a/source/common/http/conn_manager_utility.cc +++ b/source/common/http/conn_manager_utility.cc @@ -95,7 +95,7 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest // peer. Cases where we don't "use remote address" include trusted double proxy where we expect // our peer to have already properly set XFF, etc. Network::Address::InstanceConstSharedPtr final_remote_address; - bool single_xff_address; + bool single_xff_address = false; const uint32_t xff_num_trusted_hops = config.xffNumTrustedHops(); if (config.useRemoteAddress()) { @@ -127,12 +127,23 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest connection.ssl() ? Headers::get().SchemeValues.Https : Headers::get().SchemeValues.Http); } } else { - // If we are not using remote address, attempt to pull a valid IPv4 or IPv6 address out of XFF. + // If we are not using remote address, attempt to pull a valid IPv4 or IPv6 address out of XFF + // or through an extension. An extension might be needed when XFF doesn't work (e.g. an + // irregular network). + // // If we find one, it will be used as the downstream address for logging. It may or may not be // used for determining internal/external status (see below). - auto ret = Utility::getLastAddressFromXFF(request_headers, xff_num_trusted_hops); - final_remote_address = ret.address_; - single_xff_address = ret.single_address_; + auto ip_detection_extension = config.ipDetectionExtension(); + if (ip_detection_extension) { + final_remote_address = ip_detection_extension->detect(request_headers); + } + + // If there's no extension or it failed to detect, give XFF a try. + if (!final_remote_address) { + auto ret = Utility::getLastAddressFromXFF(request_headers, xff_num_trusted_hops); + final_remote_address = ret.address_; + single_xff_address = ret.single_address_; + } } // If the x-forwarded-proto header is not set, set it here, since Envoy uses it for determining @@ -170,30 +181,7 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest request_headers.setReferenceEnvoyInternalRequest( Headers::get().EnvoyInternalRequestValues.True); } else { - if (edge_request) { - request_headers.removeEnvoyDecoratorOperation(); - request_headers.removeEnvoyDownstreamServiceCluster(); - request_headers.removeEnvoyDownstreamServiceNode(); - } - - request_headers.removeEnvoyRetriableStatusCodes(); - request_headers.removeEnvoyRetriableHeaderNames(); - request_headers.removeEnvoyRetryOn(); - request_headers.removeEnvoyRetryGrpcOn(); - request_headers.removeEnvoyMaxRetries(); - request_headers.removeEnvoyUpstreamAltStatName(); - request_headers.removeEnvoyUpstreamRequestTimeoutMs(); - request_headers.removeEnvoyUpstreamRequestPerTryTimeoutMs(); - request_headers.removeEnvoyUpstreamRequestTimeoutAltResponse(); - request_headers.removeEnvoyExpectedRequestTimeoutMs(); - request_headers.removeEnvoyForceTrace(); - request_headers.removeEnvoyIpTags(); - request_headers.removeEnvoyOriginalUrl(); - request_headers.removeEnvoyHedgeOnPerTryTimeout(); - - for (const LowerCaseString& header : route_config.internalOnlyHeaders()) { - request_headers.remove(header); - } + cleanInternalHeaders(request_headers, edge_request, route_config.internalOnlyHeaders()); } if (config.userAgent()) { @@ -236,6 +224,35 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest return final_remote_address; } +void ConnectionManagerUtility::cleanInternalHeaders( + RequestHeaderMap& request_headers, bool edge_request, + const std::list& internal_only_headers) { + if (edge_request) { + request_headers.removeEnvoyDecoratorOperation(); + request_headers.removeEnvoyDownstreamServiceCluster(); + request_headers.removeEnvoyDownstreamServiceNode(); + } + + request_headers.removeEnvoyRetriableStatusCodes(); + request_headers.removeEnvoyRetriableHeaderNames(); + request_headers.removeEnvoyRetryOn(); + request_headers.removeEnvoyRetryGrpcOn(); + request_headers.removeEnvoyMaxRetries(); + request_headers.removeEnvoyUpstreamAltStatName(); + request_headers.removeEnvoyUpstreamRequestTimeoutMs(); + request_headers.removeEnvoyUpstreamRequestPerTryTimeoutMs(); + request_headers.removeEnvoyUpstreamRequestTimeoutAltResponse(); + request_headers.removeEnvoyExpectedRequestTimeoutMs(); + request_headers.removeEnvoyForceTrace(); + request_headers.removeEnvoyIpTags(); + request_headers.removeEnvoyOriginalUrl(); + request_headers.removeEnvoyHedgeOnPerTryTimeout(); + + for (const LowerCaseString& header : internal_only_headers) { + request_headers.remove(header); + } +} + void ConnectionManagerUtility::mutateTracingRequestHeader(RequestHeaderMap& request_headers, Runtime::Loader& runtime, ConnectionManagerConfig& config, diff --git a/source/common/http/conn_manager_utility.h b/source/common/http/conn_manager_utility.h index 768971ffac2d..b004c0f71f5c 100644 --- a/source/common/http/conn_manager_utility.h +++ b/source/common/http/conn_manager_utility.h @@ -87,6 +87,8 @@ class ConnectionManagerUtility { static void mutateXfccRequestHeader(RequestHeaderMap& request_headers, Network::Connection& connection, ConnectionManagerConfig& config); + static void cleanInternalHeaders(RequestHeaderMap& request_headers, bool edge_request, + const std::list& internal_only_headers); }; } // namespace Http diff --git a/source/extensions/filters/network/http_connection_manager/BUILD b/source/extensions/filters/network/http_connection_manager/BUILD index db02c5750db8..653188a89f15 100644 --- a/source/extensions/filters/network/http_connection_manager/BUILD +++ b/source/extensions/filters/network/http_connection_manager/BUILD @@ -24,6 +24,7 @@ envoy_cc_extension( "//include/envoy/filesystem:filesystem_interface", "//include/envoy/http:codec_interface", "//include/envoy/http:filter_interface", + "//include/envoy/http:ip_detection_extension_interface", "//include/envoy/http:request_id_extension_interface", "//include/envoy/registry", "//include/envoy/router:route_config_provider_manager_interface", diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 0429e1556145..044ae89a9294 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -287,6 +287,18 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( Http::RequestIDExtensionFactory::defaultInstance(context_.api().randomGenerator()); } + // Check if we are provided with an IP detection extension. + if (config.ip_detection_extension().has_typed_config()) { + auto& typed_config = config.ip_detection_extension().typed_config(); + const std::string type{TypeUtil::typeUrlToDescriptorFullName(typed_config.type_url())}; + auto* ip_detection_extension_factory = + Registry::FactoryRegistry::getFactoryByType(type); + if (!ip_detection_extension_factory) { + throw EnvoyException("IP detection extension not found"); + } + ip_detection_extension_ = ip_detection_extension_factory->createExtension(typed_config); + } + // If scoped RDS is enabled, avoid creating a route config provider. Route config providers will // be managed by the scoped routing logic instead. switch (config.route_specifier_case()) { diff --git a/source/extensions/filters/network/http_connection_manager/config.h b/source/extensions/filters/network/http_connection_manager/config.h index c3103efda53f..f28eaa000582 100644 --- a/source/extensions/filters/network/http_connection_manager/config.h +++ b/source/extensions/filters/network/http_connection_manager/config.h @@ -13,6 +13,7 @@ #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.validate.h" #include "envoy/filter/http/filter_config_provider.h" #include "envoy/http/filter.h" +#include "envoy/http/ip_detection_extension.h" #include "envoy/http/request_id_extension.h" #include "envoy/router/route_config_provider_manager.h" #include "envoy/tracing/http_tracer_manager.h" @@ -177,6 +178,9 @@ class HttpConnectionManagerConfig : Logger::Loggable, } std::chrono::milliseconds delayedCloseTimeout() const override { return delayed_close_timeout_; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } + Http::IPDetectionExtensionSharedPtr ipDetectionExtension() override { + return ip_detection_extension_; + } private: enum class CodecType { HTTP1, HTTP2, HTTP3, AUTO }; @@ -255,6 +259,7 @@ class HttpConnectionManagerConfig : Logger::Loggable, const envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction headers_with_underscores_action_; const LocalReply::LocalReplyPtr local_reply_; + Http::IPDetectionExtensionSharedPtr ip_detection_extension_{nullptr}; // Default idle timeout is 5 minutes if nothing is specified in the HCM config. static const uint64_t StreamIdleTimeoutMs = 5 * 60 * 1000; diff --git a/source/server/admin/admin.h b/source/server/admin/admin.h index 3ca7be09f1af..43a46a670cbd 100644 --- a/source/server/admin/admin.h +++ b/source/server/admin/admin.h @@ -180,6 +180,7 @@ class AdminImpl : public Admin, return envoy::config::core::v3::HttpProtocolOptions::ALLOW; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } + Http::IPDetectionExtensionSharedPtr ipDetectionExtension() override { return nullptr; }; Http::Code request(absl::string_view path_and_query, absl::string_view method, Http::ResponseHeaderMap& response_headers, std::string& body) override; void closeSocket(); From eee3cd59208565b35e210817b25ddf20366816f0 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 29 Jan 2021 15:59:51 -0500 Subject: [PATCH 002/100] Rename --> original_ip_detection Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 10 ++-- .../v4alpha/http_connection_manager.proto | 12 ++--- .../v3/http_connection_manager.proto | 10 ++-- .../v4alpha/http_connection_manager.proto | 12 ++--- include/envoy/http/BUILD | 4 +- include/envoy/http/ip_detection_extension.h | 49 ----------------- include/envoy/http/original_ip_detection.h | 53 +++++++++++++++++++ source/common/http/BUILD | 2 +- source/common/http/conn_manager_config.h | 6 +-- source/common/http/conn_manager_utility.cc | 7 +-- .../network/http_connection_manager/BUILD | 2 +- .../network/http_connection_manager/config.cc | 14 ++--- .../network/http_connection_manager/config.h | 8 +-- source/server/admin/admin.h | 2 +- test/mocks/http/mocks.h | 1 + 15 files changed, 99 insertions(+), 93 deletions(-) delete mode 100644 include/envoy/http/ip_detection_extension.h create mode 100644 include/envoy/http/original_ip_detection.h diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index c41eb8c3c947..5f6fc61b118a 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -584,10 +584,10 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the IP detection extension. + // The configuration of the original IP detection extension. // - // If not set, Envoy uses the default remote IP detection. - IPDetectionExtension ip_detection_extension = 43; + // If not set, Envoy uses the default remote IP detection mechanism. + OriginalIPDetectionExtension original_ip_detection = 43; } // The configuration to customize local reply returned by Envoy. @@ -857,7 +857,7 @@ message RequestIDExtension { google.protobuf.Any typed_config = 1; } -message IPDetectionExtension { - // IP detection extension specific configuration. +message OriginalIPDetectionExtension { + // Original IP detection extension configuration. google.protobuf.Any typed_config = 1; } diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 885ea2260338..5bb94db996a5 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -582,10 +582,10 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the IP detection extension. + // The configuration of the original IP detection extension. // - // If not set, Envoy uses the default remote IP detection. - IPDetectionExtension ip_detection_extension = 43; + // If not set, Envoy uses the default remote IP detection mechanism. + OriginalIPDetectionExtension original_ip_detection = 43; } // The configuration to customize local reply returned by Envoy. @@ -862,10 +862,10 @@ message RequestIDExtension { google.protobuf.Any typed_config = 1; } -message IPDetectionExtension { +message OriginalIPDetectionExtension { option (udpa.annotations.versioning).previous_message_type = - "envoy.extensions.filters.network.http_connection_manager.v3.IPDetectionExtension"; + "envoy.extensions.filters.network.http_connection_manager.v3.OriginalIPDetectionExtension"; - // IP detection extension specific configuration. + // Original IP detection extension configuration. google.protobuf.Any typed_config = 1; } diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index fb813d6ae37b..bd7e8517cc57 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -586,10 +586,10 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the IP detection extension. + // The configuration of the original IP detection extension. // - // If not set, Envoy uses the default remote IP detection. - IPDetectionExtension ip_detection_extension = 43; + // If not set, Envoy uses the default remote IP detection mechanism. + OriginalIPDetectionExtension original_ip_detection = 43; google.protobuf.Duration hidden_envoy_deprecated_idle_timeout = 11 [deprecated = true, (envoy.annotations.disallowed_by_default) = true]; @@ -862,7 +862,7 @@ message RequestIDExtension { google.protobuf.Any typed_config = 1; } -message IPDetectionExtension { - // IP detection extension specific configuration. +message OriginalIPDetectionExtension { + // Original IP detection extension configuration. google.protobuf.Any typed_config = 1; } diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 885ea2260338..5bb94db996a5 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -582,10 +582,10 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the IP detection extension. + // The configuration of the original IP detection extension. // - // If not set, Envoy uses the default remote IP detection. - IPDetectionExtension ip_detection_extension = 43; + // If not set, Envoy uses the default remote IP detection mechanism. + OriginalIPDetectionExtension original_ip_detection = 43; } // The configuration to customize local reply returned by Envoy. @@ -862,10 +862,10 @@ message RequestIDExtension { google.protobuf.Any typed_config = 1; } -message IPDetectionExtension { +message OriginalIPDetectionExtension { option (udpa.annotations.versioning).previous_message_type = - "envoy.extensions.filters.network.http_connection_manager.v3.IPDetectionExtension"; + "envoy.extensions.filters.network.http_connection_manager.v3.OriginalIPDetectionExtension"; - // IP detection extension specific configuration. + // Original IP detection extension configuration. google.protobuf.Any typed_config = 1; } diff --git a/include/envoy/http/BUILD b/include/envoy/http/BUILD index 04eb4102a442..4678c2b4d371 100644 --- a/include/envoy/http/BUILD +++ b/include/envoy/http/BUILD @@ -142,8 +142,8 @@ envoy_cc_library( ) envoy_cc_library( - name = "ip_detection_extension_interface", - hdrs = ["ip_detection_extension.h"], + name = "original_ip_detection_interface", + hdrs = ["original_ip_detection.h"], deps = [ ":header_map_interface", "//include/envoy/config:typed_config_interface", diff --git a/include/envoy/http/ip_detection_extension.h b/include/envoy/http/ip_detection_extension.h deleted file mode 100644 index 694d52bf5b3a..000000000000 --- a/include/envoy/http/ip_detection_extension.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include - -#include "envoy/common/pure.h" -#include "envoy/http/header_map.h" - -namespace Envoy { -namespace Http { - -/** - * Interface class for IP detection extensions. - */ -class IPDetectionExtension { -public: - virtual ~IPDetectionExtension() = default; - - /** - * Detect the final remote address if any. - * - * @param request_headers supplies the incoming request headers. - */ - virtual Network::Address::InstanceConstSharedPtr - detect(Http::RequestHeaderMap& request_headers) PURE; -}; - -using IPDetectionExtensionSharedPtr = std::shared_ptr; - -/* - * A factory for creating IP detection extensions. - */ -class IPDetectionExtensionFactory : public Envoy::Config::TypedFactory { -public: - ~IPDetectionExtensionFactory() override = default; - - /** - * Creates a particular Extension implementation. - * - * @param config supplies the configuration for the IP detection extension. - * @return IPDetectionExtensionSharedPtr the extension instance. - */ - virtual IPDetectionExtensionSharedPtr createExtension(const Protobuf::Message& config) const PURE; -}; - -using IPDetectionExtensionFactoryPtr = std::unique_ptr; - -} // namespace Http -} // namespace Envoy diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h new file mode 100644 index 000000000000..ddc6b4c3ee9d --- /dev/null +++ b/include/envoy/http/original_ip_detection.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include + +#include "envoy/common/pure.h" +#include "envoy/http/header_map.h" + +namespace Envoy { +namespace Http { + +struct OriginalIPDetectionParams { + Http::RequestHeaderMap& request_headers; +}; + +/** + * Interface class for original IP detection extensions. + */ +class OriginalIPDetection { +public: + virtual ~OriginalIPDetection() = default; + + /** + * Detect the final remote address. + * + * @param param supplies the OriginalIPDetectionParams params for detection. + */ + virtual Network::Address::InstanceConstSharedPtr + detect(struct OriginalIPDetectionParams& params) PURE; +}; + +using OriginalIPDetectionSharedPtr = std::shared_ptr; + +/* + * A factory for creating original IP detection extensions. + */ +class OriginalIPDetectionFactory : public Envoy::Config::TypedFactory { +public: + ~OriginalIPDetectionFactory() override = default; + + /** + * Creates a particular extension implementation. + * + * @param config supplies the configuration for the original IP detection extension. + * @return OriginalIPDetectionSharedPtr the extension instance. + */ + virtual OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message& config) const PURE; +}; + +using OriginalIPDetectionFactoryPtr = std::unique_ptr; + +} // namespace Http +} // namespace Envoy diff --git a/source/common/http/BUILD b/source/common/http/BUILD index 194f31959e55..86a2cb32da32 100644 --- a/source/common/http/BUILD +++ b/source/common/http/BUILD @@ -155,7 +155,7 @@ envoy_cc_library( ":date_provider_lib", "//include/envoy/config:config_provider_interface", "//include/envoy/http:filter_interface", - "//include/envoy/http:ip_detection_extension_interface", + "//include/envoy/http:original_ip_detection_interface", "//include/envoy/http:request_id_extension_interface", "//include/envoy/router:rds_interface", "//source/common/local_reply:local_reply_lib", diff --git a/source/common/http/conn_manager_config.h b/source/common/http/conn_manager_config.h index 79eaa65a185b..ad0bef9da5c2 100644 --- a/source/common/http/conn_manager_config.h +++ b/source/common/http/conn_manager_config.h @@ -3,7 +3,7 @@ #include "envoy/config/config_provider.h" #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h" #include "envoy/http/filter.h" -#include "envoy/http/ip_detection_extension.h" +#include "envoy/http/original_ip_detection.h" #include "envoy/http/request_id_extension.h" #include "envoy/router/rds.h" #include "envoy/stats/scope.h" @@ -469,9 +469,9 @@ class ConnectionManagerConfig { virtual const LocalReply::LocalReply& localReply() const PURE; /** - * @return IPDetectionExtensionSharedPtr The IP detection extension if available. + * @return OriginalIPDetectionSharedPtr original IP detection extension if available. */ - virtual IPDetectionExtensionSharedPtr ipDetectionExtension() PURE; + virtual OriginalIPDetectionSharedPtr originalIpDetection() PURE; }; } // namespace Http } // namespace Envoy diff --git a/source/common/http/conn_manager_utility.cc b/source/common/http/conn_manager_utility.cc index 3fd46b660d2d..aa6cc1ca63bf 100644 --- a/source/common/http/conn_manager_utility.cc +++ b/source/common/http/conn_manager_utility.cc @@ -133,9 +133,10 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest // // If we find one, it will be used as the downstream address for logging. It may or may not be // used for determining internal/external status (see below). - auto ip_detection_extension = config.ipDetectionExtension(); - if (ip_detection_extension) { - final_remote_address = ip_detection_extension->detect(request_headers); + auto original_ip_detection = config.originalIpDetection(); + if (original_ip_detection) { + struct OriginalIPDetectionParams params = {request_headers}; + final_remote_address = original_ip_detection->detect(params); } // If there's no extension or it failed to detect, give XFF a try. diff --git a/source/extensions/filters/network/http_connection_manager/BUILD b/source/extensions/filters/network/http_connection_manager/BUILD index 653188a89f15..c15d2e0ee696 100644 --- a/source/extensions/filters/network/http_connection_manager/BUILD +++ b/source/extensions/filters/network/http_connection_manager/BUILD @@ -24,7 +24,7 @@ envoy_cc_extension( "//include/envoy/filesystem:filesystem_interface", "//include/envoy/http:codec_interface", "//include/envoy/http:filter_interface", - "//include/envoy/http:ip_detection_extension_interface", + "//include/envoy/http:original_ip_detection_interface", "//include/envoy/http:request_id_extension_interface", "//include/envoy/registry", "//include/envoy/router:route_config_provider_manager_interface", diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 044ae89a9294..c3844f5d50e9 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -288,15 +288,15 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( } // Check if we are provided with an IP detection extension. - if (config.ip_detection_extension().has_typed_config()) { - auto& typed_config = config.ip_detection_extension().typed_config(); + if (config.original_ip_detection().has_typed_config()) { + auto& typed_config = config.original_ip_detection().typed_config(); const std::string type{TypeUtil::typeUrlToDescriptorFullName(typed_config.type_url())}; - auto* ip_detection_extension_factory = - Registry::FactoryRegistry::getFactoryByType(type); - if (!ip_detection_extension_factory) { - throw EnvoyException("IP detection extension not found"); + auto* factory = + Registry::FactoryRegistry::getFactoryByType(type); + if (!factory) { + throw EnvoyException("Original IP detection extension not found"); } - ip_detection_extension_ = ip_detection_extension_factory->createExtension(typed_config); + original_ip_detection_ = factory->createExtension(typed_config); } // If scoped RDS is enabled, avoid creating a route config provider. Route config providers will diff --git a/source/extensions/filters/network/http_connection_manager/config.h b/source/extensions/filters/network/http_connection_manager/config.h index f28eaa000582..8719d9988c9a 100644 --- a/source/extensions/filters/network/http_connection_manager/config.h +++ b/source/extensions/filters/network/http_connection_manager/config.h @@ -13,7 +13,7 @@ #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.validate.h" #include "envoy/filter/http/filter_config_provider.h" #include "envoy/http/filter.h" -#include "envoy/http/ip_detection_extension.h" +#include "envoy/http/original_ip_detection.h" #include "envoy/http/request_id_extension.h" #include "envoy/router/route_config_provider_manager.h" #include "envoy/tracing/http_tracer_manager.h" @@ -178,8 +178,8 @@ class HttpConnectionManagerConfig : Logger::Loggable, } std::chrono::milliseconds delayedCloseTimeout() const override { return delayed_close_timeout_; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } - Http::IPDetectionExtensionSharedPtr ipDetectionExtension() override { - return ip_detection_extension_; + Http::OriginalIPDetectionSharedPtr originalIpDetection() override { + return original_ip_detection_; } private: @@ -259,7 +259,7 @@ class HttpConnectionManagerConfig : Logger::Loggable, const envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction headers_with_underscores_action_; const LocalReply::LocalReplyPtr local_reply_; - Http::IPDetectionExtensionSharedPtr ip_detection_extension_{nullptr}; + Http::OriginalIPDetectionSharedPtr original_ip_detection_{nullptr}; // Default idle timeout is 5 minutes if nothing is specified in the HCM config. static const uint64_t StreamIdleTimeoutMs = 5 * 60 * 1000; diff --git a/source/server/admin/admin.h b/source/server/admin/admin.h index 43a46a670cbd..0cdb222a427a 100644 --- a/source/server/admin/admin.h +++ b/source/server/admin/admin.h @@ -180,7 +180,7 @@ class AdminImpl : public Admin, return envoy::config::core::v3::HttpProtocolOptions::ALLOW; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } - Http::IPDetectionExtensionSharedPtr ipDetectionExtension() override { return nullptr; }; + Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return nullptr; }; Http::Code request(absl::string_view path_and_query, absl::string_view method, Http::ResponseHeaderMap& response_headers, std::string& body) override; void closeSocket(); diff --git a/test/mocks/http/mocks.h b/test/mocks/http/mocks.h index 378aa1c61a2b..a6d524980afb 100644 --- a/test/mocks/http/mocks.h +++ b/test/mocks/http/mocks.h @@ -567,6 +567,7 @@ class MockConnectionManagerConfig : public ConnectionManagerConfig { MOCK_METHOD(envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction, headersWithUnderscoresAction, (), (const)); MOCK_METHOD(const LocalReply::LocalReply&, localReply, (), (const)); + MOCK_METHOD(OriginalIPDetectionSharedPtr, originalIpDetection, ()); std::unique_ptr internal_address_config_ = std::make_unique(); From 03819df46ed20a6a7deae33d51d2244795fcc661 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 29 Jan 2021 16:00:59 -0500 Subject: [PATCH 003/100] Update changelog Signed-off-by: Raul Gutierrez Segales --- docs/root/version_history/current.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 79cff0b8df27..1f3e9bbb1caa 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -55,7 +55,7 @@ New Features * access log: added the :ref:`formatters ` extension point for custom formatters (command operators). * access log: support command operator: %REQUEST_HEADERS_BYTES%, %RESPONSE_HEADERS_BYTES% and %RESPONSE_TRAILERS_BYTES%. * dispatcher: supports a stack of `Envoy::ScopeTrackedObject` instead of a single tracked object. This will allow Envoy to dump more debug information on crash. -* http: added support for IP detection extensions. +* http: added support for original IP detection extensions. * grpc_json_transcoder: filter can now be configured on per-route/per-vhost level as well. Leaving empty list of services in the filter configuration disables transcoding on the specific route. * http: added support for :ref:`:ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. * http: change frame flood and abuse checks to the upstream HTTP/2 codec to ON by default. It can be disabled by setting the `envoy.reloadable_features.upstream_http2_flood_checks` runtime key to false. From 701e9791cfbd704a9b54007dcd28ee2e9e5b2dc7 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 29 Jan 2021 16:29:28 -0500 Subject: [PATCH 004/100] Some docs Not sure where to put a full example of how to configure an extension. Signed-off-by: Raul Gutierrez Segales --- .../intro/arch_overview/other_features/ip_transparency.rst | 5 +++++ docs/root/version_history/current.rst | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/root/intro/arch_overview/other_features/ip_transparency.rst b/docs/root/intro/arch_overview/other_features/ip_transparency.rst index b662528b715f..1aab4fd75ade 100644 --- a/docs/root/intro/arch_overview/other_features/ip_transparency.rst +++ b/docs/root/intro/arch_overview/other_features/ip_transparency.rst @@ -20,6 +20,11 @@ called the *downstream remote address*, for many reasons. Some examples include: Envoy supports multiple methods for providing the downstream remote address to the upstream host. These techniques vary in complexity and applicability. +Envoy also supports an +:ref:`extension mechanism` +for detecting the original IP address. This might be useful if none of the techniques below is +applicable to your setup. + HTTP Headers ------------ diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 1f3e9bbb1caa..2c261bf527d3 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -55,7 +55,7 @@ New Features * access log: added the :ref:`formatters ` extension point for custom formatters (command operators). * access log: support command operator: %REQUEST_HEADERS_BYTES%, %RESPONSE_HEADERS_BYTES% and %RESPONSE_TRAILERS_BYTES%. * dispatcher: supports a stack of `Envoy::ScopeTrackedObject` instead of a single tracked object. This will allow Envoy to dump more debug information on crash. -* http: added support for original IP detection extensions. +* http: added support for :ref:`original ip detection extensions`. * grpc_json_transcoder: filter can now be configured on per-route/per-vhost level as well. Leaving empty list of services in the filter configuration disables transcoding on the specific route. * http: added support for :ref:`:ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. * http: change frame flood and abuse checks to the upstream HTTP/2 codec to ON by default. It can be disabled by setting the `envoy.reloadable_features.upstream_http2_flood_checks` runtime key to false. From 68c9785b19471632d27ba0e30d05a7e6c27d6dbf Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Mon, 1 Feb 2021 16:39:58 -0500 Subject: [PATCH 005/100] Add HCM config tests Signed-off-by: Raul Gutierrez Segales --- .../http_connection_manager/config_test.cc | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 5149c2e55c99..0a4772bd2596 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -1742,6 +1742,63 @@ TEST_F(HttpConnectionManagerConfigTest, DefaultRequestIDExtension) { ASSERT_NE(nullptr, request_id_extension); } +TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { + const std::string yaml_string = R"EOF( + stat_prefix: ingress_http + route_config: + name: local_route + original_ip_detection: + typed_config: + "@type": type.googleapis.com/google.protobuf.StringValue + http_filters: + - name: envoy.filters.http.router + )EOF"; + + EXPECT_THROW_WITH_REGEX(createHttpConnectionManagerConfig(yaml_string), EnvoyException, + "Original IP detection extension not found"); +} + +class TestIPDetection : public Http::OriginalIPDetection { + Network::Address::InstanceConstSharedPtr + detect(struct Http::OriginalIPDetectionParams&) override { + return nullptr; + } +}; + +class TestIPDetectionFactory : public Http::OriginalIPDetectionFactory { + Http::OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message&) const override { + return std::make_shared(); + } + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return std::make_unique(); + } + std::string name() const override { return "TestFactory"; } + std::string category() const override { return "OriginalIpDetection"; } +}; + +TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { + TestIPDetectionFactory factory; + Registry::InjectFactory ip_detection_register(factory); + const std::string yaml_string = R"EOF( + stat_prefix: ingress_http + route_config: + name: local_route + original_ip_detection: + typed_config: + "@type": type.googleapis.com/google.protobuf.StringValue + http_filters: + - name: envoy.filters.http.router + )EOF"; + + HttpConnectionManagerConfig config(parseHttpConnectionManagerFromYaml(yaml_string), context_, + date_provider_, route_config_provider_manager_, + scoped_routes_config_provider_manager_, http_tracer_manager_, + filter_config_provider_manager_); + auto original_ip_detection = + dynamic_cast(config.originalIpDetection().get()); + ASSERT_NE(nullptr, original_ip_detection); +} + TEST_F(HttpConnectionManagerConfigTest, DynamicFilterWarmingNoDefault) { const std::string yaml_string = R"EOF( codec_type: http1 From b42737bd13248debb58e290f60a3f7499d9ea592 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Mon, 1 Feb 2021 18:55:52 -0500 Subject: [PATCH 006/100] Add test for mutateRequestHeaders() using an extension Signed-off-by: Raul Gutierrez Segales --- docs/root/version_history/current.rst | 2 +- test/common/http/conn_manager_utility_test.cc | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 2ed6319b8b07..46d423a383ce 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -72,9 +72,9 @@ New Features * access log: added the :ref:`formatters ` extension point for custom formatters (command operators). * access log: support command operator: %REQUEST_HEADERS_BYTES%, %RESPONSE_HEADERS_BYTES%, and %RESPONSE_TRAILERS_BYTES%. * dispatcher: supports a stack of `Envoy::ScopeTrackedObject` instead of a single tracked object. This will allow Envoy to dump more debug information on crash. -* http: added support for :ref:`original ip detection extensions`. * grpc_json_transcoder: added option :ref:`strict_http_request_validation ` to reject invalid requests early. * grpc_json_transcoder: filter can now be configured on per-route/per-vhost level as well. Leaving empty list of services in the filter configuration disables transcoding on the specific route. +* http: added support for :ref:`original ip detection extensions`. * http: added support for :ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. * http: change frame flood and abuse checks to the upstream HTTP/2 codec to ON by default. It can be disabled by setting the `envoy.reloadable_features.upstream_http2_flood_checks` runtime key to false. * overload: add support for scaling :ref:`transport connection timeouts`. This can be used to reduce the TLS handshake timeout in response to overload. diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index f21e49898cdf..3c92d91feba7 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -1543,5 +1543,47 @@ TEST_F(ConnectionManagerUtilityTest, NoPreserveExternalRequestIdNoEdgeRequest) { EXPECT_EQ("my-request-id", headers.get_(Headers::get().RequestId)); } } + +class CustomHeaderBasedDetection : public Http::OriginalIPDetection { +public: + CustomHeaderBasedDetection(const std::string& header_name) : header_name_(header_name) {} + + Network::Address::InstanceConstSharedPtr + detect(struct Http::OriginalIPDetectionParams& params) override { + auto hdr = params.request_headers.get(LowerCaseString(header_name_)); + if (hdr.empty()) { + return nullptr; + } + auto header_value = hdr[0]->value().getStringView(); + return std::make_shared(std::string(header_value)); + } + +private: + std::string header_name_; +}; + +// Test an extension to detect the original IP for the request. +TEST_F(ConnectionManagerUtilityTest, OriginalIPDetectionExtension) { + const std::string header_name = "x-cdn-detected-ip"; + auto detection_extension = std::make_shared(header_name); + + ON_CALL(config_, originalIpDetection()).WillByDefault(Return(detection_extension)); + ON_CALL(config_, useRemoteAddress()).WillByDefault(Return(false)); + + // Header is present. + { + TestRequestHeaderMapImpl headers{{header_name, "2.1.3.4"}}; + auto ret = callMutateRequestHeaders(headers, Protocol::Http11); + EXPECT_EQ(ret.downstream_address_, "2.1.3.4:0"); + } + + // Header missing -- fallbacks to default behavior. + { + TestRequestHeaderMapImpl headers; + auto ret = callMutateRequestHeaders(headers, Protocol::Http11); + EXPECT_EQ(ret.downstream_address_, "10.0.0.3:50000"); + } +} + } // namespace Http } // namespace Envoy From 09a28e2aee5276c072b95e01f2eabbe0cb9b7ce6 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Mon, 1 Feb 2021 20:28:17 -0500 Subject: [PATCH 007/100] Use TypedExtensionConfig Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 7 +------ .../v4alpha/http_connection_manager.proto | 10 +--------- docs/root/version_history/current.rst | 2 +- generated_api_shadow/BUILD | 1 + .../v3/http_connection_manager.proto | 7 +------ .../v4alpha/http_connection_manager.proto | 10 +--------- .../filters/network/http_connection_manager/config.cc | 7 +++---- .../network/http_connection_manager/config_test.cc | 2 ++ 8 files changed, 11 insertions(+), 35 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 5f6fc61b118a..326e6f3028a9 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -587,7 +587,7 @@ message HttpConnectionManager { // The configuration of the original IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. - OriginalIPDetectionExtension original_ip_detection = 43; + config.core.v3.TypedExtensionConfig original_ip_detection = 43; } // The configuration to customize local reply returned by Envoy. @@ -856,8 +856,3 @@ message RequestIDExtension { // Request ID extension specific configuration. google.protobuf.Any typed_config = 1; } - -message OriginalIPDetectionExtension { - // Original IP detection extension configuration. - google.protobuf.Any typed_config = 1; -} diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 5bb94db996a5..634d27c6e4a6 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -585,7 +585,7 @@ message HttpConnectionManager { // The configuration of the original IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. - OriginalIPDetectionExtension original_ip_detection = 43; + config.core.v4alpha.TypedExtensionConfig original_ip_detection = 43; } // The configuration to customize local reply returned by Envoy. @@ -861,11 +861,3 @@ message RequestIDExtension { // Request ID extension specific configuration. google.protobuf.Any typed_config = 1; } - -message OriginalIPDetectionExtension { - option (udpa.annotations.versioning).previous_message_type = - "envoy.extensions.filters.network.http_connection_manager.v3.OriginalIPDetectionExtension"; - - // Original IP detection extension configuration. - google.protobuf.Any typed_config = 1; -} diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 46d423a383ce..8ca13795553e 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -74,7 +74,7 @@ New Features * dispatcher: supports a stack of `Envoy::ScopeTrackedObject` instead of a single tracked object. This will allow Envoy to dump more debug information on crash. * grpc_json_transcoder: added option :ref:`strict_http_request_validation ` to reject invalid requests early. * grpc_json_transcoder: filter can now be configured on per-route/per-vhost level as well. Leaving empty list of services in the filter configuration disables transcoding on the specific route. -* http: added support for :ref:`original ip detection extensions`. +* http: added support for :ref:`original IP detection extensions`. * http: added support for :ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. * http: change frame flood and abuse checks to the upstream HTTP/2 codec to ON by default. It can be disabled by setting the `envoy.reloadable_features.upstream_http2_flood_checks` runtime key to false. * overload: add support for scaling :ref:`transport connection timeouts`. This can be used to reduce the TLS handshake timeout in response to overload. diff --git a/generated_api_shadow/BUILD b/generated_api_shadow/BUILD index effde23bad70..300420c00238 100644 --- a/generated_api_shadow/BUILD +++ b/generated_api_shadow/BUILD @@ -146,6 +146,7 @@ proto_library( "//envoy/config/retry/omit_canary_hosts/v2:pkg", "//envoy/config/retry/omit_canary_hosts/v3:pkg", "//envoy/config/retry/previous_hosts/v2:pkg", + "//envoy/config/retry/previous_hosts/v3:pkg", "//envoy/config/route/v3:pkg", "//envoy/config/tap/v3:pkg", "//envoy/config/trace/v3:pkg", diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index bd7e8517cc57..d04bb35c8612 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -589,7 +589,7 @@ message HttpConnectionManager { // The configuration of the original IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. - OriginalIPDetectionExtension original_ip_detection = 43; + config.core.v3.TypedExtensionConfig original_ip_detection = 43; google.protobuf.Duration hidden_envoy_deprecated_idle_timeout = 11 [deprecated = true, (envoy.annotations.disallowed_by_default) = true]; @@ -861,8 +861,3 @@ message RequestIDExtension { // Request ID extension specific configuration. google.protobuf.Any typed_config = 1; } - -message OriginalIPDetectionExtension { - // Original IP detection extension configuration. - google.protobuf.Any typed_config = 1; -} diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 5bb94db996a5..634d27c6e4a6 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -585,7 +585,7 @@ message HttpConnectionManager { // The configuration of the original IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. - OriginalIPDetectionExtension original_ip_detection = 43; + config.core.v4alpha.TypedExtensionConfig original_ip_detection = 43; } // The configuration to customize local reply returned by Envoy. @@ -861,11 +861,3 @@ message RequestIDExtension { // Request ID extension specific configuration. google.protobuf.Any typed_config = 1; } - -message OriginalIPDetectionExtension { - option (udpa.annotations.versioning).previous_message_type = - "envoy.extensions.filters.network.http_connection_manager.v3.OriginalIPDetectionExtension"; - - // Original IP detection extension configuration. - google.protobuf.Any typed_config = 1; -} diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 847d167777ae..d0dfc6c24e16 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -288,11 +288,10 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( } // Check if we are provided with an IP detection extension. - if (config.original_ip_detection().has_typed_config()) { - auto& typed_config = config.original_ip_detection().typed_config(); - const std::string type{TypeUtil::typeUrlToDescriptorFullName(typed_config.type_url())}; + if (config.has_original_ip_detection()) { + auto& typed_config = config.original_ip_detection(); auto* factory = - Registry::FactoryRegistry::getFactoryByType(type); + Envoy::Config::Utility::getFactory(typed_config); if (!factory) { throw EnvoyException("Original IP detection extension not found"); } diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 0a4772bd2596..a12cd8736c8f 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -1748,6 +1748,7 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { route_config: name: local_route original_ip_detection: + name: envoy.ip_detection.UnknownOriginalIPDetectionExtension typed_config: "@type": type.googleapis.com/google.protobuf.StringValue http_filters: @@ -1784,6 +1785,7 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { route_config: name: local_route original_ip_detection: + name: envoy.ip_detection.OriginalIPDetectionExtension typed_config: "@type": type.googleapis.com/google.protobuf.StringValue http_filters: From 2358acb218e37ac733641796b86ed215f560f9c6 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Mon, 1 Feb 2021 20:52:02 -0500 Subject: [PATCH 008/100] Extensive comments around the config message Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 19 +++++++++++++++++++ .../v4alpha/http_connection_manager.proto | 19 +++++++++++++++++++ .../v3/http_connection_manager.proto | 19 +++++++++++++++++++ .../v4alpha/http_connection_manager.proto | 19 +++++++++++++++++++ 4 files changed, 76 insertions(+) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 326e6f3028a9..b08cc87a8590 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -587,6 +587,25 @@ message HttpConnectionManager { // The configuration of the original IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. + // + // When the remote address of the downstream connection is not used as + // the detection mechanism for the request's original address, Envoy + // will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP + // header to detect the address. + // + // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // header doesn't necessarily work for all network configurations. For instance, + // if the number of trusted hops isn't consistent for requests flowing into + // Envoy the header cannot be used reliably. For such cases, the following + // option allows for a custom extension to be provided. + // + // If configured, the custom extension will be called along with the + // request headers when the HCM needs to populate the remote address. + // The extension will then rely on the available headers to decide the + // value of the request's remote address. + // + // An example extension could lookup at a configured header name to figure out the + // remote address as detected by a CDN or some other preceding network. config.core.v3.TypedExtensionConfig original_ip_detection = 43; } diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 634d27c6e4a6..e4bd1588420e 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -585,6 +585,25 @@ message HttpConnectionManager { // The configuration of the original IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. + // + // When the remote address of the downstream connection is not used as + // the detection mechanism for the request's original address, Envoy + // will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP + // header to detect the address. + // + // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // header doesn't necessarily work for all network configurations. For instance, + // if the number of trusted hops isn't consistent for requests flowing into + // Envoy the header cannot be used reliably. For such cases, the following + // option allows for a custom extension to be provided. + // + // If configured, the custom extension will be called along with the + // request headers when the HCM needs to populate the remote address. + // The extension will then rely on the available headers to decide the + // value of the request's remote address. + // + // An example extension could lookup at a configured header name to figure out the + // remote address as detected by a CDN or some other preceding network. config.core.v4alpha.TypedExtensionConfig original_ip_detection = 43; } diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index d04bb35c8612..127ebbb9ec26 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -589,6 +589,25 @@ message HttpConnectionManager { // The configuration of the original IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. + // + // When the remote address of the downstream connection is not used as + // the detection mechanism for the request's original address, Envoy + // will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP + // header to detect the address. + // + // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // header doesn't necessarily work for all network configurations. For instance, + // if the number of trusted hops isn't consistent for requests flowing into + // Envoy the header cannot be used reliably. For such cases, the following + // option allows for a custom extension to be provided. + // + // If configured, the custom extension will be called along with the + // request headers when the HCM needs to populate the remote address. + // The extension will then rely on the available headers to decide the + // value of the request's remote address. + // + // An example extension could lookup at a configured header name to figure out the + // remote address as detected by a CDN or some other preceding network. config.core.v3.TypedExtensionConfig original_ip_detection = 43; google.protobuf.Duration hidden_envoy_deprecated_idle_timeout = 11 diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 634d27c6e4a6..e4bd1588420e 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -585,6 +585,25 @@ message HttpConnectionManager { // The configuration of the original IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. + // + // When the remote address of the downstream connection is not used as + // the detection mechanism for the request's original address, Envoy + // will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP + // header to detect the address. + // + // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // header doesn't necessarily work for all network configurations. For instance, + // if the number of trusted hops isn't consistent for requests flowing into + // Envoy the header cannot be used reliably. For such cases, the following + // option allows for a custom extension to be provided. + // + // If configured, the custom extension will be called along with the + // request headers when the HCM needs to populate the remote address. + // The extension will then rely on the available headers to decide the + // value of the request's remote address. + // + // An example extension could lookup at a configured header name to figure out the + // remote address as detected by a CDN or some other preceding network. config.core.v4alpha.TypedExtensionConfig original_ip_detection = 43; } From 445d0b2423d486237571e36888f05daf0e551f27 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 2 Feb 2021 10:25:40 -0500 Subject: [PATCH 009/100] Fix test Signed-off-by: Raul Gutierrez Segales --- test/common/http/conn_manager_impl_test_base.h | 1 + 1 file changed, 1 insertion(+) diff --git a/test/common/http/conn_manager_impl_test_base.h b/test/common/http/conn_manager_impl_test_base.h index ca36ece9ede6..fa6de8907bd6 100644 --- a/test/common/http/conn_manager_impl_test_base.h +++ b/test/common/http/conn_manager_impl_test_base.h @@ -140,6 +140,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan return headers_with_underscores_action_; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } + Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return nullptr; }; Envoy::Event::SimulatedTimeSystem test_time_; NiceMock route_config_provider_; From c8b4115f81314c5b12d7aa65f385b481326d2fd4 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 2 Feb 2021 13:00:14 -0500 Subject: [PATCH 010/100] Fix another test Signed-off-by: Raul Gutierrez Segales --- test/common/http/conn_manager_impl_fuzz_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/common/http/conn_manager_impl_fuzz_test.cc b/test/common/http/conn_manager_impl_fuzz_test.cc index 132307e4be15..07e1f3ec2754 100644 --- a/test/common/http/conn_manager_impl_fuzz_test.cc +++ b/test/common/http/conn_manager_impl_fuzz_test.cc @@ -206,6 +206,7 @@ class FuzzConfig : public ConnectionManagerConfig { return envoy::config::core::v3::HttpProtocolOptions::ALLOW; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } + Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return nullptr; }; const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager config_; From 0868c1ecbf912e1bc5f1bbb22e4488ad6edd567a Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 2 Feb 2021 15:10:52 -0500 Subject: [PATCH 011/100] clang-tidy fixes Signed-off-by: Raul Gutierrez Segales --- include/envoy/http/BUILD | 1 + include/envoy/http/original_ip_detection.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/include/envoy/http/BUILD b/include/envoy/http/BUILD index 4678c2b4d371..55ebbd5a6e7f 100644 --- a/include/envoy/http/BUILD +++ b/include/envoy/http/BUILD @@ -147,5 +147,6 @@ envoy_cc_library( deps = [ ":header_map_interface", "//include/envoy/config:typed_config_interface", + "//include/envoy/network:address_interface", ], ) diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index ddc6b4c3ee9d..4d6a50d49aa1 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -4,7 +4,9 @@ #include #include "envoy/common/pure.h" +#include "envoy/config/typed_config.h" #include "envoy/http/header_map.h" +#include "envoy/network/address.h" namespace Envoy { namespace Http { From def62d34ad344732cd3ed08f121c4a577b7050cf Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 3 Feb 2021 17:45:14 -0500 Subject: [PATCH 012/100] Add integration test This should probably suffice as a guide for adding new IP detection extensions. Signed-off-by: Raul Gutierrez Segales --- test/integration/BUILD | 11 +++ .../original_ip_detection_integration_test.cc | 75 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 test/integration/original_ip_detection_integration_test.cc diff --git a/test/integration/BUILD b/test/integration/BUILD index 3296268332e5..9bbd86778742 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -1634,3 +1634,14 @@ envoy_cc_test( "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", ], ) + +envoy_cc_test( + name = "original_ip_detection_integration_test", + srcs = [ + "original_ip_detection_integration_test.cc", + ], + deps = [ + ":http_integration_lib", + "//test/test_common:utility_lib", + ], +) diff --git a/test/integration/original_ip_detection_integration_test.cc b/test/integration/original_ip_detection_integration_test.cc new file mode 100644 index 000000000000..a837c28099a9 --- /dev/null +++ b/test/integration/original_ip_detection_integration_test.cc @@ -0,0 +1,75 @@ +#include "test/integration/http_integration.h" +#include "test/test_common/registry.h" +#include "test/test_common/utility.h" + +#include "gtest/gtest.h" + +using testing::HasSubstr; + +namespace Envoy { +namespace Formatter { + +class OriginalIPDetectionIntegrationTest : public testing::Test, public HttpIntegrationTest { +public: + OriginalIPDetectionIntegrationTest() + : HttpIntegrationTest(Http::CodecClient::Type::HTTP1, Network::Address::IpVersion::v4) {} +}; + +class CustomHeaderDetection : public Http::OriginalIPDetection { +public: + CustomHeaderDetection(const std::string& header_name) : header_name_(header_name) {} + + Network::Address::InstanceConstSharedPtr + detect(struct Http::OriginalIPDetectionParams& params) override { + auto hdr = params.request_headers.get(Http::LowerCaseString(header_name_)); + if (hdr.empty()) { + return nullptr; + } + auto header_value = hdr[0]->value().getStringView(); + return std::make_shared(std::string(header_value)); + } + +private: + std::string header_name_; +}; + +class HeaderDetectionFactory : public Http::OriginalIPDetectionFactory { +public: + Http::OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message&) const override { + return std::make_shared("x-cdn-detected-ip"); + } + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return std::make_unique(); + } + std::string name() const override { return "CustomHeaderDetection"; } + std::string category() const override { return "OriginalIpDetection"; } +}; + +TEST_F(OriginalIPDetectionIntegrationTest, HeaderBasedDetection) { + HeaderDetectionFactory factory; + Registry::InjectFactory header_detection_factory_register( + factory); + + useAccessLog("%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%"); + config_helper_.addConfigModifier( + [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& + hcm) -> void { + ProtobufWkt::StringValue config; + + auto* original_ip_detection = hcm.mutable_original_ip_detection(); + original_ip_detection->set_name("CustomHeaderDetection"); + original_ip_detection->mutable_typed_config()->PackFrom(config); + + hcm.mutable_use_remote_address()->set_value(false); + }); + initialize(); + std::string response; + sendRawHttpAndWaitForResponse( + lookupPort("http"), "GET / HTTP/1.1\r\nHost: host\r\nx-cdn-detected-ip: 9.9.9.9\r\n\r\n", + &response, true); + std::string log = waitForAccessLog(access_log_name_); + EXPECT_THAT(log, HasSubstr("9.9.9.9")); +} + +} // namespace Formatter +} // namespace Envoy From 863481950af804d5da8a6a9f0394e1eff39d12d7 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 10 Feb 2021 21:43:23 -0500 Subject: [PATCH 013/100] Address Alyssa's review. Just saw Antonio's review come in, I'll address those comments in a follow-up. Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 12 +++++++----- .../v4alpha/http_connection_manager.proto | 12 +++++++----- .../arch_overview/other_features/ip_transparency.rst | 5 ++++- generated_api_shadow/BUILD | 2 ++ .../v3/http_connection_manager.proto | 12 +++++++----- .../v4alpha/http_connection_manager.proto | 12 +++++++----- include/envoy/http/original_ip_detection.h | 10 ++++++++++ source/common/http/conn_manager_utility.cc | 3 ++- 8 files changed, 46 insertions(+), 22 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 25a2e799fb85..1780da2c4b4b 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -582,7 +582,7 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the original IP detection extension. + // The configuration of the original-IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. // @@ -598,11 +598,13 @@ message HttpConnectionManager { // option allows for a custom extension to be provided. // // If configured, the custom extension will be called along with the - // request headers when the HCM needs to populate the remote address. - // The extension will then rely on the available headers to decide the - // value of the request's remote address. + // request headers and the downstream directly connected address when the + // HCM needs to populate the final remote address. The extension will then rely + // on these parameters to decide the value of the request's final remote address. + // If the extension fails to detect the original IP address, the HCM will then fallback + // to the standard detection mechanisms. // - // An example extension could lookup at a configured header name to figure out the + // An example extension could look up at a configured header name to figure out the // remote address as detected by a CDN or some other preceding network. config.core.v3.TypedExtensionConfig original_ip_detection = 43; } diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 23c254e1dab4..fe09e4426981 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -580,7 +580,7 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the original IP detection extension. + // The configuration of the original-IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. // @@ -596,11 +596,13 @@ message HttpConnectionManager { // option allows for a custom extension to be provided. // // If configured, the custom extension will be called along with the - // request headers when the HCM needs to populate the remote address. - // The extension will then rely on the available headers to decide the - // value of the request's remote address. + // request headers and the downstream directly connected address when the + // HCM needs to populate the final remote address. The extension will then rely + // on these parameters to decide the value of the request's final remote address. + // If the extension fails to detect the original IP address, the HCM will then fallback + // to the standard detection mechanisms. // - // An example extension could lookup at a configured header name to figure out the + // An example extension could look up at a configured header name to figure out the // remote address as detected by a CDN or some other preceding network. config.core.v4alpha.TypedExtensionConfig original_ip_detection = 43; } diff --git a/docs/root/intro/arch_overview/other_features/ip_transparency.rst b/docs/root/intro/arch_overview/other_features/ip_transparency.rst index 1aab4fd75ade..f4239a366aae 100644 --- a/docs/root/intro/arch_overview/other_features/ip_transparency.rst +++ b/docs/root/intro/arch_overview/other_features/ip_transparency.rst @@ -23,7 +23,10 @@ These techniques vary in complexity and applicability. Envoy also supports an :ref:`extension mechanism` for detecting the original IP address. This might be useful if none of the techniques below is -applicable to your setup. +applicable to your setup. Note that, if configured, an extension will be called ahead of the +attempt to extract the downstream remote address from the +:ref:`x-forwarded-for ` header. If the extension +fails to detect the original IP address, the standard detection mechanisms will then be exercised. HTTP Headers ------------ diff --git a/generated_api_shadow/BUILD b/generated_api_shadow/BUILD index 300420c00238..daee0fd94426 100644 --- a/generated_api_shadow/BUILD +++ b/generated_api_shadow/BUILD @@ -165,6 +165,8 @@ proto_library( "//envoy/extensions/common/matching/v3:pkg", "//envoy/extensions/common/ratelimit/v3:pkg", "//envoy/extensions/common/tap/v3:pkg", + "//envoy/extensions/compression/brotli/compressor/v3:pkg", + "//envoy/extensions/compression/brotli/decompressor/v3:pkg", "//envoy/extensions/compression/gzip/compressor/v3:pkg", "//envoy/extensions/compression/gzip/decompressor/v3:pkg", "//envoy/extensions/filters/common/dependency/v3:pkg", diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 127ebbb9ec26..b50092fd5875 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -586,7 +586,7 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the original IP detection extension. + // The configuration of the original-IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. // @@ -602,11 +602,13 @@ message HttpConnectionManager { // option allows for a custom extension to be provided. // // If configured, the custom extension will be called along with the - // request headers when the HCM needs to populate the remote address. - // The extension will then rely on the available headers to decide the - // value of the request's remote address. + // request headers and the downstream directly connected address when the + // HCM needs to populate the final remote address. The extension will then rely + // on these parameters to decide the value of the request's final remote address. + // If the extension fails to detect the original IP address, the HCM will then fallback + // to the standard detection mechanisms. // - // An example extension could lookup at a configured header name to figure out the + // An example extension could look up at a configured header name to figure out the // remote address as detected by a CDN or some other preceding network. config.core.v3.TypedExtensionConfig original_ip_detection = 43; diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 23c254e1dab4..fe09e4426981 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -580,7 +580,7 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the original IP detection extension. + // The configuration of the original-IP detection extension. // // If not set, Envoy uses the default remote IP detection mechanism. // @@ -596,11 +596,13 @@ message HttpConnectionManager { // option allows for a custom extension to be provided. // // If configured, the custom extension will be called along with the - // request headers when the HCM needs to populate the remote address. - // The extension will then rely on the available headers to decide the - // value of the request's remote address. + // request headers and the downstream directly connected address when the + // HCM needs to populate the final remote address. The extension will then rely + // on these parameters to decide the value of the request's final remote address. + // If the extension fails to detect the original IP address, the HCM will then fallback + // to the standard detection mechanisms. // - // An example extension could lookup at a configured header name to figure out the + // An example extension could look up at a configured header name to figure out the // remote address as detected by a CDN or some other preceding network. config.core.v4alpha.TypedExtensionConfig original_ip_detection = 43; } diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index 4d6a50d49aa1..21a0f9c364b3 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -12,7 +12,10 @@ namespace Envoy { namespace Http { struct OriginalIPDetectionParams { + // Note: headers will be sanitized after the OriginalIPDetection::detect() call. Http::RequestHeaderMap& request_headers; + // The downstream directly connected address. + Network::Address::InstanceConstSharedPtr downstream_remote_address; }; /** @@ -25,7 +28,14 @@ class OriginalIPDetection { /** * Detect the final remote address. * + * Note that, when an extension is configured, this method will be called + * ahead of the attempt to extract the downstream remote address from the + * x-forwarded-for header. If the call fails to detect the original IP address, + * the HCM will then fallback to the standard IP detection mechanisms. + * * @param param supplies the OriginalIPDetectionParams params for detection. + * @return Address::InstanceConstSharedPtr an address that represents the detected address or + * nullptr. */ virtual Network::Address::InstanceConstSharedPtr detect(struct OriginalIPDetectionParams& params) PURE; diff --git a/source/common/http/conn_manager_utility.cc b/source/common/http/conn_manager_utility.cc index aa6cc1ca63bf..968830a4a0cf 100644 --- a/source/common/http/conn_manager_utility.cc +++ b/source/common/http/conn_manager_utility.cc @@ -135,7 +135,8 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest // used for determining internal/external status (see below). auto original_ip_detection = config.originalIpDetection(); if (original_ip_detection) { - struct OriginalIPDetectionParams params = {request_headers}; + struct OriginalIPDetectionParams params = {request_headers, + connection.addressProvider().remoteAddress()}; final_remote_address = original_ip_detection->detect(params); } From 7d4d71b79eab72ccde337f9cc2bfcefd328ce61c Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 10 Feb 2021 23:52:54 -0500 Subject: [PATCH 014/100] Don't copy downstream_remote_address Signed-off-by: Raul Gutierrez Segales --- include/envoy/http/original_ip_detection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index 21a0f9c364b3..a778ede44ce6 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -15,7 +15,7 @@ struct OriginalIPDetectionParams { // Note: headers will be sanitized after the OriginalIPDetection::detect() call. Http::RequestHeaderMap& request_headers; // The downstream directly connected address. - Network::Address::InstanceConstSharedPtr downstream_remote_address; + Network::Address::InstanceConstSharedPtr& downstream_remote_address; }; /** From b30ce452b8e6ed1f0ed249090dc97571ed310e46 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 11 Feb 2021 12:25:23 -0500 Subject: [PATCH 015/100] Fix build Signed-off-by: Raul Gutierrez Segales --- include/envoy/http/original_ip_detection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index a778ede44ce6..8a4bee0f0d5a 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -15,7 +15,7 @@ struct OriginalIPDetectionParams { // Note: headers will be sanitized after the OriginalIPDetection::detect() call. Http::RequestHeaderMap& request_headers; // The downstream directly connected address. - Network::Address::InstanceConstSharedPtr& downstream_remote_address; + const Network::Address::InstanceConstSharedPtr& downstream_remote_address; }; /** From 406d8258c5c1085bdad0657e8ede129aea1e7629 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 11 Feb 2021 12:35:41 -0500 Subject: [PATCH 016/100] Drop struct Signed-off-by: Raul Gutierrez Segales --- include/envoy/http/original_ip_detection.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index 8a4bee0f0d5a..660f34f06a1f 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -37,8 +37,7 @@ class OriginalIPDetection { * @return Address::InstanceConstSharedPtr an address that represents the detected address or * nullptr. */ - virtual Network::Address::InstanceConstSharedPtr - detect(struct OriginalIPDetectionParams& params) PURE; + virtual Network::Address::InstanceConstSharedPtr detect(OriginalIPDetectionParams& params) PURE; }; using OriginalIPDetectionSharedPtr = std::shared_ptr; From 7440409099654c0bba618180e3aed3baadab2c0f Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 12 Feb 2021 14:40:06 -0500 Subject: [PATCH 017/100] Review feedback * Use a Result type for detect() * add CustomHeader as an included extension * more fixes Signed-off-by: Raul Gutierrez Segales --- api/BUILD | 1 + .../custom_header/v3/BUILD | 12 ++++ .../custom_header/v3/custom_header.proto | 40 ++++++++++++ api/versioning/BUILD | 1 + bazel/envoy_library.bzl | 1 + generated_api_shadow/BUILD | 2 +- .../custom_header/v3/BUILD | 12 ++++ .../custom_header/v3/custom_header.proto | 40 ++++++++++++ include/envoy/http/original_ip_detection.h | 20 ++++-- source/common/http/conn_manager_utility.cc | 15 +++-- source/extensions/extensions_build_config.bzl | 6 ++ .../original_ip_detection/custom_header/BUILD | 35 +++++++++++ .../custom_header/config.cc | 27 ++++++++ .../custom_header/config.h | 29 +++++++++ .../custom_header/custom_header.cc | 32 ++++++++++ .../custom_header/custom_header.h | 26 ++++++++ test/common/http/conn_manager_utility_test.cc | 7 +-- .../http_connection_manager/config_test.cc | 7 ++- .../original_ip_detection/custom_header/BUILD | 37 +++++++++++ .../custom_header/config_test.cc | 29 +++++++++ .../custom_header/custom_header_test.cc | 62 +++++++++++++++++++ 21 files changed, 424 insertions(+), 17 deletions(-) create mode 100644 api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD create mode 100644 api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto create mode 100644 generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD create mode 100644 generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto create mode 100644 source/extensions/original_ip_detection/custom_header/BUILD create mode 100644 source/extensions/original_ip_detection/custom_header/config.cc create mode 100644 source/extensions/original_ip_detection/custom_header/config.h create mode 100644 source/extensions/original_ip_detection/custom_header/custom_header.cc create mode 100644 source/extensions/original_ip_detection/custom_header/custom_header.h create mode 100644 test/extensions/original_ip_detection/custom_header/BUILD create mode 100644 test/extensions/original_ip_detection/custom_header/config_test.cc create mode 100644 test/extensions/original_ip_detection/custom_header/custom_header_test.cc diff --git a/api/BUILD b/api/BUILD index 046fac3d012d..a824d4500c40 100644 --- a/api/BUILD +++ b/api/BUILD @@ -244,6 +244,7 @@ proto_library( "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", + "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/resource_monitors/fixed_heap/v3:pkg", "//envoy/extensions/resource_monitors/injected_resource/v3:pkg", diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD b/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD new file mode 100644 index 000000000000..9a76b7e148e0 --- /dev/null +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD @@ -0,0 +1,12 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/type/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto new file mode 100644 index 000000000000..c5481362674d --- /dev/null +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +package envoy.extensions.original_ip_detection.custom_header.v3; + +import "envoy/type/v3/http_status.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.custom_header.v3"; +option java_outer_classname = "CustomHeaderProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Custom header original IP detection extension] +// +// This extension allows for the original dowstream remote IP to be detected +// by reading the value for a configured header name. If the value is successfully parsed +// as an IP, it'll be treated as the effective downstream remote address and seen as such +// by all filters. If the detection or parsing of the header value fails, Envoy will fallback +// to its default detection extension. +// +// [#extension: envoy.original_ip_detection.custom_header] +message CustomHeaderConfig { + // The name for the header containing the original downstream remote address, if present. + string header_name = 1; + + // Is the detected address trusted (e.g.: can it be used to determine if this is an internal + // request). + bool allow_trusted_address_checks = 2; + + // If true, requests for which either the configured header is missing or parsing an IP from its + // value fails will be rejected. + bool reject_request_if_detection_fails = 3; + + // If reject_request_if_detection_fails is set, this Sets the HTTP status that is returned to the client + // when detection fails. The default status is HTTP 403 Forbidden. + type.v3.HttpStatus status_on_error = 4; +} diff --git a/api/versioning/BUILD b/api/versioning/BUILD index f5bb3ce6e8d9..f5f10b549a1f 100644 --- a/api/versioning/BUILD +++ b/api/versioning/BUILD @@ -127,6 +127,7 @@ proto_library( "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", + "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/resource_monitors/fixed_heap/v3:pkg", "//envoy/extensions/resource_monitors/injected_resource/v3:pkg", diff --git a/bazel/envoy_library.bzl b/bazel/envoy_library.bzl index d052c481ace5..8343da584e68 100644 --- a/bazel/envoy_library.bzl +++ b/bazel/envoy_library.bzl @@ -83,6 +83,7 @@ EXTENSION_CATEGORIES = [ "envoy.health_checkers", "envoy.internal_redirect_predicates", "envoy.io_socket", + "envoy.original_ip_detection", "envoy.rate_limit_descriptors", "envoy.resolvers", "envoy.resource_monitors", diff --git a/generated_api_shadow/BUILD b/generated_api_shadow/BUILD index e2e5b3bfeb77..a824d4500c40 100644 --- a/generated_api_shadow/BUILD +++ b/generated_api_shadow/BUILD @@ -145,7 +145,6 @@ proto_library( "//envoy/config/resource_monitor/injected_resource/v2alpha:pkg", "//envoy/config/retry/omit_canary_hosts/v2:pkg", "//envoy/config/retry/previous_hosts/v2:pkg", - "//envoy/config/retry/previous_hosts/v3:pkg", "//envoy/config/route/v3:pkg", "//envoy/config/tap/v3:pkg", "//envoy/config/trace/v3:pkg", @@ -245,6 +244,7 @@ proto_library( "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", + "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/resource_monitors/fixed_heap/v3:pkg", "//envoy/extensions/resource_monitors/injected_resource/v3:pkg", diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD new file mode 100644 index 000000000000..9a76b7e148e0 --- /dev/null +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD @@ -0,0 +1,12 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/type/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto new file mode 100644 index 000000000000..c5481362674d --- /dev/null +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +package envoy.extensions.original_ip_detection.custom_header.v3; + +import "envoy/type/v3/http_status.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.custom_header.v3"; +option java_outer_classname = "CustomHeaderProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Custom header original IP detection extension] +// +// This extension allows for the original dowstream remote IP to be detected +// by reading the value for a configured header name. If the value is successfully parsed +// as an IP, it'll be treated as the effective downstream remote address and seen as such +// by all filters. If the detection or parsing of the header value fails, Envoy will fallback +// to its default detection extension. +// +// [#extension: envoy.original_ip_detection.custom_header] +message CustomHeaderConfig { + // The name for the header containing the original downstream remote address, if present. + string header_name = 1; + + // Is the detected address trusted (e.g.: can it be used to determine if this is an internal + // request). + bool allow_trusted_address_checks = 2; + + // If true, requests for which either the configured header is missing or parsing an IP from its + // value fails will be rejected. + bool reject_request_if_detection_fails = 3; + + // If reject_request_if_detection_fails is set, this Sets the HTTP status that is returned to the client + // when detection fails. The default status is HTTP 403 Forbidden. + type.v3.HttpStatus status_on_error = 4; +} diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index 660f34f06a1f..30a6b67eae8e 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -12,12 +12,22 @@ namespace Envoy { namespace Http { struct OriginalIPDetectionParams { - // Note: headers will be sanitized after the OriginalIPDetection::detect() call. + // Note that while extensions can modify the headers, they will undergo standard Envoy + // sanitation after the detect() call so additions made here may be removed before + // filters have access to headers. Http::RequestHeaderMap& request_headers; // The downstream directly connected address. const Network::Address::InstanceConstSharedPtr& downstream_remote_address; }; +struct OriginalIPDetectionResult { + // An address that represents the detected address or nullptr if detection failed. + Network::Address::InstanceConstSharedPtr detected_remote_address; + // Is the detected address trusted (e.g.: can it be used to determine if this is an internal + // request). + bool allow_trusted_address_checks; +}; + /** * Interface class for original IP detection extensions. */ @@ -34,10 +44,10 @@ class OriginalIPDetection { * the HCM will then fallback to the standard IP detection mechanisms. * * @param param supplies the OriginalIPDetectionParams params for detection. - * @return Address::InstanceConstSharedPtr an address that represents the detected address or - * nullptr. + * @return OriginalIPDetectionResult the result of the extension's attempt to detect + * the final remote address. */ - virtual Network::Address::InstanceConstSharedPtr detect(OriginalIPDetectionParams& params) PURE; + virtual OriginalIPDetectionResult detect(OriginalIPDetectionParams& params) PURE; }; using OriginalIPDetectionSharedPtr = std::shared_ptr; @@ -56,6 +66,8 @@ class OriginalIPDetectionFactory : public Envoy::Config::TypedFactory { * @return OriginalIPDetectionSharedPtr the extension instance. */ virtual OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message& config) const PURE; + + std::string category() const override { return "envoy.original_ip_detection"; } }; using OriginalIPDetectionFactoryPtr = std::unique_ptr; diff --git a/source/common/http/conn_manager_utility.cc b/source/common/http/conn_manager_utility.cc index 968830a4a0cf..94f6e4234f8b 100644 --- a/source/common/http/conn_manager_utility.cc +++ b/source/common/http/conn_manager_utility.cc @@ -95,11 +95,11 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest // peer. Cases where we don't "use remote address" include trusted double proxy where we expect // our peer to have already properly set XFF, etc. Network::Address::InstanceConstSharedPtr final_remote_address; - bool single_xff_address = false; + bool allow_trusted_address_checks = false; const uint32_t xff_num_trusted_hops = config.xffNumTrustedHops(); if (config.useRemoteAddress()) { - single_xff_address = request_headers.ForwardedFor() == nullptr; + allow_trusted_address_checks = request_headers.ForwardedFor() == nullptr; // If there are any trusted proxies in front of this Envoy instance (as indicated by // the xff_num_trusted_hops configuration option), get the trusted client address // from the XFF before we append to XFF. @@ -137,14 +137,19 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest if (original_ip_detection) { struct OriginalIPDetectionParams params = {request_headers, connection.addressProvider().remoteAddress()}; - final_remote_address = original_ip_detection->detect(params); + auto result = original_ip_detection->detect(params); + + if (result.detected_remote_address) { + final_remote_address = result.detected_remote_address; + allow_trusted_address_checks = result.allow_trusted_address_checks; + } } // If there's no extension or it failed to detect, give XFF a try. if (!final_remote_address) { auto ret = Utility::getLastAddressFromXFF(request_headers, xff_num_trusted_hops); final_remote_address = ret.address_; - single_xff_address = ret.single_address_; + allow_trusted_address_checks = ret.single_address_; } } @@ -165,7 +170,7 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest // we can't change it at this point. In the future we will likely need to add // additional inference modes and make this mode legacy. const bool internal_request = - single_xff_address && final_remote_address != nullptr && + allow_trusted_address_checks && final_remote_address != nullptr && config.internalAddressConfig().isInternalAddress(*final_remote_address); // After determining internal request status, if there is no final remote address, due to no XFF, diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index 8b2565a0fa84..e152fc0f0d8a 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -243,6 +243,12 @@ EXTENSIONS = { # "envoy.io_socket.user_space": "//source/extensions/io_socket/user_space:config", + + # + # Original IP detection + # + + "envoy.original_ip_detection.custom_header": "//source/extensions/original_ip_detection/custom_header:config", } # These can be changed to ["//visibility:public"], for downstream builds which diff --git a/source/extensions/original_ip_detection/custom_header/BUILD b/source/extensions/original_ip_detection/custom_header/BUILD new file mode 100644 index 000000000000..9c5ee22d25c0 --- /dev/null +++ b/source/extensions/original_ip_detection/custom_header/BUILD @@ -0,0 +1,35 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_extension", + "envoy_cc_library", + "envoy_extension_package", +) + +licenses(["notice"]) # Apache 2 + +envoy_extension_package() + +envoy_cc_library( + name = "custom_header_lib", + srcs = ["custom_header.cc"], + hdrs = ["custom_header.h"], + deps = [ + "//include/envoy/http:original_ip_detection_interface", + "//source/common/network:utility_lib", + "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", + ], +) + +envoy_cc_extension( + name = "config", + srcs = ["config.cc"], + hdrs = ["config.h"], + category = "envoy.original_ip_detection", + security_posture = "robust_to_untrusted_downstream", + deps = [ + ":custom_header_lib", + "//include/envoy/http:original_ip_detection_interface", + "//include/envoy/registry", + "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", + ], +) diff --git a/source/extensions/original_ip_detection/custom_header/config.cc b/source/extensions/original_ip_detection/custom_header/config.cc new file mode 100644 index 000000000000..6dd7192d9f59 --- /dev/null +++ b/source/extensions/original_ip_detection/custom_header/config.cc @@ -0,0 +1,27 @@ +#include "extensions/original_ip_detection/custom_header/config.h" +#include "extensions/original_ip_detection/custom_header/custom_header.h" + +#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" +#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.validate.h" +#include "envoy/http/original_ip_detection.h" +#include "envoy/registry/registry.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace CustomHeader { + +Http::OriginalIPDetectionSharedPtr +CustomHeaderIPDetectionFactory::createExtension(const Protobuf::Message& message) const { + return std::make_shared( + dynamic_cast< + const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig&>( + message)); +} + +REGISTER_FACTORY(CustomHeaderIPDetectionFactory, Http::OriginalIPDetectionFactory); + +} // namespace CustomHeader +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/original_ip_detection/custom_header/config.h b/source/extensions/original_ip_detection/custom_header/config.h new file mode 100644 index 000000000000..14e6819a7946 --- /dev/null +++ b/source/extensions/original_ip_detection/custom_header/config.h @@ -0,0 +1,29 @@ +#pragma once + +#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" +#include "envoy/http/original_ip_detection.h" + +#include "common/protobuf/protobuf.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace CustomHeader { + +class CustomHeaderIPDetectionFactory : public Http::OriginalIPDetectionFactory { +public: + Http::OriginalIPDetectionSharedPtr + createExtension(const Protobuf::Message& message) const override; + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return ProtobufTypes::MessagePtr( + new envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig()); + } + + std::string name() const override { return "envoy.original_ip_detection.custom_header"; } +}; + +} // namespace CustomHeader +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc new file mode 100644 index 000000000000..10130f8f88da --- /dev/null +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -0,0 +1,32 @@ +#include "extensions/original_ip_detection/custom_header/custom_header.h" + +#include "common/network/utility.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace CustomHeader { + +CustomHeaderIPDetection::CustomHeaderIPDetection( + const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& config) + : header_name_(config.header_name()) {} + +Http::OriginalIPDetectionResult +CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { + auto hdr = params.request_headers.get(Http::LowerCaseString(header_name_)); + if (hdr.empty()) { + return {nullptr, false}; + } + auto header_value = hdr[0]->value().getStringView(); + try { + return {Network::Utility::parseInternetAddress(std::string(header_value)), false}; + } catch (const EnvoyException&) { + } + + return {nullptr, false}; +} + +} // namespace CustomHeader +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.h b/source/extensions/original_ip_detection/custom_header/custom_header.h new file mode 100644 index 000000000000..12403dfb3ea3 --- /dev/null +++ b/source/extensions/original_ip_detection/custom_header/custom_header.h @@ -0,0 +1,26 @@ +#pragma once + +#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" +#include "envoy/http/original_ip_detection.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace CustomHeader { + +class CustomHeaderIPDetection : public Http::OriginalIPDetection { +public: + CustomHeaderIPDetection( + const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& + config); + + Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override; + +private: + std::string header_name_; +}; + +} // namespace CustomHeader +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index 3c92d91feba7..e6e599274d3d 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -1548,14 +1548,13 @@ class CustomHeaderBasedDetection : public Http::OriginalIPDetection { public: CustomHeaderBasedDetection(const std::string& header_name) : header_name_(header_name) {} - Network::Address::InstanceConstSharedPtr - detect(struct Http::OriginalIPDetectionParams& params) override { + Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override { auto hdr = params.request_headers.get(LowerCaseString(header_name_)); if (hdr.empty()) { - return nullptr; + return {nullptr, false}; } auto header_value = hdr[0]->value().getStringView(); - return std::make_shared(std::string(header_value)); + return {std::make_shared(std::string(header_value)), false}; } private: diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index a12cd8736c8f..e8c56c965764 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -1760,13 +1760,14 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { } class TestIPDetection : public Http::OriginalIPDetection { - Network::Address::InstanceConstSharedPtr - detect(struct Http::OriginalIPDetectionParams&) override { - return nullptr; +public: + Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams&) override { + return {nullptr, false}; } }; class TestIPDetectionFactory : public Http::OriginalIPDetectionFactory { +public: Http::OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message&) const override { return std::make_shared(); } diff --git a/test/extensions/original_ip_detection/custom_header/BUILD b/test/extensions/original_ip_detection/custom_header/BUILD new file mode 100644 index 000000000000..56b7d1134fde --- /dev/null +++ b/test/extensions/original_ip_detection/custom_header/BUILD @@ -0,0 +1,37 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_package", +) +load( + "//test/extensions:extensions_build_system.bzl", + "envoy_extension_cc_test", +) + +licenses(["notice"]) # Apache 2 + +envoy_package() + +envoy_extension_cc_test( + name = "custom_header_detection_test", + extension_name = "envoy.original_ip_detection.custom_header", + srcs = ["custom_header_test.cc"], + deps = [ + "//source/common/network:utility_lib", + "//source/extensions/original_ip_detection/custom_header:custom_header_lib", + "//test/test_common:utility_lib", + "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", + ], +) + +envoy_extension_cc_test( + name = "config_test", + extension_name = "envoy.original_ip_detection.custom_header", + srcs = ["config_test.cc"], + deps = [ + "//include/envoy/registry", + "//source/extensions/original_ip_detection/custom_header:config", + "//source/extensions/original_ip_detection/custom_header:custom_header_lib", + "//test/test_common:utility_lib", + "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", + ], +) diff --git a/test/extensions/original_ip_detection/custom_header/config_test.cc b/test/extensions/original_ip_detection/custom_header/config_test.cc new file mode 100644 index 000000000000..e1790896459d --- /dev/null +++ b/test/extensions/original_ip_detection/custom_header/config_test.cc @@ -0,0 +1,29 @@ +#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" +#include "envoy/registry/registry.h" + +#include "extensions/original_ip_detection/custom_header/config.h" + +#include "test/test_common/utility.h" + +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace CustomHeader { + +TEST(CustomHeaderFactoryTest, Basic) { + auto* factory = Registry::FactoryRegistry::getFactory( + "envoy.original_ip_detection.custom_header"); + ASSERT_NE(factory, nullptr); + + envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; + config.set_header_name("x-real-ip"); + + EXPECT_NE(factory->createExtension(config), nullptr); +} + +} // namespace CustomHeader +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc new file mode 100644 index 000000000000..3aaef7658030 --- /dev/null +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -0,0 +1,62 @@ +#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" + +#include "extensions/original_ip_detection/custom_header/custom_header.h" + +#include "common/network/utility.h" + +#include "test/test_common/utility.h" + +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace CustomHeader { + +class CustomHeaderTest : public testing::Test { +protected: + CustomHeaderTest() { + envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; + config.set_header_name("x-real-ip"); + custom_header_extension_ = std::make_shared(config); + } + + std::shared_ptr custom_header_extension_; +}; + +TEST_F(CustomHeaderTest, Detection) { + // Header missing. + { + Http::TestRequestHeaderMapImpl headers{{"x-other", "abc"}}; + Http::OriginalIPDetectionParams params = {headers, nullptr}; + auto result = custom_header_extension_->detect(params); + + EXPECT_EQ(nullptr, result.detected_remote_address); + EXPECT_FALSE(result.allow_trusted_address_checks); + } + + // Bad IP in the header. + { + Http::TestRequestHeaderMapImpl headers{{"x-real-ip", "not-a-real-ip"}}; + Http::OriginalIPDetectionParams params = {headers, nullptr}; + auto result = custom_header_extension_->detect(params); + + EXPECT_EQ(nullptr, result.detected_remote_address); + EXPECT_FALSE(result.allow_trusted_address_checks); + } + + // Good IP. + { + Http::TestRequestHeaderMapImpl headers{{"x-real-ip", "1.2.3.4"}}; + Http::OriginalIPDetectionParams params = {headers, nullptr}; + auto result = custom_header_extension_->detect(params); + + EXPECT_EQ("1.2.3.4:0", result.detected_remote_address->asString()); + EXPECT_FALSE(result.allow_trusted_address_checks); + } +} + +} // namespace CustomHeader +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy From 39603372701b15e1576efb6b8ff4d65249fa49d2 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 12 Feb 2021 14:42:59 -0500 Subject: [PATCH 018/100] Implement/Exercise allow_trusted_address_checks option Signed-off-by: Raul Gutierrez Segales --- .../original_ip_detection/custom_header/custom_header.cc | 6 ++++-- .../original_ip_detection/custom_header/custom_header.h | 1 + .../custom_header/custom_header_test.cc | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc index 10130f8f88da..d98bc304202c 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -9,7 +9,8 @@ namespace CustomHeader { CustomHeaderIPDetection::CustomHeaderIPDetection( const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& config) - : header_name_(config.header_name()) {} + : header_name_(config.header_name()), + allow_trusted_address_checks_(config.allow_trusted_address_checks()) {} Http::OriginalIPDetectionResult CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { @@ -19,7 +20,8 @@ CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { } auto header_value = hdr[0]->value().getStringView(); try { - return {Network::Utility::parseInternetAddress(std::string(header_value)), false}; + return {Network::Utility::parseInternetAddress(std::string(header_value)), + allow_trusted_address_checks_}; } catch (const EnvoyException&) { } diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.h b/source/extensions/original_ip_detection/custom_header/custom_header.h index 12403dfb3ea3..90758196de88 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.h +++ b/source/extensions/original_ip_detection/custom_header/custom_header.h @@ -18,6 +18,7 @@ class CustomHeaderIPDetection : public Http::OriginalIPDetection { private: std::string header_name_; + bool allow_trusted_address_checks_; }; } // namespace CustomHeader diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index 3aaef7658030..7177cf68bb1a 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -18,6 +18,7 @@ class CustomHeaderTest : public testing::Test { CustomHeaderTest() { envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; config.set_header_name("x-real-ip"); + config.set_allow_trusted_address_checks(true); custom_header_extension_ = std::make_shared(config); } @@ -52,7 +53,7 @@ TEST_F(CustomHeaderTest, Detection) { auto result = custom_header_extension_->detect(params); EXPECT_EQ("1.2.3.4:0", result.detected_remote_address->asString()); - EXPECT_FALSE(result.allow_trusted_address_checks); + EXPECT_TRUE(result.allow_trusted_address_checks); } } From 24a45b02256a78b53b891857439c6163c36d4a00 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 12 Feb 2021 15:43:28 -0500 Subject: [PATCH 019/100] Drop struct Signed-off-by: Raul Gutierrez Segales --- source/common/http/conn_manager_utility.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/common/http/conn_manager_utility.cc b/source/common/http/conn_manager_utility.cc index 94f6e4234f8b..edaab942ec67 100644 --- a/source/common/http/conn_manager_utility.cc +++ b/source/common/http/conn_manager_utility.cc @@ -135,10 +135,10 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest // used for determining internal/external status (see below). auto original_ip_detection = config.originalIpDetection(); if (original_ip_detection) { - struct OriginalIPDetectionParams params = {request_headers, - connection.addressProvider().remoteAddress()}; - auto result = original_ip_detection->detect(params); + OriginalIPDetectionParams params = {request_headers, + connection.addressProvider().remoteAddress()}; + auto result = original_ip_detection->detect(params); if (result.detected_remote_address) { final_remote_address = result.detected_remote_address; allow_trusted_address_checks = result.allow_trusted_address_checks; From 612ae54f8d2575e99ed2c1fec03d2d94f583ac3d Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 12 Feb 2021 17:40:39 -0500 Subject: [PATCH 020/100] Add XFF detection extension Signed-off-by: Raul Gutierrez Segales --- api/BUILD | 2 + .../original_ip_detection/common/v3/BUILD | 12 +++++ .../common/v3/original_ip_detection.proto | 29 +++++++++++ .../custom_header/v3/BUILD | 2 +- .../custom_header/v3/custom_header.proto | 15 ++---- .../original_ip_detection/xff/v3/BUILD | 12 +++++ .../original_ip_detection/xff/v3/xff.proto | 35 +++++++++++++ api/versioning/BUILD | 2 + generated_api_shadow/BUILD | 2 + .../original_ip_detection/common/v3/BUILD | 12 +++++ .../common/v3/original_ip_detection.proto | 29 +++++++++++ .../custom_header/v3/BUILD | 2 +- .../custom_header/v3/custom_header.proto | 15 ++---- .../original_ip_detection/xff/v3/BUILD | 12 +++++ .../original_ip_detection/xff/v3/xff.proto | 35 +++++++++++++ source/extensions/extensions_build_config.bzl | 1 + .../custom_header/custom_header.cc | 2 +- .../original_ip_detection/xff/BUILD | 35 +++++++++++++ .../original_ip_detection/xff/config.cc | 25 ++++++++++ .../original_ip_detection/xff/config.h | 29 +++++++++++ .../original_ip_detection/xff/xff.cc | 25 ++++++++++ .../original_ip_detection/xff/xff.h | 25 ++++++++++ .../custom_header/custom_header_test.cc | 2 +- .../original_ip_detection/xff/BUILD | 37 ++++++++++++++ .../original_ip_detection/xff/config_test.cc | 29 +++++++++++ .../original_ip_detection/xff/xff_test.cc | 50 +++++++++++++++++++ 26 files changed, 448 insertions(+), 28 deletions(-) create mode 100644 api/envoy/extensions/original_ip_detection/common/v3/BUILD create mode 100644 api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto create mode 100644 api/envoy/extensions/original_ip_detection/xff/v3/BUILD create mode 100644 api/envoy/extensions/original_ip_detection/xff/v3/xff.proto create mode 100644 generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/BUILD create mode 100644 generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto create mode 100644 generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/BUILD create mode 100644 generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto create mode 100644 source/extensions/original_ip_detection/xff/BUILD create mode 100644 source/extensions/original_ip_detection/xff/config.cc create mode 100644 source/extensions/original_ip_detection/xff/config.h create mode 100644 source/extensions/original_ip_detection/xff/xff.cc create mode 100644 source/extensions/original_ip_detection/xff/xff.h create mode 100644 test/extensions/original_ip_detection/xff/BUILD create mode 100644 test/extensions/original_ip_detection/xff/config_test.cc create mode 100644 test/extensions/original_ip_detection/xff/xff_test.cc diff --git a/api/BUILD b/api/BUILD index a824d4500c40..a5df18fecb63 100644 --- a/api/BUILD +++ b/api/BUILD @@ -244,7 +244,9 @@ proto_library( "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", + "//envoy/extensions/original_ip_detection/common/v3:pkg", "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", + "//envoy/extensions/original_ip_detection/xff/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/resource_monitors/fixed_heap/v3:pkg", "//envoy/extensions/resource_monitors/injected_resource/v3:pkg", diff --git a/api/envoy/extensions/original_ip_detection/common/v3/BUILD b/api/envoy/extensions/original_ip_detection/common/v3/BUILD new file mode 100644 index 000000000000..9a76b7e148e0 --- /dev/null +++ b/api/envoy/extensions/original_ip_detection/common/v3/BUILD @@ -0,0 +1,12 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/type/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto b/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto new file mode 100644 index 000000000000..67a7feff2a3a --- /dev/null +++ b/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package envoy.extensions.original_ip_detection.common.v3; + +import "envoy/type/v3/http_status.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.common.v3"; +option java_outer_classname = "OriginalIpDetectionProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Common original IP detection types] +message OriginalIPDetectionCommonConfig { + // Is the detected address trusted (e.g.: can it be used to determine if this is an internal + // request). + bool allow_trusted_address_checks = 1; + + // If true, requests for which either the configured header is missing or parsing an IP from its + // value fails will be rejected. + bool reject_request_if_detection_fails = 2; + + // If reject_request_if_detection_fails is set, this Sets the HTTP status that is returned to the client + // when detection fails. The default status is HTTP 403 Forbidden. + type.v3.HttpStatus status_on_error = 3; +} diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD b/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD index 9a76b7e148e0..5e7ea3961cc3 100644 --- a/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD @@ -6,7 +6,7 @@ licenses(["notice"]) # Apache 2 api_proto_package( deps = [ - "//envoy/type/v3:pkg", + "//envoy/extensions/original_ip_detection/common/v3:pkg", "@com_github_cncf_udpa//udpa/annotations:pkg", ], ) diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index c5481362674d..3ae45525bfdb 100644 --- a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package envoy.extensions.original_ip_detection.custom_header.v3; -import "envoy/type/v3/http_status.proto"; +import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; @@ -26,15 +26,6 @@ message CustomHeaderConfig { // The name for the header containing the original downstream remote address, if present. string header_name = 1; - // Is the detected address trusted (e.g.: can it be used to determine if this is an internal - // request). - bool allow_trusted_address_checks = 2; - - // If true, requests for which either the configured header is missing or parsing an IP from its - // value fails will be rejected. - bool reject_request_if_detection_fails = 3; - - // If reject_request_if_detection_fails is set, this Sets the HTTP status that is returned to the client - // when detection fails. The default status is HTTP 403 Forbidden. - type.v3.HttpStatus status_on_error = 4; + // Common configuration across detection extensions. + common.v3.OriginalIPDetectionCommonConfig common_config = 2; } diff --git a/api/envoy/extensions/original_ip_detection/xff/v3/BUILD b/api/envoy/extensions/original_ip_detection/xff/v3/BUILD new file mode 100644 index 000000000000..5e7ea3961cc3 --- /dev/null +++ b/api/envoy/extensions/original_ip_detection/xff/v3/BUILD @@ -0,0 +1,12 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/extensions/original_ip_detection/common/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto new file mode 100644 index 000000000000..a6511f7c86b9 --- /dev/null +++ b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package envoy.extensions.original_ip_detection.xff.v3; + +import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.xff.v3"; +option java_outer_classname = "XffProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: XFF original IP detection extension] +// +// This extension allows for the original dowstream remote IP to be detected +// by reading the :ref:`config_http_conn_man_headers_x-forwarded-for` header. +// +// If no other extension is configured or detection fails for the configured +// extension, Envoy will fallback to using this extension. +// +// [#extension: envoy.original_ip_detection.xff] +message XffConfig { + // The number of additional ingress proxy hops from the right side of the + // :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header to trust when + // determining the origin client's IP address. The default is zero if this option + // is not specified. See the documentation for + // :ref:`config_http_conn_man_headers_x-forwarded-for` for more information. + uint32 xff_num_trusted_hops = 1; + + // Common configuration across detection extensions. + common.v3.OriginalIPDetectionCommonConfig common_config = 2; +} diff --git a/api/versioning/BUILD b/api/versioning/BUILD index f5f10b549a1f..3ee1a045ad85 100644 --- a/api/versioning/BUILD +++ b/api/versioning/BUILD @@ -127,7 +127,9 @@ proto_library( "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", + "//envoy/extensions/original_ip_detection/common/v3:pkg", "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", + "//envoy/extensions/original_ip_detection/xff/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/resource_monitors/fixed_heap/v3:pkg", "//envoy/extensions/resource_monitors/injected_resource/v3:pkg", diff --git a/generated_api_shadow/BUILD b/generated_api_shadow/BUILD index a824d4500c40..a5df18fecb63 100644 --- a/generated_api_shadow/BUILD +++ b/generated_api_shadow/BUILD @@ -244,7 +244,9 @@ proto_library( "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", + "//envoy/extensions/original_ip_detection/common/v3:pkg", "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", + "//envoy/extensions/original_ip_detection/xff/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/resource_monitors/fixed_heap/v3:pkg", "//envoy/extensions/resource_monitors/injected_resource/v3:pkg", diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/BUILD b/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/BUILD new file mode 100644 index 000000000000..9a76b7e148e0 --- /dev/null +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/BUILD @@ -0,0 +1,12 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/type/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto new file mode 100644 index 000000000000..67a7feff2a3a --- /dev/null +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package envoy.extensions.original_ip_detection.common.v3; + +import "envoy/type/v3/http_status.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.common.v3"; +option java_outer_classname = "OriginalIpDetectionProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Common original IP detection types] +message OriginalIPDetectionCommonConfig { + // Is the detected address trusted (e.g.: can it be used to determine if this is an internal + // request). + bool allow_trusted_address_checks = 1; + + // If true, requests for which either the configured header is missing or parsing an IP from its + // value fails will be rejected. + bool reject_request_if_detection_fails = 2; + + // If reject_request_if_detection_fails is set, this Sets the HTTP status that is returned to the client + // when detection fails. The default status is HTTP 403 Forbidden. + type.v3.HttpStatus status_on_error = 3; +} diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD index 9a76b7e148e0..5e7ea3961cc3 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD @@ -6,7 +6,7 @@ licenses(["notice"]) # Apache 2 api_proto_package( deps = [ - "//envoy/type/v3:pkg", + "//envoy/extensions/original_ip_detection/common/v3:pkg", "@com_github_cncf_udpa//udpa/annotations:pkg", ], ) diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index c5481362674d..3ae45525bfdb 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package envoy.extensions.original_ip_detection.custom_header.v3; -import "envoy/type/v3/http_status.proto"; +import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; @@ -26,15 +26,6 @@ message CustomHeaderConfig { // The name for the header containing the original downstream remote address, if present. string header_name = 1; - // Is the detected address trusted (e.g.: can it be used to determine if this is an internal - // request). - bool allow_trusted_address_checks = 2; - - // If true, requests for which either the configured header is missing or parsing an IP from its - // value fails will be rejected. - bool reject_request_if_detection_fails = 3; - - // If reject_request_if_detection_fails is set, this Sets the HTTP status that is returned to the client - // when detection fails. The default status is HTTP 403 Forbidden. - type.v3.HttpStatus status_on_error = 4; + // Common configuration across detection extensions. + common.v3.OriginalIPDetectionCommonConfig common_config = 2; } diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/BUILD b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/BUILD new file mode 100644 index 000000000000..5e7ea3961cc3 --- /dev/null +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/BUILD @@ -0,0 +1,12 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/extensions/original_ip_detection/common/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto new file mode 100644 index 000000000000..a6511f7c86b9 --- /dev/null +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package envoy.extensions.original_ip_detection.xff.v3; + +import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; + +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.xff.v3"; +option java_outer_classname = "XffProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: XFF original IP detection extension] +// +// This extension allows for the original dowstream remote IP to be detected +// by reading the :ref:`config_http_conn_man_headers_x-forwarded-for` header. +// +// If no other extension is configured or detection fails for the configured +// extension, Envoy will fallback to using this extension. +// +// [#extension: envoy.original_ip_detection.xff] +message XffConfig { + // The number of additional ingress proxy hops from the right side of the + // :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header to trust when + // determining the origin client's IP address. The default is zero if this option + // is not specified. See the documentation for + // :ref:`config_http_conn_man_headers_x-forwarded-for` for more information. + uint32 xff_num_trusted_hops = 1; + + // Common configuration across detection extensions. + common.v3.OriginalIPDetectionCommonConfig common_config = 2; +} diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index e152fc0f0d8a..99d70bf1a990 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -249,6 +249,7 @@ EXTENSIONS = { # "envoy.original_ip_detection.custom_header": "//source/extensions/original_ip_detection/custom_header:config", + "envoy.original_ip_detection.xff": "//source/extensions/original_ip_detection/xff:config", } # These can be changed to ["//visibility:public"], for downstream builds which diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc index d98bc304202c..43c01c3d6280 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -10,7 +10,7 @@ namespace CustomHeader { CustomHeaderIPDetection::CustomHeaderIPDetection( const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& config) : header_name_(config.header_name()), - allow_trusted_address_checks_(config.allow_trusted_address_checks()) {} + allow_trusted_address_checks_(config.common_config().allow_trusted_address_checks()) {} Http::OriginalIPDetectionResult CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { diff --git a/source/extensions/original_ip_detection/xff/BUILD b/source/extensions/original_ip_detection/xff/BUILD new file mode 100644 index 000000000000..126708c9a50e --- /dev/null +++ b/source/extensions/original_ip_detection/xff/BUILD @@ -0,0 +1,35 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_extension", + "envoy_cc_library", + "envoy_extension_package", +) + +licenses(["notice"]) # Apache 2 + +envoy_extension_package() + +envoy_cc_library( + name = "xff_lib", + srcs = ["xff.cc"], + hdrs = ["xff.h"], + deps = [ + "//include/envoy/http:original_ip_detection_interface", + "//source/common/http:utility_lib", + "@envoy_api//envoy/extensions/original_ip_detection/xff/v3:pkg_cc_proto", + ], +) + +envoy_cc_extension( + name = "config", + srcs = ["config.cc"], + hdrs = ["config.h"], + category = "envoy.original_ip_detection", + security_posture = "robust_to_untrusted_downstream", + deps = [ + ":xff_lib", + "//include/envoy/http:original_ip_detection_interface", + "//include/envoy/registry", + "@envoy_api//envoy/extensions/original_ip_detection/xff/v3:pkg_cc_proto", + ], +) diff --git a/source/extensions/original_ip_detection/xff/config.cc b/source/extensions/original_ip_detection/xff/config.cc new file mode 100644 index 000000000000..a3a5d0d437ce --- /dev/null +++ b/source/extensions/original_ip_detection/xff/config.cc @@ -0,0 +1,25 @@ +#include "extensions/original_ip_detection/xff/config.h" +#include "extensions/original_ip_detection/xff/xff.h" + +#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" +#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.validate.h" +#include "envoy/http/original_ip_detection.h" +#include "envoy/registry/registry.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace Xff { + +Http::OriginalIPDetectionSharedPtr +XffIPDetectionFactory::createExtension(const Protobuf::Message& message) const { + return std::make_shared( + dynamic_cast(message)); +} + +REGISTER_FACTORY(XffIPDetectionFactory, Http::OriginalIPDetectionFactory); + +} // namespace Xff +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/original_ip_detection/xff/config.h b/source/extensions/original_ip_detection/xff/config.h new file mode 100644 index 000000000000..1b21c1e91736 --- /dev/null +++ b/source/extensions/original_ip_detection/xff/config.h @@ -0,0 +1,29 @@ +#pragma once + +#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" +#include "envoy/http/original_ip_detection.h" + +#include "common/protobuf/protobuf.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace Xff { + +class XffIPDetectionFactory : public Http::OriginalIPDetectionFactory { +public: + Http::OriginalIPDetectionSharedPtr + createExtension(const Protobuf::Message& message) const override; + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return ProtobufTypes::MessagePtr( + new envoy::extensions::original_ip_detection::xff::v3::XffConfig()); + } + + std::string name() const override { return "envoy.original_ip_detection.xff"; } +}; + +} // namespace Xff +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/original_ip_detection/xff/xff.cc b/source/extensions/original_ip_detection/xff/xff.cc new file mode 100644 index 000000000000..b967b78972fe --- /dev/null +++ b/source/extensions/original_ip_detection/xff/xff.cc @@ -0,0 +1,25 @@ +#include "extensions/original_ip_detection/xff/xff.h" + +#include "common/http/utility.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace Xff { + +XffIPDetection::XffIPDetection( + const envoy::extensions::original_ip_detection::xff::v3::XffConfig& config) + : xff_num_trusted_hops_(config.xff_num_trusted_hops()) {} + +XffIPDetection::XffIPDetection(uint32_t xff_num_trusted_hops) + : xff_num_trusted_hops_(xff_num_trusted_hops) {} + +Http::OriginalIPDetectionResult XffIPDetection::detect(Http::OriginalIPDetectionParams& params) { + auto ret = Http::Utility::getLastAddressFromXFF(params.request_headers, xff_num_trusted_hops_); + return {ret.address_, ret.single_address_}; +} + +} // namespace Xff +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/original_ip_detection/xff/xff.h b/source/extensions/original_ip_detection/xff/xff.h new file mode 100644 index 000000000000..efda8f47ccad --- /dev/null +++ b/source/extensions/original_ip_detection/xff/xff.h @@ -0,0 +1,25 @@ +#pragma once + +#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" +#include "envoy/http/original_ip_detection.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace Xff { + +class XffIPDetection : public Http::OriginalIPDetection { +public: + XffIPDetection(const envoy::extensions::original_ip_detection::xff::v3::XffConfig& config); + XffIPDetection(uint32_t xff_num_trusted_hops); + + Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override; + +private: + const uint32_t xff_num_trusted_hops_; +}; + +} // namespace Xff +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index 7177cf68bb1a..2c1f2a23181d 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -18,7 +18,7 @@ class CustomHeaderTest : public testing::Test { CustomHeaderTest() { envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; config.set_header_name("x-real-ip"); - config.set_allow_trusted_address_checks(true); + config.mutable_common_config()->set_allow_trusted_address_checks(true); custom_header_extension_ = std::make_shared(config); } diff --git a/test/extensions/original_ip_detection/xff/BUILD b/test/extensions/original_ip_detection/xff/BUILD new file mode 100644 index 000000000000..9dd8d6e53cc7 --- /dev/null +++ b/test/extensions/original_ip_detection/xff/BUILD @@ -0,0 +1,37 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_package", +) +load( + "//test/extensions:extensions_build_system.bzl", + "envoy_extension_cc_test", +) + +licenses(["notice"]) # Apache 2 + +envoy_package() + +envoy_extension_cc_test( + name = "xff_detection_test", + extension_name = "envoy.original_ip_detection.xff", + srcs = ["xff_test.cc"], + deps = [ + "//source/common/http:utility_lib", + "//source/extensions/original_ip_detection/xff:xff_lib", + "//test/test_common:utility_lib", + "@envoy_api//envoy/extensions/original_ip_detection/xff/v3:pkg_cc_proto", + ], +) + +envoy_extension_cc_test( + name = "config_test", + extension_name = "envoy.original_ip_detection.xff", + srcs = ["config_test.cc"], + deps = [ + "//include/envoy/registry", + "//source/extensions/original_ip_detection/xff:config", + "//source/extensions/original_ip_detection/xff:xff_lib", + "//test/test_common:utility_lib", + "@envoy_api//envoy/extensions/original_ip_detection/xff/v3:pkg_cc_proto", + ], +) diff --git a/test/extensions/original_ip_detection/xff/config_test.cc b/test/extensions/original_ip_detection/xff/config_test.cc new file mode 100644 index 000000000000..c7afba3c11b1 --- /dev/null +++ b/test/extensions/original_ip_detection/xff/config_test.cc @@ -0,0 +1,29 @@ +#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" +#include "envoy/registry/registry.h" + +#include "extensions/original_ip_detection/xff/config.h" + +#include "test/test_common/utility.h" + +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace Xff { + +TEST(CustomHeaderFactoryTest, Basic) { + auto* factory = Registry::FactoryRegistry::getFactory( + "envoy.original_ip_detection.xff"); + ASSERT_NE(factory, nullptr); + + envoy::extensions::original_ip_detection::xff::v3::XffConfig config; + config.set_xff_num_trusted_hops(1); + + EXPECT_NE(factory->createExtension(config), nullptr); +} + +} // namespace Xff +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/original_ip_detection/xff/xff_test.cc b/test/extensions/original_ip_detection/xff/xff_test.cc new file mode 100644 index 000000000000..9029f869f8ff --- /dev/null +++ b/test/extensions/original_ip_detection/xff/xff_test.cc @@ -0,0 +1,50 @@ +#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" + +#include "extensions/original_ip_detection/xff/xff.h" + +#include "test/test_common/utility.h" + +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace OriginalIPDetection { +namespace Xff { + +class XffTest : public testing::Test { +protected: + XffTest() { + envoy::extensions::original_ip_detection::xff::v3::XffConfig config; + config.set_xff_num_trusted_hops(1); + xff_extension_ = std::make_shared(config); + } + + std::shared_ptr xff_extension_; +}; + +TEST_F(XffTest, Detection) { + // Header missing. + { + Http::TestRequestHeaderMapImpl headers{{"x-other", "abc"}}; + Http::OriginalIPDetectionParams params = {headers, nullptr}; + auto result = xff_extension_->detect(params); + + EXPECT_EQ(nullptr, result.detected_remote_address); + EXPECT_FALSE(result.allow_trusted_address_checks); + } + + // Good request. + { + Http::TestRequestHeaderMapImpl headers{{"x-forwarded-for", "1.2.3.4,2.2.2.2"}}; + Http::OriginalIPDetectionParams params = {headers, nullptr}; + auto result = xff_extension_->detect(params); + + EXPECT_EQ("1.2.3.4:0", result.detected_remote_address->asString()); + EXPECT_FALSE(result.allow_trusted_address_checks); + } +} + +} // namespace Xff +} // namespace OriginalIPDetection +} // namespace Extensions +} // namespace Envoy From 9db5c611be5866186e26a2f80827960033b512e3 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 12 Feb 2021 18:09:00 -0500 Subject: [PATCH 021/100] Use the XFF extension as the default fallback Signed-off-by: Raul Gutierrez Segales --- source/common/http/conn_manager_config.h | 5 +++++ source/common/http/conn_manager_utility.cc | 14 +++++++------- .../filters/network/http_connection_manager/BUILD | 1 + .../network/http_connection_manager/config.cc | 5 +++++ .../network/http_connection_manager/config.h | 2 ++ source/server/admin/admin.h | 1 + test/common/http/conn_manager_impl_fuzz_test.cc | 1 + test/common/http/conn_manager_impl_test_base.h | 1 + test/mocks/http/mocks.h | 1 + 9 files changed, 24 insertions(+), 7 deletions(-) diff --git a/source/common/http/conn_manager_config.h b/source/common/http/conn_manager_config.h index ad0bef9da5c2..6c1e2b3288de 100644 --- a/source/common/http/conn_manager_config.h +++ b/source/common/http/conn_manager_config.h @@ -472,6 +472,11 @@ class ConnectionManagerConfig { * @return OriginalIPDetectionSharedPtr original IP detection extension if available. */ virtual OriginalIPDetectionSharedPtr originalIpDetection() PURE; + + /** + * @return OriginalIPDetectionSharedPtr the IP detection extension (namely XFF). + */ + virtual OriginalIPDetectionSharedPtr defaultIpDetection() PURE; }; } // namespace Http } // namespace Envoy diff --git a/source/common/http/conn_manager_utility.cc b/source/common/http/conn_manager_utility.cc index edaab942ec67..4101c220fc00 100644 --- a/source/common/http/conn_manager_utility.cc +++ b/source/common/http/conn_manager_utility.cc @@ -133,11 +133,10 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest // // If we find one, it will be used as the downstream address for logging. It may or may not be // used for determining internal/external status (see below). + OriginalIPDetectionParams params = {request_headers, + connection.addressProvider().remoteAddress()}; auto original_ip_detection = config.originalIpDetection(); if (original_ip_detection) { - OriginalIPDetectionParams params = {request_headers, - connection.addressProvider().remoteAddress()}; - auto result = original_ip_detection->detect(params); if (result.detected_remote_address) { final_remote_address = result.detected_remote_address; @@ -145,11 +144,12 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest } } - // If there's no extension or it failed to detect, give XFF a try. + // If there's no extension or it failed to detect, try the default extension (XFF). if (!final_remote_address) { - auto ret = Utility::getLastAddressFromXFF(request_headers, xff_num_trusted_hops); - final_remote_address = ret.address_; - allow_trusted_address_checks = ret.single_address_; + auto default_ip_detection = config.defaultIpDetection(); + auto result = default_ip_detection->detect(params); + final_remote_address = result.detected_remote_address; + allow_trusted_address_checks = result.allow_trusted_address_checks; } } diff --git a/source/extensions/filters/network/http_connection_manager/BUILD b/source/extensions/filters/network/http_connection_manager/BUILD index 9c54c1158c4f..5a8ab9b55545 100644 --- a/source/extensions/filters/network/http_connection_manager/BUILD +++ b/source/extensions/filters/network/http_connection_manager/BUILD @@ -54,6 +54,7 @@ envoy_cc_extension( "//source/extensions/filters/http/common:pass_through_filter_lib", "//source/extensions/filters/network:well_known_names", "//source/extensions/filters/network/common:factory_base_lib", + "//source/extensions/original_ip_detection/xff:xff_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", "@envoy_api//envoy/type/tracing/v3:pkg_cc_proto", diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index d0dfc6c24e16..e27343dcd086 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -37,6 +37,7 @@ #include "common/tracing/http_tracer_manager_impl.h" #include "extensions/filters/http/common/pass_through_filter.h" +#include "extensions/original_ip_detection/xff/xff.h" namespace Envoy { namespace Extensions { @@ -298,6 +299,10 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( original_ip_detection_ = factory->createExtension(typed_config); } + // Create the default IP detection extension. + default_ip_detection_ = + std::make_shared(xff_num_trusted_hops_); + // If scoped RDS is enabled, avoid creating a route config provider. Route config providers will // be managed by the scoped routing logic instead. switch (config.route_specifier_case()) { diff --git a/source/extensions/filters/network/http_connection_manager/config.h b/source/extensions/filters/network/http_connection_manager/config.h index 8719d9988c9a..b770fd139446 100644 --- a/source/extensions/filters/network/http_connection_manager/config.h +++ b/source/extensions/filters/network/http_connection_manager/config.h @@ -181,6 +181,7 @@ class HttpConnectionManagerConfig : Logger::Loggable, Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return original_ip_detection_; } + Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return default_ip_detection_; } private: enum class CodecType { HTTP1, HTTP2, HTTP3, AUTO }; @@ -260,6 +261,7 @@ class HttpConnectionManagerConfig : Logger::Loggable, headers_with_underscores_action_; const LocalReply::LocalReplyPtr local_reply_; Http::OriginalIPDetectionSharedPtr original_ip_detection_{nullptr}; + Http::OriginalIPDetectionSharedPtr default_ip_detection_{nullptr}; // Default idle timeout is 5 minutes if nothing is specified in the HCM config. static const uint64_t StreamIdleTimeoutMs = 5 * 60 * 1000; diff --git a/source/server/admin/admin.h b/source/server/admin/admin.h index 0cdb222a427a..227f3b95b3b2 100644 --- a/source/server/admin/admin.h +++ b/source/server/admin/admin.h @@ -181,6 +181,7 @@ class AdminImpl : public Admin, } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return nullptr; }; + Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return nullptr; }; Http::Code request(absl::string_view path_and_query, absl::string_view method, Http::ResponseHeaderMap& response_headers, std::string& body) override; void closeSocket(); diff --git a/test/common/http/conn_manager_impl_fuzz_test.cc b/test/common/http/conn_manager_impl_fuzz_test.cc index 07e1f3ec2754..6acbb23dfd85 100644 --- a/test/common/http/conn_manager_impl_fuzz_test.cc +++ b/test/common/http/conn_manager_impl_fuzz_test.cc @@ -207,6 +207,7 @@ class FuzzConfig : public ConnectionManagerConfig { } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return nullptr; }; + Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return nullptr; }; const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager config_; diff --git a/test/common/http/conn_manager_impl_test_base.h b/test/common/http/conn_manager_impl_test_base.h index fa6de8907bd6..c23c235bcfd2 100644 --- a/test/common/http/conn_manager_impl_test_base.h +++ b/test/common/http/conn_manager_impl_test_base.h @@ -141,6 +141,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return nullptr; }; + Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return nullptr; }; Envoy::Event::SimulatedTimeSystem test_time_; NiceMock route_config_provider_; diff --git a/test/mocks/http/mocks.h b/test/mocks/http/mocks.h index a6d524980afb..d33f1b12eaf0 100644 --- a/test/mocks/http/mocks.h +++ b/test/mocks/http/mocks.h @@ -568,6 +568,7 @@ class MockConnectionManagerConfig : public ConnectionManagerConfig { headersWithUnderscoresAction, (), (const)); MOCK_METHOD(const LocalReply::LocalReply&, localReply, (), (const)); MOCK_METHOD(OriginalIPDetectionSharedPtr, originalIpDetection, ()); + MOCK_METHOD(OriginalIPDetectionSharedPtr, defaultIpDetection, ()); std::unique_ptr internal_address_config_ = std::make_unique(); From 3608dbfeb2d1d1da3c87ab12684b95787f3d5899 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 12 Feb 2021 19:39:39 -0500 Subject: [PATCH 022/100] Add support for rejecting requests when detection fails Signed-off-by: Raul Gutierrez Segales --- .../common/v3/original_ip_detection.proto | 10 +++++++- .../common/v3/original_ip_detection.proto | 10 +++++++- include/envoy/http/original_ip_detection.h | 11 +++++++++ source/common/http/conn_manager_impl.cc | 16 +++++++++++-- source/common/http/conn_manager_utility.cc | 9 +++++-- source/common/http/conn_manager_utility.h | 24 ++++++++++++++----- .../custom_header/custom_header.cc | 20 ++++++++++++---- .../custom_header/custom_header.h | 3 +++ .../original_ip_detection/xff/xff.cc | 2 +- test/common/http/conn_manager_utility_test.cc | 11 +++++---- .../http_connection_manager/config_test.cc | 2 +- .../original_ip_detection_integration_test.cc | 8 +++---- 12 files changed, 99 insertions(+), 27 deletions(-) diff --git a/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto b/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto index 67a7feff2a3a..15c07141a6a3 100644 --- a/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto +++ b/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto @@ -14,6 +14,7 @@ option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Common original IP detection types] +// [#next-free-field: 6] message OriginalIPDetectionCommonConfig { // Is the detected address trusted (e.g.: can it be used to determine if this is an internal // request). @@ -23,7 +24,14 @@ message OriginalIPDetectionCommonConfig { // value fails will be rejected. bool reject_request_if_detection_fails = 2; - // If reject_request_if_detection_fails is set, this Sets the HTTP status that is returned to the client + // If reject_request_if_detection_fails is set, this sets the HTTP status that is returned to the client // when detection fails. The default status is HTTP 403 Forbidden. type.v3.HttpStatus status_on_error = 3; + + // If reject_request_if_detection_fails is set, this sets the HTTP body that is returned to the client + // when detection fails. + string body_on_error = 4; + + // If reject_request_if_detection_fails is set, this sets the a string detailing why this local reply was sent. + string details_on_error = 5; } diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto index 67a7feff2a3a..15c07141a6a3 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto @@ -14,6 +14,7 @@ option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Common original IP detection types] +// [#next-free-field: 6] message OriginalIPDetectionCommonConfig { // Is the detected address trusted (e.g.: can it be used to determine if this is an internal // request). @@ -23,7 +24,14 @@ message OriginalIPDetectionCommonConfig { // value fails will be rejected. bool reject_request_if_detection_fails = 2; - // If reject_request_if_detection_fails is set, this Sets the HTTP status that is returned to the client + // If reject_request_if_detection_fails is set, this sets the HTTP status that is returned to the client // when detection fails. The default status is HTTP 403 Forbidden. type.v3.HttpStatus status_on_error = 3; + + // If reject_request_if_detection_fails is set, this sets the HTTP body that is returned to the client + // when detection fails. + string body_on_error = 4; + + // If reject_request_if_detection_fails is set, this sets the a string detailing why this local reply was sent. + string details_on_error = 5; } diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index 30a6b67eae8e..ee94e0f882f2 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -5,6 +5,7 @@ #include "envoy/common/pure.h" #include "envoy/config/typed_config.h" +#include "envoy/http/codes.h" #include "envoy/http/header_map.h" #include "envoy/network/address.h" @@ -20,12 +21,22 @@ struct OriginalIPDetectionParams { const Network::Address::InstanceConstSharedPtr& downstream_remote_address; }; +// Parameters to be used for sending a local reply when detection fails. +struct OriginalIPRejectRequestOptions { + Code response_code; + std::string body; + std::string details; +}; + struct OriginalIPDetectionResult { // An address that represents the detected address or nullptr if detection failed. Network::Address::InstanceConstSharedPtr detected_remote_address; // Is the detected address trusted (e.g.: can it be used to determine if this is an internal // request). bool allow_trusted_address_checks; + // If set, these parameters will be used to signal that detection failed and the request should + // be rejected. + absl::optional reject_options; }; /** diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc index 494795db36c6..10d164e7041e 100644 --- a/source/common/http/conn_manager_impl.cc +++ b/source/common/http/conn_manager_impl.cc @@ -979,9 +979,21 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(RequestHeaderMapPtr&& he if (!state_.is_internally_created_) { // Only sanitize headers on first pass. // Modify the downstream remote address depending on configuration and headers. - filter_manager_.setDownstreamRemoteAddress(ConnectionManagerUtility::mutateRequestHeaders( + const auto mutate_result = ConnectionManagerUtility::mutateRequestHeaders( *request_headers_, connection_manager_.read_callbacks_->connection(), - connection_manager_.config_, *snapped_route_config_, connection_manager_.local_info_)); + connection_manager_.config_, *snapped_route_config_, connection_manager_.local_info_); + + // IP detection failed, reject the request. + if (mutate_result.reject_request.has_value()) { + const auto& reject_request_params = mutate_result.reject_request.value(); + // TODO(rgs1): bump stat? + sendLocalReply(Grpc::Common::isGrpcRequestHeaders(*request_headers_), + reject_request_params.response_code, reject_request_params.body, nullptr, + absl::nullopt, reject_request_params.details); + return; + } + + filter_manager_.setDownstreamRemoteAddress(mutate_result.final_remote_address); } ASSERT(filter_manager_.streamInfo().downstreamAddressProvider().remoteAddress() != nullptr); diff --git a/source/common/http/conn_manager_utility.cc b/source/common/http/conn_manager_utility.cc index 4101c220fc00..53348e8e6c75 100644 --- a/source/common/http/conn_manager_utility.cc +++ b/source/common/http/conn_manager_utility.cc @@ -63,7 +63,7 @@ ServerConnectionPtr ConnectionManagerUtility::autoCreateCodec( } } -Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequestHeaders( +ConnectionManagerUtility::MutateRequestHeadersResult ConnectionManagerUtility::mutateRequestHeaders( RequestHeaderMap& request_headers, Network::Connection& connection, ConnectionManagerConfig& config, const Router::Config& route_config, const LocalInfo::LocalInfo& local_info) { @@ -138,6 +138,11 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest auto original_ip_detection = config.originalIpDetection(); if (original_ip_detection) { auto result = original_ip_detection->detect(params); + + if (result.reject_options.has_value()) { + return {nullptr, result.reject_options}; + } + if (result.detected_remote_address) { final_remote_address = result.detected_remote_address; allow_trusted_address_checks = result.allow_trusted_address_checks; @@ -228,7 +233,7 @@ Network::Address::InstanceConstSharedPtr ConnectionManagerUtility::mutateRequest mutateXfccRequestHeader(request_headers, connection, config); - return final_remote_address; + return {final_remote_address, absl::nullopt}; } void ConnectionManagerUtility::cleanInternalHeaders( diff --git a/source/common/http/conn_manager_utility.h b/source/common/http/conn_manager_utility.h index b004c0f71f5c..6650974da800 100644 --- a/source/common/http/conn_manager_utility.h +++ b/source/common/http/conn_manager_utility.h @@ -46,6 +46,15 @@ class ConnectionManagerUtility { envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction headers_with_underscores_action); + /* The result after calling mutateRequestHeaders(), containing the final remote address. Note that + * an extension used for detecting the original IP of the request might decide it should be + * rejected if the detection failed. In this case, the reject_request optional will be set. + */ + struct MutateRequestHeadersResult { + Network::Address::InstanceConstSharedPtr final_remote_address; + absl::optional reject_request; + }; + /** * Mutates request headers in various ways. This functionality is broken out because of its * complexity for ease of testing. See the method itself for detailed comments on what @@ -54,13 +63,16 @@ class ConnectionManagerUtility { * Note this function may be called twice on the response path if there are * 100-Continue headers. * - * @return the final trusted remote address. This depends on various settings and the - * existence of the x-forwarded-for header. Again see the method for more details. + * @return MutateRequestHeadersResult containing the final trusted remote address if detected. + * This depends on various settings and the existence of the x-forwarded-for header. + * Note that an extension might also be used. If detection fails, the result may contain + * options for rejecting the request. */ - static Network::Address::InstanceConstSharedPtr - mutateRequestHeaders(RequestHeaderMap& request_headers, Network::Connection& connection, - ConnectionManagerConfig& config, const Router::Config& route_config, - const LocalInfo::LocalInfo& local_info); + static MutateRequestHeadersResult mutateRequestHeaders(RequestHeaderMap& request_headers, + Network::Connection& connection, + ConnectionManagerConfig& config, + const Router::Config& route_config, + const LocalInfo::LocalInfo& local_info); static void mutateResponseHeaders(ResponseHeaderMap& response_headers, const RequestHeaderMap* request_headers, diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc index 43c01c3d6280..e3a0b604d988 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -10,22 +10,34 @@ namespace CustomHeader { CustomHeaderIPDetection::CustomHeaderIPDetection( const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& config) : header_name_(config.header_name()), - allow_trusted_address_checks_(config.common_config().allow_trusted_address_checks()) {} + allow_trusted_address_checks_(config.common_config().allow_trusted_address_checks()) { + + if (config.has_common_config() && config.common_config().reject_request_if_detection_fails()) { + Http::Code reject_code = Http::Code::Forbidden; + + if (config.common_config().has_status_on_error()) { + reject_code = static_cast(config.common_config().status_on_error().code()); + } + + reject_options_ = {reject_code, config.common_config().body_on_error(), + config.common_config().details_on_error()}; + } +} Http::OriginalIPDetectionResult CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { auto hdr = params.request_headers.get(Http::LowerCaseString(header_name_)); if (hdr.empty()) { - return {nullptr, false}; + return {nullptr, false, reject_options_}; } auto header_value = hdr[0]->value().getStringView(); try { return {Network::Utility::parseInternetAddress(std::string(header_value)), - allow_trusted_address_checks_}; + allow_trusted_address_checks_, absl::nullopt}; } catch (const EnvoyException&) { } - return {nullptr, false}; + return {nullptr, false, reject_options_}; } } // namespace CustomHeader diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.h b/source/extensions/original_ip_detection/custom_header/custom_header.h index 90758196de88..e8377eb768db 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.h +++ b/source/extensions/original_ip_detection/custom_header/custom_header.h @@ -1,6 +1,8 @@ #pragma once #include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" + +#include "envoy/http/codes.h" #include "envoy/http/original_ip_detection.h" namespace Envoy { @@ -19,6 +21,7 @@ class CustomHeaderIPDetection : public Http::OriginalIPDetection { private: std::string header_name_; bool allow_trusted_address_checks_; + absl::optional reject_options_{absl::nullopt}; }; } // namespace CustomHeader diff --git a/source/extensions/original_ip_detection/xff/xff.cc b/source/extensions/original_ip_detection/xff/xff.cc index b967b78972fe..820f25514047 100644 --- a/source/extensions/original_ip_detection/xff/xff.cc +++ b/source/extensions/original_ip_detection/xff/xff.cc @@ -16,7 +16,7 @@ XffIPDetection::XffIPDetection(uint32_t xff_num_trusted_hops) Http::OriginalIPDetectionResult XffIPDetection::detect(Http::OriginalIPDetectionParams& params) { auto ret = Http::Utility::getLastAddressFromXFF(params.request_headers, xff_num_trusted_hops_); - return {ret.address_, ret.single_address_}; + return {ret.address_, ret.single_address_, absl::nullopt}; } } // namespace Xff diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index e6e599274d3d..105963e07f2f 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -116,9 +116,9 @@ class ConnectionManagerUtilityTest : public testing::Test { // the request is internal/external, given the importance of these two pieces of data. MutateRequestRet callMutateRequestHeaders(RequestHeaderMap& headers, Protocol) { MutateRequestRet ret; - ret.downstream_address_ = ConnectionManagerUtility::mutateRequestHeaders( - headers, connection_, config_, route_config_, local_info_) - ->asString(); + const auto result = ConnectionManagerUtility::mutateRequestHeaders( + headers, connection_, config_, route_config_, local_info_); + ret.downstream_address_ = result.final_remote_address->asString(); ConnectionManagerUtility::mutateTracingRequestHeader(headers, runtime_, config_, &route_); ret.internal_ = HeaderUtility::isEnvoyInternalRequest(headers); return ret; @@ -1551,10 +1551,11 @@ class CustomHeaderBasedDetection : public Http::OriginalIPDetection { Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override { auto hdr = params.request_headers.get(LowerCaseString(header_name_)); if (hdr.empty()) { - return {nullptr, false}; + return {nullptr, false, absl::nullopt}; } auto header_value = hdr[0]->value().getStringView(); - return {std::make_shared(std::string(header_value)), false}; + return {std::make_shared(std::string(header_value)), false, + absl::nullopt}; } private: diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index e8c56c965764..e0c33c727cf0 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -1762,7 +1762,7 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { class TestIPDetection : public Http::OriginalIPDetection { public: Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams&) override { - return {nullptr, false}; + return {nullptr, false, absl::nullopt}; } }; diff --git a/test/integration/original_ip_detection_integration_test.cc b/test/integration/original_ip_detection_integration_test.cc index a837c28099a9..deb1b0f90e8b 100644 --- a/test/integration/original_ip_detection_integration_test.cc +++ b/test/integration/original_ip_detection_integration_test.cc @@ -19,14 +19,14 @@ class CustomHeaderDetection : public Http::OriginalIPDetection { public: CustomHeaderDetection(const std::string& header_name) : header_name_(header_name) {} - Network::Address::InstanceConstSharedPtr - detect(struct Http::OriginalIPDetectionParams& params) override { + Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override { auto hdr = params.request_headers.get(Http::LowerCaseString(header_name_)); if (hdr.empty()) { - return nullptr; + return {nullptr, false, absl::nullopt}; } auto header_value = hdr[0]->value().getStringView(); - return std::make_shared(std::string(header_value)); + return {std::make_shared(std::string(header_value)), false, + absl::nullopt}; } private: From 11900354dc697eb6cb02e3104fe18de65abe264e Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Sat, 13 Feb 2021 13:45:21 -0500 Subject: [PATCH 023/100] Fixes for CI Signed-off-by: Raul Gutierrez Segales --- .../extensions/original_ip_detection/xff/v3/xff.proto | 2 +- .../extensions/original_ip_detection/xff/v3/xff.proto | 2 +- .../original_ip_detection/custom_header/config.cc | 3 ++- .../custom_header/custom_header.h | 1 - source/extensions/original_ip_detection/xff/BUILD | 2 ++ source/extensions/original_ip_detection/xff/config.cc | 3 ++- test/common/http/BUILD | 1 + test/common/http/conn_manager_utility_test.cc | 10 ++++++++++ .../original_ip_detection/custom_header/BUILD | 4 ++-- .../custom_header/custom_header_test.cc | 4 ++-- test/extensions/original_ip_detection/xff/BUILD | 4 ++-- 11 files changed, 25 insertions(+), 11 deletions(-) diff --git a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto index a6511f7c86b9..e9be13b51c9e 100644 --- a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -15,7 +15,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: XFF original IP detection extension] // -// This extension allows for the original dowstream remote IP to be detected +// This extension allows for the original downstream remote IP to be detected // by reading the :ref:`config_http_conn_man_headers_x-forwarded-for` header. // // If no other extension is configured or detection fails for the configured diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto index a6511f7c86b9..e9be13b51c9e 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -15,7 +15,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: XFF original IP detection extension] // -// This extension allows for the original dowstream remote IP to be detected +// This extension allows for the original downstream remote IP to be detected // by reading the :ref:`config_http_conn_man_headers_x-forwarded-for` header. // // If no other extension is configured or detection fails for the configured diff --git a/source/extensions/original_ip_detection/custom_header/config.cc b/source/extensions/original_ip_detection/custom_header/config.cc index 6dd7192d9f59..6a3d7e22021d 100644 --- a/source/extensions/original_ip_detection/custom_header/config.cc +++ b/source/extensions/original_ip_detection/custom_header/config.cc @@ -1,11 +1,12 @@ #include "extensions/original_ip_detection/custom_header/config.h" -#include "extensions/original_ip_detection/custom_header/custom_header.h" #include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" #include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.validate.h" #include "envoy/http/original_ip_detection.h" #include "envoy/registry/registry.h" +#include "extensions/original_ip_detection/custom_header/custom_header.h" + namespace Envoy { namespace Extensions { namespace OriginalIPDetection { diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.h b/source/extensions/original_ip_detection/custom_header/custom_header.h index e8377eb768db..a8b51832078c 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.h +++ b/source/extensions/original_ip_detection/custom_header/custom_header.h @@ -1,7 +1,6 @@ #pragma once #include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" - #include "envoy/http/codes.h" #include "envoy/http/original_ip_detection.h" diff --git a/source/extensions/original_ip_detection/xff/BUILD b/source/extensions/original_ip_detection/xff/BUILD index 126708c9a50e..86f3626edf5d 100644 --- a/source/extensions/original_ip_detection/xff/BUILD +++ b/source/extensions/original_ip_detection/xff/BUILD @@ -13,6 +13,8 @@ envoy_cc_library( name = "xff_lib", srcs = ["xff.cc"], hdrs = ["xff.h"], + # This extensions is core code. + visibility = ["//visibility:public"], deps = [ "//include/envoy/http:original_ip_detection_interface", "//source/common/http:utility_lib", diff --git a/source/extensions/original_ip_detection/xff/config.cc b/source/extensions/original_ip_detection/xff/config.cc index a3a5d0d437ce..9b0f77a2ae9a 100644 --- a/source/extensions/original_ip_detection/xff/config.cc +++ b/source/extensions/original_ip_detection/xff/config.cc @@ -1,11 +1,12 @@ #include "extensions/original_ip_detection/xff/config.h" -#include "extensions/original_ip_detection/xff/xff.h" #include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" #include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.validate.h" #include "envoy/http/original_ip_detection.h" #include "envoy/registry/registry.h" +#include "extensions/original_ip_detection/xff/xff.h" + namespace Envoy { namespace Extensions { namespace OriginalIPDetection { diff --git a/test/common/http/BUILD b/test/common/http/BUILD index 36d60dcddfb8..e583dfb97e52 100644 --- a/test/common/http/BUILD +++ b/test/common/http/BUILD @@ -245,6 +245,7 @@ envoy_cc_test( "//source/common/network:address_lib", "//source/common/network:utility_lib", "//source/common/runtime:runtime_lib", + "//source/extensions/original_ip_detection/xff:xff_lib", "//test/mocks/http:http_mocks", "//test/mocks/local_info:local_info_mocks", "//test/mocks/network:network_mocks", diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index 105963e07f2f..65c2ec6d197f 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -13,6 +13,8 @@ #include "common/network/utility.h" #include "common/runtime/runtime_impl.h" +#include "extensions/original_ip_detection/xff/xff.h" + #include "test/mocks/http/mocks.h" #include "test/mocks/local_info/mocks.h" #include "test/mocks/network/mocks.h" @@ -85,6 +87,8 @@ class ConnectionManagerUtilityTest : public testing::Test { public: ConnectionManagerUtilityTest() : request_id_extension_(std::make_shared>(random_)), + default_detection_( + std::make_shared(0)), local_reply_(LocalReply::Factory::createDefault()) { ON_CALL(config_, userAgent()).WillByDefault(ReturnRef(user_agent_)); @@ -100,6 +104,7 @@ class ConnectionManagerUtilityTest : public testing::Test { ON_CALL(config_, via()).WillByDefault(ReturnRef(via_)); ON_CALL(config_, requestIDExtension()).WillByDefault(Return(request_id_extension_)); + ON_CALL(config_, defaultIpDetection()).WillByDefault(Return(default_detection_)); } struct MutateRequestRet { @@ -127,6 +132,7 @@ class ConnectionManagerUtilityTest : public testing::Test { NiceMock connection_; NiceMock random_; std::shared_ptr> request_id_extension_; + std::shared_ptr default_detection_; NiceMock config_; NiceMock route_config_; NiceMock route_; @@ -314,6 +320,10 @@ TEST_F(ConnectionManagerUtilityTest, UseRemoteAddressWithXFFTrustedHops) { // Verify that xff_num_trusted_hops works when not using remote address. TEST_F(ConnectionManagerUtilityTest, UseXFFTrustedHopsWithoutRemoteAddress) { + // Reconfigure XFF detecton. + default_detection_ = std::make_shared(1); + ON_CALL(config_, defaultIpDetection()).WillByDefault(Return(default_detection_)); + connection_.stream_info_.downstream_address_provider_->setRemoteAddress( std::make_shared("127.0.0.1")); ON_CALL(config_, useRemoteAddress()).WillByDefault(Return(false)); diff --git a/test/extensions/original_ip_detection/custom_header/BUILD b/test/extensions/original_ip_detection/custom_header/BUILD index 56b7d1134fde..7cad806dbe62 100644 --- a/test/extensions/original_ip_detection/custom_header/BUILD +++ b/test/extensions/original_ip_detection/custom_header/BUILD @@ -13,8 +13,8 @@ envoy_package() envoy_extension_cc_test( name = "custom_header_detection_test", - extension_name = "envoy.original_ip_detection.custom_header", srcs = ["custom_header_test.cc"], + extension_name = "envoy.original_ip_detection.custom_header", deps = [ "//source/common/network:utility_lib", "//source/extensions/original_ip_detection/custom_header:custom_header_lib", @@ -25,8 +25,8 @@ envoy_extension_cc_test( envoy_extension_cc_test( name = "config_test", - extension_name = "envoy.original_ip_detection.custom_header", srcs = ["config_test.cc"], + extension_name = "envoy.original_ip_detection.custom_header", deps = [ "//include/envoy/registry", "//source/extensions/original_ip_detection/custom_header:config", diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index 2c1f2a23181d..008b24fe4b6c 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -1,9 +1,9 @@ #include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" -#include "extensions/original_ip_detection/custom_header/custom_header.h" - #include "common/network/utility.h" +#include "extensions/original_ip_detection/custom_header/custom_header.h" + #include "test/test_common/utility.h" #include "gtest/gtest.h" diff --git a/test/extensions/original_ip_detection/xff/BUILD b/test/extensions/original_ip_detection/xff/BUILD index 9dd8d6e53cc7..cbca6ea4d968 100644 --- a/test/extensions/original_ip_detection/xff/BUILD +++ b/test/extensions/original_ip_detection/xff/BUILD @@ -13,8 +13,8 @@ envoy_package() envoy_extension_cc_test( name = "xff_detection_test", - extension_name = "envoy.original_ip_detection.xff", srcs = ["xff_test.cc"], + extension_name = "envoy.original_ip_detection.xff", deps = [ "//source/common/http:utility_lib", "//source/extensions/original_ip_detection/xff:xff_lib", @@ -25,8 +25,8 @@ envoy_extension_cc_test( envoy_extension_cc_test( name = "config_test", - extension_name = "envoy.original_ip_detection.xff", srcs = ["config_test.cc"], + extension_name = "envoy.original_ip_detection.xff", deps = [ "//include/envoy/registry", "//source/extensions/original_ip_detection/xff:config", From 970b42b631efc0569b19aaebfeac71536bd5327e Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Sat, 13 Feb 2021 17:06:34 -0500 Subject: [PATCH 024/100] Fix docs Signed-off-by: Raul Gutierrez Segales --- .../common/v3/original_ip_detection.proto | 5 +++-- .../custom_header/v3/custom_header.proto | 6 ++---- .../extensions/original_ip_detection/xff/v3/xff.proto | 4 +--- docs/root/api-v3/config/config.rst | 1 + .../original_ip_detection/original_ip_detection.rst | 8 ++++++++ .../common/v3/original_ip_detection.proto | 5 +++-- .../custom_header/v3/custom_header.proto | 6 ++---- .../extensions/original_ip_detection/xff/v3/xff.proto | 4 +--- 8 files changed, 21 insertions(+), 18 deletions(-) create mode 100644 docs/root/api-v3/config/original_ip_detection/original_ip_detection.rst diff --git a/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto b/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto index 15c07141a6a3..6d31c78db943 100644 --- a/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto +++ b/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto @@ -5,8 +5,6 @@ package envoy.extensions.original_ip_detection.common.v3; import "envoy/type/v3/http_status.proto"; import "udpa/annotations/status.proto"; -import "udpa/annotations/versioning.proto"; -import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.common.v3"; option java_outer_classname = "OriginalIpDetectionProto"; @@ -14,6 +12,9 @@ option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Common original IP detection types] + +// Common configuration for IP detection extensions. +// // [#next-free-field: 6] message OriginalIPDetectionCommonConfig { // Is the detected address trusted (e.g.: can it be used to determine if this is an internal diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index 3ae45525bfdb..1f7dde92cd52 100644 --- a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -5,8 +5,6 @@ package envoy.extensions.original_ip_detection.custom_header.v3; import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; import "udpa/annotations/status.proto"; -import "udpa/annotations/versioning.proto"; -import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.custom_header.v3"; option java_outer_classname = "CustomHeaderProto"; @@ -14,8 +12,8 @@ option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Custom header original IP detection extension] -// -// This extension allows for the original dowstream remote IP to be detected + +// This extension allows for the original downstream remote IP to be detected // by reading the value for a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such // by all filters. If the detection or parsing of the header value fails, Envoy will fallback diff --git a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto index e9be13b51c9e..0a4ec0364bd7 100644 --- a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -5,8 +5,6 @@ package envoy.extensions.original_ip_detection.xff.v3; import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; import "udpa/annotations/status.proto"; -import "udpa/annotations/versioning.proto"; -import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.xff.v3"; option java_outer_classname = "XffProto"; @@ -14,7 +12,7 @@ option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: XFF original IP detection extension] -// + // This extension allows for the original downstream remote IP to be detected // by reading the :ref:`config_http_conn_man_headers_x-forwarded-for` header. // diff --git a/docs/root/api-v3/config/config.rst b/docs/root/api-v3/config/config.rst index c1240c53af72..072d1fd1b916 100644 --- a/docs/root/api-v3/config/config.rst +++ b/docs/root/api-v3/config/config.rst @@ -25,3 +25,4 @@ Extensions wasm/wasm watchdog/watchdog descriptors/descriptors + original_ip_detection/original_ip_detection diff --git a/docs/root/api-v3/config/original_ip_detection/original_ip_detection.rst b/docs/root/api-v3/config/original_ip_detection/original_ip_detection.rst new file mode 100644 index 000000000000..0bfaa28c804c --- /dev/null +++ b/docs/root/api-v3/config/original_ip_detection/original_ip_detection.rst @@ -0,0 +1,8 @@ +Original IP Detection +===================== + +.. toctree:: + :glob: + :maxdepth: 2 + + ../../extensions/original_ip_detection/*/v3/* diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto index 15c07141a6a3..6d31c78db943 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto @@ -5,8 +5,6 @@ package envoy.extensions.original_ip_detection.common.v3; import "envoy/type/v3/http_status.proto"; import "udpa/annotations/status.proto"; -import "udpa/annotations/versioning.proto"; -import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.common.v3"; option java_outer_classname = "OriginalIpDetectionProto"; @@ -14,6 +12,9 @@ option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Common original IP detection types] + +// Common configuration for IP detection extensions. +// // [#next-free-field: 6] message OriginalIPDetectionCommonConfig { // Is the detected address trusted (e.g.: can it be used to determine if this is an internal diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index 3ae45525bfdb..1f7dde92cd52 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -5,8 +5,6 @@ package envoy.extensions.original_ip_detection.custom_header.v3; import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; import "udpa/annotations/status.proto"; -import "udpa/annotations/versioning.proto"; -import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.custom_header.v3"; option java_outer_classname = "CustomHeaderProto"; @@ -14,8 +12,8 @@ option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Custom header original IP detection extension] -// -// This extension allows for the original dowstream remote IP to be detected + +// This extension allows for the original downstream remote IP to be detected // by reading the value for a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such // by all filters. If the detection or parsing of the header value fails, Envoy will fallback diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto index e9be13b51c9e..0a4ec0364bd7 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -5,8 +5,6 @@ package envoy.extensions.original_ip_detection.xff.v3; import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; import "udpa/annotations/status.proto"; -import "udpa/annotations/versioning.proto"; -import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.xff.v3"; option java_outer_classname = "XffProto"; @@ -14,7 +12,7 @@ option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: XFF original IP detection extension] -// + // This extension allows for the original downstream remote IP to be detected // by reading the :ref:`config_http_conn_man_headers_x-forwarded-for` header. // From 2e5e67f5ab5ed8c0b55cc1981e9b92cbdfcee615 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Sat, 13 Feb 2021 19:56:13 -0500 Subject: [PATCH 025/100] Fix spelling Signed-off-by: Raul Gutierrez Segales --- test/common/http/conn_manager_utility_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index 65c2ec6d197f..7900b98d8335 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -320,7 +320,7 @@ TEST_F(ConnectionManagerUtilityTest, UseRemoteAddressWithXFFTrustedHops) { // Verify that xff_num_trusted_hops works when not using remote address. TEST_F(ConnectionManagerUtilityTest, UseXFFTrustedHopsWithoutRemoteAddress) { - // Reconfigure XFF detecton. + // Reconfigure XFF detection. default_detection_ = std::make_shared(1); ON_CALL(config_, defaultIpDetection()).WillByDefault(Return(default_detection_)); From a23f44f73e171c3fa4a048943ee1c47e7b7eb5d6 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Sun, 14 Feb 2021 11:38:03 -0500 Subject: [PATCH 026/100] Code owners Signed-off-by: Raul Gutierrez Segales --- CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CODEOWNERS b/CODEOWNERS index 8b71656fcb5a..ffaa6e79081f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -166,3 +166,6 @@ extensions/filters/http/oauth2 @rgs1 @derekargueta @snowp /*/extensions/rate_limit_descriptors/expr @kyessenov @lizan # user space socket pair and event /*/extensions/io_socket/user_space @lambdai @antoniovicente +# Original IP detection +/*/extensions/original_ip_detection/custom_header @rgs1 @alyssawilk @antoniovicente +/*/extensions/original_ip_detection/xff @rgs1 @alyssawilk @antoniovicente From 5bd6813a2b7e135daf4e814b5b629350159ff6c6 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Sun, 14 Feb 2021 19:22:36 -0500 Subject: [PATCH 027/100] Fix test Signed-off-by: Raul Gutierrez Segales --- test/common/http/BUILD | 1 + test/common/http/conn_manager_impl_test_base.cc | 1 + test/common/http/conn_manager_impl_test_base.h | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/test/common/http/BUILD b/test/common/http/BUILD index e583dfb97e52..5382579c24c6 100644 --- a/test/common/http/BUILD +++ b/test/common/http/BUILD @@ -218,6 +218,7 @@ envoy_cc_test( "//source/common/http:conn_manager_lib", "//source/common/http:context_lib", "//source/extensions/access_loggers/file:file_access_log_lib", + "//source/extensions/original_ip_detection/xff:xff_lib", "//test/mocks/access_log:access_log_mocks", "//test/mocks/event:event_mocks", "//test/mocks/http:http_mocks", diff --git a/test/common/http/conn_manager_impl_test_base.cc b/test/common/http/conn_manager_impl_test_base.cc index 3407d3c6faed..01f60c85ec49 100644 --- a/test/common/http/conn_manager_impl_test_base.cc +++ b/test/common/http/conn_manager_impl_test_base.cc @@ -21,6 +21,7 @@ HttpConnectionManagerImplTest::HttpConnectionManagerImplTest() listener_stats_({CONN_MAN_LISTENER_STATS(POOL_COUNTER(fake_listener_stats_))}), request_id_extension_(RequestIDExtensionFactory::defaultInstance(random_)), + default_detection_(std::make_shared(0)), local_reply_(LocalReply::Factory::createDefault()) { ON_CALL(route_config_provider_, lastUpdated()) diff --git a/test/common/http/conn_manager_impl_test_base.h b/test/common/http/conn_manager_impl_test_base.h index c23c235bcfd2..b917180e4ca8 100644 --- a/test/common/http/conn_manager_impl_test_base.h +++ b/test/common/http/conn_manager_impl_test_base.h @@ -6,6 +6,7 @@ #include "common/network/address_impl.h" #include "extensions/access_loggers/file/file_access_log_impl.h" +#include "extensions/original_ip_detection/xff/xff.h" #include "test/mocks/access_log/mocks.h" #include "test/mocks/event/mocks.h" @@ -141,7 +142,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return nullptr; }; - Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return nullptr; }; + Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return default_detection_; }; Envoy::Event::SimulatedTimeSystem test_time_; NiceMock route_config_provider_; @@ -207,6 +208,8 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan NiceMock upstream_conn_; // for websocket tests NiceMock conn_pool_; // for websocket tests RequestIDExtensionSharedPtr request_id_extension_; + std::shared_ptr default_detection_; + const LocalReply::LocalReplyPtr local_reply_; // TODO(mattklein123): Not all tests have been converted over to better setup. Convert the rest. From bd00e7fded58853e795b81e718645a8dad4400fd Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Sun, 14 Feb 2021 22:28:50 -0500 Subject: [PATCH 028/100] Fix clang-tidy issue Signed-off-by: Raul Gutierrez Segales --- include/envoy/http/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/include/envoy/http/BUILD b/include/envoy/http/BUILD index 55ebbd5a6e7f..642a48d85556 100644 --- a/include/envoy/http/BUILD +++ b/include/envoy/http/BUILD @@ -145,6 +145,7 @@ envoy_cc_library( name = "original_ip_detection_interface", hdrs = ["original_ip_detection.h"], deps = [ + ":codes_interface", ":header_map_interface", "//include/envoy/config:typed_config_interface", "//include/envoy/network:address_interface", From 178d28729ae09069926d60e0b69338eba431db51 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Mon, 15 Feb 2021 09:27:44 -0500 Subject: [PATCH 029/100] Fix coverage Signed-off-by: Raul Gutierrez Segales --- .../custom_header/config_test.cc | 7 +++++- .../custom_header/custom_header_test.cc | 23 ++++++++++++++++++- .../original_ip_detection/xff/config_test.cc | 6 ++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/test/extensions/original_ip_detection/custom_header/config_test.cc b/test/extensions/original_ip_detection/custom_header/config_test.cc index e1790896459d..6d33dcc96a8a 100644 --- a/test/extensions/original_ip_detection/custom_header/config_test.cc +++ b/test/extensions/original_ip_detection/custom_header/config_test.cc @@ -17,7 +17,12 @@ TEST(CustomHeaderFactoryTest, Basic) { "envoy.original_ip_detection.custom_header"); ASSERT_NE(factory, nullptr); - envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; + auto empty = factory->createEmptyConfigProto(); + EXPECT_NE(empty, nullptr); + + auto config = *dynamic_cast< + envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig*>( + empty.get()); config.set_header_name("x-real-ip"); EXPECT_NE(factory->createExtension(config), nullptr); diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index 008b24fe4b6c..92cd99d1dec0 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -18,7 +18,16 @@ class CustomHeaderTest : public testing::Test { CustomHeaderTest() { envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; config.set_header_name("x-real-ip"); - config.mutable_common_config()->set_allow_trusted_address_checks(true); + + auto* common_config = config.mutable_common_config(); + common_config->set_allow_trusted_address_checks(true); + common_config->set_reject_request_if_detection_fails(true); + common_config->set_body_on_error("detection failed"); + common_config->set_details_on_error("rejecting because detection failed"); + + auto* status_on_error = common_config->mutable_status_on_error(); + status_on_error->set_code(envoy::type::v3::StatusCode::Unauthorized); + custom_header_extension_ = std::make_shared(config); } @@ -34,6 +43,12 @@ TEST_F(CustomHeaderTest, Detection) { EXPECT_EQ(nullptr, result.detected_remote_address); EXPECT_FALSE(result.allow_trusted_address_checks); + EXPECT_TRUE(result.reject_options.has_value()); + + const auto& reject_options = result.reject_options.value(); + EXPECT_EQ(reject_options.response_code, Http::Code::Unauthorized); + EXPECT_EQ(reject_options.body, "detection failed"); + EXPECT_EQ(reject_options.details, "rejecting because detection failed"); } // Bad IP in the header. @@ -44,6 +59,12 @@ TEST_F(CustomHeaderTest, Detection) { EXPECT_EQ(nullptr, result.detected_remote_address); EXPECT_FALSE(result.allow_trusted_address_checks); + EXPECT_TRUE(result.reject_options.has_value()); + + const auto& reject_options = result.reject_options.value(); + EXPECT_EQ(reject_options.response_code, Http::Code::Unauthorized); + EXPECT_EQ(reject_options.body, "detection failed"); + EXPECT_EQ(reject_options.details, "rejecting because detection failed"); } // Good IP. diff --git a/test/extensions/original_ip_detection/xff/config_test.cc b/test/extensions/original_ip_detection/xff/config_test.cc index c7afba3c11b1..c51f330068a4 100644 --- a/test/extensions/original_ip_detection/xff/config_test.cc +++ b/test/extensions/original_ip_detection/xff/config_test.cc @@ -17,7 +17,11 @@ TEST(CustomHeaderFactoryTest, Basic) { "envoy.original_ip_detection.xff"); ASSERT_NE(factory, nullptr); - envoy::extensions::original_ip_detection::xff::v3::XffConfig config; + auto empty = factory->createEmptyConfigProto(); + EXPECT_NE(empty, nullptr); + + auto config = + *dynamic_cast(empty.get()); config.set_xff_num_trusted_hops(1); EXPECT_NE(factory->createExtension(config), nullptr); From 802c379e37dada3d491a87a0668de94987f6aafb Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Mon, 15 Feb 2021 09:33:56 -0500 Subject: [PATCH 030/100] Check that a good detection doesn't set rejection options Signed-off-by: Raul Gutierrez Segales --- .../original_ip_detection/custom_header/custom_header_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index 92cd99d1dec0..c66387fea2d5 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -75,6 +75,7 @@ TEST_F(CustomHeaderTest, Detection) { EXPECT_EQ("1.2.3.4:0", result.detected_remote_address->asString()); EXPECT_TRUE(result.allow_trusted_address_checks); + EXPECT_FALSE(result.reject_options.has_value()); } } From 8f5165b0374403285e8a96cfd0c8ed640e651a51 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 16 Feb 2021 14:10:27 -0500 Subject: [PATCH 031/100] Review comments Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 3 ++- .../v4alpha/http_connection_manager.proto | 3 ++- .../custom_header/v3/custom_header.proto | 7 ++++--- api/envoy/extensions/original_ip_detection/xff/v3/BUILD | 5 +---- .../extensions/original_ip_detection/xff/v3/xff.proto | 5 ----- docs/root/version_history/current.rst | 2 ++ .../v3/http_connection_manager.proto | 3 ++- .../v4alpha/http_connection_manager.proto | 3 ++- .../custom_header/v3/custom_header.proto | 7 ++++--- .../envoy/extensions/original_ip_detection/xff/v3/BUILD | 5 +---- .../extensions/original_ip_detection/xff/v3/xff.proto | 5 ----- 11 files changed, 20 insertions(+), 28 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 63c918085138..6feac837846b 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -584,7 +584,8 @@ message HttpConnectionManager { // The configuration of the original-IP detection extension. // - // If not set, Envoy uses the default remote IP detection mechanism. + // If not set, Envoy uses the default remote IP detection mechanism (:ref:`XFF + // `). // // When the remote address of the downstream connection is not used as // the detection mechanism for the request's original address, Envoy diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index d554cafed9a9..cfdd60f21d08 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -582,7 +582,8 @@ message HttpConnectionManager { // The configuration of the original-IP detection extension. // - // If not set, Envoy uses the default remote IP detection mechanism. + // If not set, Envoy uses the default remote IP detection mechanism (:ref:`XFF + // `). // // When the remote address of the downstream connection is not used as // the detection mechanism for the request's original address, Envoy diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index 1f7dde92cd52..075f2b681698 100644 --- a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -5,6 +5,7 @@ package envoy.extensions.original_ip_detection.custom_header.v3; import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; import "udpa/annotations/status.proto"; +import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.custom_header.v3"; option java_outer_classname = "CustomHeaderProto"; @@ -14,15 +15,15 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Custom header original IP detection extension] // This extension allows for the original downstream remote IP to be detected -// by reading the value for a configured header name. If the value is successfully parsed +// by reading the value from a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such // by all filters. If the detection or parsing of the header value fails, Envoy will fallback // to its default detection extension. // // [#extension: envoy.original_ip_detection.custom_header] message CustomHeaderConfig { - // The name for the header containing the original downstream remote address, if present. - string header_name = 1; + // The header name containing the original downstream remote address, if present. + string header_name = 1 [(validate.rules).string = {min_len: 1}]; // Common configuration across detection extensions. common.v3.OriginalIPDetectionCommonConfig common_config = 2; diff --git a/api/envoy/extensions/original_ip_detection/xff/v3/BUILD b/api/envoy/extensions/original_ip_detection/xff/v3/BUILD index 5e7ea3961cc3..ee92fb652582 100644 --- a/api/envoy/extensions/original_ip_detection/xff/v3/BUILD +++ b/api/envoy/extensions/original_ip_detection/xff/v3/BUILD @@ -5,8 +5,5 @@ load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") licenses(["notice"]) # Apache 2 api_proto_package( - deps = [ - "//envoy/extensions/original_ip_detection/common/v3:pkg", - "@com_github_cncf_udpa//udpa/annotations:pkg", - ], + deps = ["@com_github_cncf_udpa//udpa/annotations:pkg"], ) diff --git a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto index 0a4ec0364bd7..cc9774539bd2 100644 --- a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -2,8 +2,6 @@ syntax = "proto3"; package envoy.extensions.original_ip_detection.xff.v3; -import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; - import "udpa/annotations/status.proto"; option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.xff.v3"; @@ -27,7 +25,4 @@ message XffConfig { // is not specified. See the documentation for // :ref:`config_http_conn_man_headers_x-forwarded-for` for more information. uint32 xff_num_trusted_hops = 1; - - // Common configuration across detection extensions. - common.v3.OriginalIPDetectionCommonConfig common_config = 2; } diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index c9b38ca2a119..c830bcab0f95 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -89,6 +89,8 @@ New Features * grpc_json_transcoder: added :ref:`request_validation_options ` to reject invalid requests early. * grpc_json_transcoder: filter can now be configured on per-route/per-vhost level as well. Leaving empty list of services in the filter configuration disables transcoding on the specific route. * http: added support for :ref:`original IP detection extensions`. + Two initial extensions were added, the :ref:`custom header ` extension and and the default + :ref:`xff ` extension. * http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 dispatching. Crashes while inside the dispatching loop should dump debug information. * http: added support for :ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. * http: change frame flood and abuse checks to the upstream HTTP/2 codec to ON by default. It can be disabled by setting the `envoy.reloadable_features.upstream_http2_flood_checks` runtime key to false. diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 0ead776ec584..97c6a24f6575 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -588,7 +588,8 @@ message HttpConnectionManager { // The configuration of the original-IP detection extension. // - // If not set, Envoy uses the default remote IP detection mechanism. + // If not set, Envoy uses the default remote IP detection mechanism (:ref:`XFF + // `). // // When the remote address of the downstream connection is not used as // the detection mechanism for the request's original address, Envoy diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index d554cafed9a9..cfdd60f21d08 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -582,7 +582,8 @@ message HttpConnectionManager { // The configuration of the original-IP detection extension. // - // If not set, Envoy uses the default remote IP detection mechanism. + // If not set, Envoy uses the default remote IP detection mechanism (:ref:`XFF + // `). // // When the remote address of the downstream connection is not used as // the detection mechanism for the request's original address, Envoy diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index 1f7dde92cd52..075f2b681698 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -5,6 +5,7 @@ package envoy.extensions.original_ip_detection.custom_header.v3; import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; import "udpa/annotations/status.proto"; +import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.custom_header.v3"; option java_outer_classname = "CustomHeaderProto"; @@ -14,15 +15,15 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Custom header original IP detection extension] // This extension allows for the original downstream remote IP to be detected -// by reading the value for a configured header name. If the value is successfully parsed +// by reading the value from a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such // by all filters. If the detection or parsing of the header value fails, Envoy will fallback // to its default detection extension. // // [#extension: envoy.original_ip_detection.custom_header] message CustomHeaderConfig { - // The name for the header containing the original downstream remote address, if present. - string header_name = 1; + // The header name containing the original downstream remote address, if present. + string header_name = 1 [(validate.rules).string = {min_len: 1}]; // Common configuration across detection extensions. common.v3.OriginalIPDetectionCommonConfig common_config = 2; diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/BUILD b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/BUILD index 5e7ea3961cc3..ee92fb652582 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/BUILD +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/BUILD @@ -5,8 +5,5 @@ load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") licenses(["notice"]) # Apache 2 api_proto_package( - deps = [ - "//envoy/extensions/original_ip_detection/common/v3:pkg", - "@com_github_cncf_udpa//udpa/annotations:pkg", - ], + deps = ["@com_github_cncf_udpa//udpa/annotations:pkg"], ) diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto index 0a4ec0364bd7..cc9774539bd2 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -2,8 +2,6 @@ syntax = "proto3"; package envoy.extensions.original_ip_detection.xff.v3; -import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; - import "udpa/annotations/status.proto"; option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.xff.v3"; @@ -27,7 +25,4 @@ message XffConfig { // is not specified. See the documentation for // :ref:`config_http_conn_man_headers_x-forwarded-for` for more information. uint32 xff_num_trusted_hops = 1; - - // Common configuration across detection extensions. - common.v3.OriginalIPDetectionCommonConfig common_config = 2; } From a246e9efe60470fdeadf104ec822658ed688a4a1 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 16 Feb 2021 16:31:55 -0500 Subject: [PATCH 032/100] Add stat for ip detection rejections Signed-off-by: Raul Gutierrez Segales --- .../http/http_conn_man/stats.rst | 1 + source/common/http/conn_manager_config.h | 1 + source/common/http/conn_manager_impl.cc | 2 +- test/common/http/conn_manager_impl_test_2.cc | 31 +++++++++++++++++++ .../common/http/conn_manager_impl_test_base.h | 7 +++-- 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/docs/root/configuration/http/http_conn_man/stats.rst b/docs/root/configuration/http/http_conn_man/stats.rst index c6aa07f284d4..7be24389e544 100644 --- a/docs/root/configuration/http/http_conn_man/stats.rst +++ b/docs/root/configuration/http/http_conn_man/stats.rst @@ -42,6 +42,7 @@ statistics: downstream_rq_http1_total, Counter, Total HTTP/1.1 requests downstream_rq_http2_total, Counter, Total HTTP/2 requests downstream_rq_active, Gauge, Total active requests + downstream_rq_rejected_via_ip_detection, Counter, Total requests rejected because the original IP detection failed downstream_rq_response_before_rq_complete, Counter, Total responses sent before the request was complete downstream_rq_rx_reset, Counter, Total request resets received downstream_rq_tx_reset, Counter, Total request resets sent diff --git a/source/common/http/conn_manager_config.h b/source/common/http/conn_manager_config.h index 6c1e2b3288de..9d809cf68a61 100644 --- a/source/common/http/conn_manager_config.h +++ b/source/common/http/conn_manager_config.h @@ -56,6 +56,7 @@ namespace Http { COUNTER(downstream_rq_idle_timeout) \ COUNTER(downstream_rq_non_relative_path) \ COUNTER(downstream_rq_overload_close) \ + COUNTER(downstream_rq_rejected_via_ip_detection) \ COUNTER(downstream_rq_response_before_rq_complete) \ COUNTER(downstream_rq_rx_reset) \ COUNTER(downstream_rq_timeout) \ diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc index 10d164e7041e..fde342f6f574 100644 --- a/source/common/http/conn_manager_impl.cc +++ b/source/common/http/conn_manager_impl.cc @@ -986,7 +986,7 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(RequestHeaderMapPtr&& he // IP detection failed, reject the request. if (mutate_result.reject_request.has_value()) { const auto& reject_request_params = mutate_result.reject_request.value(); - // TODO(rgs1): bump stat? + connection_manager_.stats_.named_.downstream_rq_rejected_via_ip_detection_.inc(); sendLocalReply(Grpc::Common::isGrpcRequestHeaders(*request_headers_), reject_request_params.response_code, reject_request_params.body, nullptr, absl::nullopt, reject_request_params.details); diff --git a/test/common/http/conn_manager_impl_test_2.cc b/test/common/http/conn_manager_impl_test_2.cc index b7dfd0298ab9..8e6ae982f0ef 100644 --- a/test/common/http/conn_manager_impl_test_2.cc +++ b/test/common/http/conn_manager_impl_test_2.cc @@ -2987,5 +2987,36 @@ TEST_F(HttpConnectionManagerImplDeathTest, InvalidConnectionManagerConfig) { filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); } +class RejectDetection : public Http::OriginalIPDetection { +public: + RejectDetection() {} + + Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams&) override { + OriginalIPRejectRequestOptions reject_options = {Http::Code::Forbidden, "ip detection failed", + "ip detection failed"}; + return {nullptr, false, reject_options}; + } +}; + +TEST_F(HttpConnectionManagerImplTest, RequestRejectedViaIPDetection) { + use_remote_address_ = false; + ip_detection_extension_ = std::make_shared(); + + setup(false, ""); + + // 403 direct response when IP detection fails. + EXPECT_CALL(response_encoder_, encodeHeaders(_, false)) + .WillOnce(Invoke([](const ResponseHeaderMap& headers, bool) -> void { + EXPECT_EQ("403", headers.getStatusValue()); + })); + std::string response_body; + EXPECT_CALL(response_encoder_, encodeData(_, true)).WillOnce(AddBufferToString(&response_body)); + + startRequest(); + + EXPECT_EQ("ip detection failed", response_body); + EXPECT_EQ(1U, stats_.named_.downstream_rq_rejected_via_ip_detection_.value()); +} + } // namespace Http } // namespace Envoy diff --git a/test/common/http/conn_manager_impl_test_base.h b/test/common/http/conn_manager_impl_test_base.h index b917180e4ca8..412c0d27d5e2 100644 --- a/test/common/http/conn_manager_impl_test_base.h +++ b/test/common/http/conn_manager_impl_test_base.h @@ -141,7 +141,9 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan return headers_with_underscores_action_; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } - Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return nullptr; }; + Http::OriginalIPDetectionSharedPtr originalIpDetection() override { + return ip_detection_extension_; + }; Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return default_detection_; }; Envoy::Event::SimulatedTimeSystem test_time_; @@ -208,7 +210,8 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan NiceMock upstream_conn_; // for websocket tests NiceMock conn_pool_; // for websocket tests RequestIDExtensionSharedPtr request_id_extension_; - std::shared_ptr default_detection_; + Http::OriginalIPDetectionSharedPtr ip_detection_extension_{nullptr}; + Http::OriginalIPDetectionSharedPtr default_detection_; const LocalReply::LocalReplyPtr local_reply_; From e2fc5810f6214ba928fe19bcab0c5b95ad997998 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 16 Feb 2021 16:49:03 -0500 Subject: [PATCH 033/100] Remove possible exception from data path Signed-off-by: Raul Gutierrez Segales --- source/common/network/utility.cc | 13 +++++++++++-- source/common/network/utility.h | 13 ++++++++++++- .../custom_header/custom_header.cc | 8 ++++---- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/source/common/network/utility.cc b/source/common/network/utility.cc index faee96e38521..e46556a1e7c0 100644 --- a/source/common/network/utility.cc +++ b/source/common/network/utility.cc @@ -127,6 +127,16 @@ uint32_t Utility::portFromUdpUrl(const std::string& url) { Address::InstanceConstSharedPtr Utility::parseInternetAddress(const std::string& ip_address, uint16_t port, bool v6only) { + auto addr = parseInternetAddressNoThrow(ip_address, port, v6only); + if (addr) { + return addr; + } + throwWithMalformedIp(ip_address); + NOT_REACHED_GCOVR_EXCL_LINE; +} + +Address::InstanceConstSharedPtr Utility::parseInternetAddressNoThrow(const std::string& ip_address, + uint16_t port, bool v6only) { sockaddr_in sa4; if (inet_pton(AF_INET, ip_address.c_str(), &sa4.sin_addr) == 1) { sa4.sin_family = AF_INET; @@ -140,8 +150,7 @@ Address::InstanceConstSharedPtr Utility::parseInternetAddress(const std::string& sa6.sin6_port = htons(port); return std::make_shared(sa6, v6only); } - throwWithMalformedIp(ip_address); - NOT_REACHED_GCOVR_EXCL_LINE; + return nullptr; } Address::InstanceConstSharedPtr diff --git a/source/common/network/utility.h b/source/common/network/utility.h index 09bb33fb780e..8d0042577afa 100644 --- a/source/common/network/utility.h +++ b/source/common/network/utility.h @@ -131,11 +131,22 @@ class Utility { * @param ip_address string to be parsed as an internet address. * @param port optional port to include in Instance created from ip_address, 0 by default. * @param v6only disable IPv4-IPv6 mapping for IPv6 addresses? - * @return pointer to the Instance, or nullptr if unable to parse the address. + * @return pointer to the Instance. */ static Address::InstanceConstSharedPtr parseInternetAddress(const std::string& ip_address, uint16_t port = 0, bool v6only = true); + /** + * Parse an internet host address (IPv4 or IPv6) and create an Instance from it. The address must + * not include a port number. + * @param ip_address string to be parsed as an internet address. + * @param port optional port to include in Instance created from ip_address, 0 by default. + * @param v6only disable IPv4-IPv6 mapping for IPv6 addresses? + * @return pointer to the Instance, or nullptr if unable to parse the address. + */ + static Address::InstanceConstSharedPtr + parseInternetAddressNoThrow(const std::string& ip_address, uint16_t port = 0, bool v6only = true); + /** * Parse an internet host address (IPv4 or IPv6) AND port, and create an Instance from it. Throws * EnvoyException if unable to parse the address. This is needed when a shared pointer is needed diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc index e3a0b604d988..fa5da9df4bbf 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -30,11 +30,11 @@ CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { if (hdr.empty()) { return {nullptr, false, reject_options_}; } + auto header_value = hdr[0]->value().getStringView(); - try { - return {Network::Utility::parseInternetAddress(std::string(header_value)), - allow_trusted_address_checks_, absl::nullopt}; - } catch (const EnvoyException&) { + auto addr = Network::Utility::parseInternetAddressNoThrow(std::string(header_value)); + if (addr) { + return {addr, allow_trusted_address_checks_, absl::nullopt}; } return {nullptr, false, reject_options_}; From 7476d1a55a3c0947ea97005bfe4c43f997f1423f Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 16 Feb 2021 19:47:41 -0500 Subject: [PATCH 034/100] Matt's review comments * use repeated TypedExtensionConfig for configuring extensions * no need to default to XFF when a list of extensions is provided Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 39 ++++++++++--------- .../v4alpha/http_connection_manager.proto | 39 ++++++++++--------- .../custom_header/v3/custom_header.proto | 3 +- .../original_ip_detection/xff/v3/xff.proto | 3 -- .../other_features/ip_transparency.rst | 12 +++--- docs/root/version_history/current.rst | 4 +- .../v3/http_connection_manager.proto | 39 ++++++++++--------- .../v4alpha/http_connection_manager.proto | 39 ++++++++++--------- .../custom_header/v3/custom_header.proto | 3 +- .../original_ip_detection/xff/v3/xff.proto | 3 -- source/common/http/conn_manager_config.h | 10 ++--- source/common/http/conn_manager_utility.cc | 14 ++----- .../network/http_connection_manager/config.cc | 26 +++++++------ .../network/http_connection_manager/config.h | 9 ++--- source/server/admin/admin.h | 7 +++- .../http/conn_manager_impl_fuzz_test.cc | 7 +++- test/common/http/conn_manager_impl_test_2.cc | 4 +- .../http/conn_manager_impl_test_base.cc | 4 +- .../common/http/conn_manager_impl_test_base.h | 9 ++--- test/common/http/conn_manager_utility_test.cc | 19 +++++---- .../http_connection_manager/config_test.cc | 17 ++++---- .../original_ip_detection_integration_test.cc | 3 +- test/mocks/http/mocks.h | 4 +- 23 files changed, 158 insertions(+), 159 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 6feac837846b..c786fafbaf4b 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -582,32 +582,33 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the original-IP detection extension. + // The configuration for the original-IP detection extensions. // - // If not set, Envoy uses the default remote IP detection mechanism (:ref:`XFF - // `). - // - // When the remote address of the downstream connection is not used as - // the detection mechanism for the request's original address, Envoy - // will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP - // header to detect the address. + // By default, when the :ref:`use_remote_address + // ` + // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header + // and the :ref:`xff_num_trusted_hops + // ` + // configuration option to detect the remote address. // // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` // header doesn't necessarily work for all network configurations. For instance, // if the number of trusted hops isn't consistent for requests flowing into - // Envoy the header cannot be used reliably. For such cases, the following - // option allows for a custom extension to be provided. + // Envoy this mechanism cannot be used reliably. For such cases, the following + // option allows for a list of custom extensions to be provided. // - // If configured, the custom extension will be called along with the - // request headers and the downstream directly connected address when the - // HCM needs to populate the final remote address. The extension will then rely + // If configured, the custom extensions will be called along with the request headers + // and information about the downstream connection, such as direct connected address, + // when the HCM needs to populate the final remote address. Each extension will then rely // on these parameters to decide the value of the request's final remote address. - // If the extension fails to detect the original IP address, the HCM will then fallback - // to the standard detection mechanisms. - // - // An example extension could look up at a configured header name to figure out the - // remote address as detected by a CDN or some other preceding network. - config.core.v3.TypedExtensionConfig original_ip_detection = 43; + // If an extension fails to detect the original IP address and isn't configured to reject + // the request when this happens, the HCM will then try the remaining configured extensions + // until one succeeds or the request is rejected. + // + // Two available extensions are the :ref:`xff + // extension ` and the + // :ref:`custom header extension `. + repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 43; } // The configuration to customize local reply returned by Envoy. diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index cfdd60f21d08..9b6ff27feecc 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -580,32 +580,33 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the original-IP detection extension. + // The configuration for the original-IP detection extensions. // - // If not set, Envoy uses the default remote IP detection mechanism (:ref:`XFF - // `). - // - // When the remote address of the downstream connection is not used as - // the detection mechanism for the request's original address, Envoy - // will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP - // header to detect the address. + // By default, when the :ref:`use_remote_address + // ` + // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header + // and the :ref:`xff_num_trusted_hops + // ` + // configuration option to detect the remote address. // // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` // header doesn't necessarily work for all network configurations. For instance, // if the number of trusted hops isn't consistent for requests flowing into - // Envoy the header cannot be used reliably. For such cases, the following - // option allows for a custom extension to be provided. + // Envoy this mechanism cannot be used reliably. For such cases, the following + // option allows for a list of custom extensions to be provided. // - // If configured, the custom extension will be called along with the - // request headers and the downstream directly connected address when the - // HCM needs to populate the final remote address. The extension will then rely + // If configured, the custom extensions will be called along with the request headers + // and information about the downstream connection, such as direct connected address, + // when the HCM needs to populate the final remote address. Each extension will then rely // on these parameters to decide the value of the request's final remote address. - // If the extension fails to detect the original IP address, the HCM will then fallback - // to the standard detection mechanisms. - // - // An example extension could look up at a configured header name to figure out the - // remote address as detected by a CDN or some other preceding network. - config.core.v4alpha.TypedExtensionConfig original_ip_detection = 43; + // If an extension fails to detect the original IP address and isn't configured to reject + // the request when this happens, the HCM will then try the remaining configured extensions + // until one succeeds or the request is rejected. + // + // Two available extensions are the :ref:`xff + // extension ` and the + // :ref:`custom header extension `. + repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 43; } // The configuration to customize local reply returned by Envoy. diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index 075f2b681698..7fe80600ac7d 100644 --- a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -17,8 +17,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // This extension allows for the original downstream remote IP to be detected // by reading the value from a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such -// by all filters. If the detection or parsing of the header value fails, Envoy will fallback -// to its default detection extension. +// by all filters. // // [#extension: envoy.original_ip_detection.custom_header] message CustomHeaderConfig { diff --git a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto index cc9774539bd2..84e2bcba67b8 100644 --- a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -14,9 +14,6 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // This extension allows for the original downstream remote IP to be detected // by reading the :ref:`config_http_conn_man_headers_x-forwarded-for` header. // -// If no other extension is configured or detection fails for the configured -// extension, Envoy will fallback to using this extension. -// // [#extension: envoy.original_ip_detection.xff] message XffConfig { // The number of additional ingress proxy hops from the right side of the diff --git a/docs/root/intro/arch_overview/other_features/ip_transparency.rst b/docs/root/intro/arch_overview/other_features/ip_transparency.rst index f4239a366aae..010c816b3646 100644 --- a/docs/root/intro/arch_overview/other_features/ip_transparency.rst +++ b/docs/root/intro/arch_overview/other_features/ip_transparency.rst @@ -20,13 +20,13 @@ called the *downstream remote address*, for many reasons. Some examples include: Envoy supports multiple methods for providing the downstream remote address to the upstream host. These techniques vary in complexity and applicability. -Envoy also supports an -:ref:`extension mechanism` +Envoy also supports +:ref:`extensions ` for detecting the original IP address. This might be useful if none of the techniques below is -applicable to your setup. Note that, if configured, an extension will be called ahead of the -attempt to extract the downstream remote address from the -:ref:`x-forwarded-for ` header. If the extension -fails to detect the original IP address, the standard detection mechanisms will then be exercised. +applicable to your setup. Two available extensions are the :ref:`custom header +` +extension and the :ref:`xff ` +extension. HTTP Headers ------------ diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 9371329b7754..2eed0e4245dd 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -87,8 +87,8 @@ New Features * ext_authz: added :ref:`allowed_client_headers_on_success ` to support sending response headers to downstream clients on OK external authorization checks via HTTP. * grpc_json_transcoder: added :ref:`request_validation_options ` to reject invalid requests early. * grpc_json_transcoder: filter can now be configured on per-route/per-vhost level as well. Leaving empty list of services in the filter configuration disables transcoding on the specific route. -* http: added support for :ref:`original IP detection extensions`. - Two initial extensions were added, the :ref:`custom header ` extension and and the default +* http: added support for :ref:`original IP detection extensions`. + Two initial extensions were added, the :ref:`custom header ` extension and the :ref:`xff ` extension. * http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 dispatching. Crashes while inside the dispatching loop should dump debug information. * http: added support for :ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 97c6a24f6575..016d96f3deba 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -586,32 +586,33 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the original-IP detection extension. + // The configuration for the original-IP detection extensions. // - // If not set, Envoy uses the default remote IP detection mechanism (:ref:`XFF - // `). - // - // When the remote address of the downstream connection is not used as - // the detection mechanism for the request's original address, Envoy - // will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP - // header to detect the address. + // By default, when the :ref:`use_remote_address + // ` + // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header + // and the :ref:`xff_num_trusted_hops + // ` + // configuration option to detect the remote address. // // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` // header doesn't necessarily work for all network configurations. For instance, // if the number of trusted hops isn't consistent for requests flowing into - // Envoy the header cannot be used reliably. For such cases, the following - // option allows for a custom extension to be provided. + // Envoy this mechanism cannot be used reliably. For such cases, the following + // option allows for a list of custom extensions to be provided. // - // If configured, the custom extension will be called along with the - // request headers and the downstream directly connected address when the - // HCM needs to populate the final remote address. The extension will then rely + // If configured, the custom extensions will be called along with the request headers + // and information about the downstream connection, such as direct connected address, + // when the HCM needs to populate the final remote address. Each extension will then rely // on these parameters to decide the value of the request's final remote address. - // If the extension fails to detect the original IP address, the HCM will then fallback - // to the standard detection mechanisms. - // - // An example extension could look up at a configured header name to figure out the - // remote address as detected by a CDN or some other preceding network. - config.core.v3.TypedExtensionConfig original_ip_detection = 43; + // If an extension fails to detect the original IP address and isn't configured to reject + // the request when this happens, the HCM will then try the remaining configured extensions + // until one succeeds or the request is rejected. + // + // Two available extensions are the :ref:`xff + // extension ` and the + // :ref:`custom header extension `. + repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 43; google.protobuf.Duration hidden_envoy_deprecated_idle_timeout = 11 [deprecated = true, (envoy.annotations.disallowed_by_default) = true]; diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index cfdd60f21d08..9b6ff27feecc 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -580,32 +580,33 @@ message HttpConnectionManager { // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; - // The configuration of the original-IP detection extension. + // The configuration for the original-IP detection extensions. // - // If not set, Envoy uses the default remote IP detection mechanism (:ref:`XFF - // `). - // - // When the remote address of the downstream connection is not used as - // the detection mechanism for the request's original address, Envoy - // will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP - // header to detect the address. + // By default, when the :ref:`use_remote_address + // ` + // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header + // and the :ref:`xff_num_trusted_hops + // ` + // configuration option to detect the remote address. // // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` // header doesn't necessarily work for all network configurations. For instance, // if the number of trusted hops isn't consistent for requests flowing into - // Envoy the header cannot be used reliably. For such cases, the following - // option allows for a custom extension to be provided. + // Envoy this mechanism cannot be used reliably. For such cases, the following + // option allows for a list of custom extensions to be provided. // - // If configured, the custom extension will be called along with the - // request headers and the downstream directly connected address when the - // HCM needs to populate the final remote address. The extension will then rely + // If configured, the custom extensions will be called along with the request headers + // and information about the downstream connection, such as direct connected address, + // when the HCM needs to populate the final remote address. Each extension will then rely // on these parameters to decide the value of the request's final remote address. - // If the extension fails to detect the original IP address, the HCM will then fallback - // to the standard detection mechanisms. - // - // An example extension could look up at a configured header name to figure out the - // remote address as detected by a CDN or some other preceding network. - config.core.v4alpha.TypedExtensionConfig original_ip_detection = 43; + // If an extension fails to detect the original IP address and isn't configured to reject + // the request when this happens, the HCM will then try the remaining configured extensions + // until one succeeds or the request is rejected. + // + // Two available extensions are the :ref:`xff + // extension ` and the + // :ref:`custom header extension `. + repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 43; } // The configuration to customize local reply returned by Envoy. diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index 075f2b681698..7fe80600ac7d 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -17,8 +17,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // This extension allows for the original downstream remote IP to be detected // by reading the value from a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such -// by all filters. If the detection or parsing of the header value fails, Envoy will fallback -// to its default detection extension. +// by all filters. // // [#extension: envoy.original_ip_detection.custom_header] message CustomHeaderConfig { diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto index cc9774539bd2..84e2bcba67b8 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -14,9 +14,6 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // This extension allows for the original downstream remote IP to be detected // by reading the :ref:`config_http_conn_man_headers_x-forwarded-for` header. // -// If no other extension is configured or detection fails for the configured -// extension, Envoy will fallback to using this extension. -// // [#extension: envoy.original_ip_detection.xff] message XffConfig { // The number of additional ingress proxy hops from the right side of the diff --git a/source/common/http/conn_manager_config.h b/source/common/http/conn_manager_config.h index 9d809cf68a61..80838897f358 100644 --- a/source/common/http/conn_manager_config.h +++ b/source/common/http/conn_manager_config.h @@ -470,14 +470,10 @@ class ConnectionManagerConfig { virtual const LocalReply::LocalReply& localReply() const PURE; /** - * @return OriginalIPDetectionSharedPtr original IP detection extension if available. + * @return vector of OriginalIPDetectionSharedPtr original IP detection extensions. */ - virtual OriginalIPDetectionSharedPtr originalIpDetection() PURE; - - /** - * @return OriginalIPDetectionSharedPtr the IP detection extension (namely XFF). - */ - virtual OriginalIPDetectionSharedPtr defaultIpDetection() PURE; + virtual const std::vector& + originalIpDetectionExtensions() const PURE; }; } // namespace Http } // namespace Envoy diff --git a/source/common/http/conn_manager_utility.cc b/source/common/http/conn_manager_utility.cc index 53348e8e6c75..eb81031f89db 100644 --- a/source/common/http/conn_manager_utility.cc +++ b/source/common/http/conn_manager_utility.cc @@ -135,9 +135,8 @@ ConnectionManagerUtility::MutateRequestHeadersResult ConnectionManagerUtility::m // used for determining internal/external status (see below). OriginalIPDetectionParams params = {request_headers, connection.addressProvider().remoteAddress()}; - auto original_ip_detection = config.originalIpDetection(); - if (original_ip_detection) { - auto result = original_ip_detection->detect(params); + for (const auto& detection_extension : config.originalIpDetectionExtensions()) { + const auto result = detection_extension->detect(params); if (result.reject_options.has_value()) { return {nullptr, result.reject_options}; @@ -146,16 +145,9 @@ ConnectionManagerUtility::MutateRequestHeadersResult ConnectionManagerUtility::m if (result.detected_remote_address) { final_remote_address = result.detected_remote_address; allow_trusted_address_checks = result.allow_trusted_address_checks; + break; } } - - // If there's no extension or it failed to detect, try the default extension (XFF). - if (!final_remote_address) { - auto default_ip_detection = config.defaultIpDetection(); - auto result = default_ip_detection->detect(params); - final_remote_address = result.detected_remote_address; - allow_trusted_address_checks = result.allow_trusted_address_checks; - } } // If the x-forwarded-proto header is not set, set it here, since Envoy uses it for determining diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index e27343dcd086..f56d64ce5e68 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -288,21 +288,23 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( Http::RequestIDExtensionFactory::defaultInstance(context_.api().randomGenerator()); } - // Check if we are provided with an IP detection extension. - if (config.has_original_ip_detection()) { - auto& typed_config = config.original_ip_detection(); - auto* factory = - Envoy::Config::Utility::getFactory(typed_config); - if (!factory) { - throw EnvoyException("Original IP detection extension not found"); + // Check if IP detection extensions were configured. + const auto& ip_detection_extensions = config.original_ip_detection_extensions(); + if (ip_detection_extensions.size() > 0) { + original_ip_detection_extensions_.reserve(ip_detection_extensions.size()); + for (const auto& typed_config : ip_detection_extensions) { + auto* factory = + Envoy::Config::Utility::getFactory(typed_config); + if (!factory) { + throw EnvoyException("Original IP detection extension not found"); + } + original_ip_detection_extensions_.push_back(factory->createExtension(typed_config)); } - original_ip_detection_ = factory->createExtension(typed_config); + } else { + original_ip_detection_extensions_.push_back( + std::make_shared(xff_num_trusted_hops_)); } - // Create the default IP detection extension. - default_ip_detection_ = - std::make_shared(xff_num_trusted_hops_); - // If scoped RDS is enabled, avoid creating a route config provider. Route config providers will // be managed by the scoped routing logic instead. switch (config.route_specifier_case()) { diff --git a/source/extensions/filters/network/http_connection_manager/config.h b/source/extensions/filters/network/http_connection_manager/config.h index b770fd139446..efab882a51c3 100644 --- a/source/extensions/filters/network/http_connection_manager/config.h +++ b/source/extensions/filters/network/http_connection_manager/config.h @@ -178,10 +178,10 @@ class HttpConnectionManagerConfig : Logger::Loggable, } std::chrono::milliseconds delayedCloseTimeout() const override { return delayed_close_timeout_; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } - Http::OriginalIPDetectionSharedPtr originalIpDetection() override { - return original_ip_detection_; + const std::vector& + originalIpDetectionExtensions() const override { + return original_ip_detection_extensions_; } - Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return default_ip_detection_; } private: enum class CodecType { HTTP1, HTTP2, HTTP3, AUTO }; @@ -260,8 +260,7 @@ class HttpConnectionManagerConfig : Logger::Loggable, const envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction headers_with_underscores_action_; const LocalReply::LocalReplyPtr local_reply_; - Http::OriginalIPDetectionSharedPtr original_ip_detection_{nullptr}; - Http::OriginalIPDetectionSharedPtr default_ip_detection_{nullptr}; + std::vector original_ip_detection_extensions_{}; // Default idle timeout is 5 minutes if nothing is specified in the HCM config. static const uint64_t StreamIdleTimeoutMs = 5 * 60 * 1000; diff --git a/source/server/admin/admin.h b/source/server/admin/admin.h index 227f3b95b3b2..1225292aa508 100644 --- a/source/server/admin/admin.h +++ b/source/server/admin/admin.h @@ -180,8 +180,10 @@ class AdminImpl : public Admin, return envoy::config::core::v3::HttpProtocolOptions::ALLOW; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } - Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return nullptr; }; - Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return nullptr; }; + const std::vector& + originalIpDetectionExtensions() const override { + return detection_extensions_; + }; Http::Code request(absl::string_view path_and_query, absl::string_view method, Http::ResponseHeaderMap& response_headers, std::string& body) override; void closeSocket(); @@ -444,6 +446,7 @@ class AdminImpl : public Admin, AdminListenerPtr listener_; const AdminInternalAddressConfig internal_address_config_; const LocalReply::LocalReplyPtr local_reply_; + const std::vector detection_extensions_{}; }; } // namespace Server diff --git a/test/common/http/conn_manager_impl_fuzz_test.cc b/test/common/http/conn_manager_impl_fuzz_test.cc index 6acbb23dfd85..6f4740fa6da3 100644 --- a/test/common/http/conn_manager_impl_fuzz_test.cc +++ b/test/common/http/conn_manager_impl_fuzz_test.cc @@ -206,8 +206,10 @@ class FuzzConfig : public ConnectionManagerConfig { return envoy::config::core::v3::HttpProtocolOptions::ALLOW; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } - Http::OriginalIPDetectionSharedPtr originalIpDetection() override { return nullptr; }; - Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return nullptr; }; + const std::vector& + originalIpDetectionExtensions() const override { + return ip_detection_extensions_; + }; const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager config_; @@ -253,6 +255,7 @@ class FuzzConfig : public ConnectionManagerConfig { Http::DefaultInternalAddressConfig internal_address_config_; bool normalize_path_{true}; LocalReply::LocalReplyPtr local_reply_; + std::vector ip_detection_extensions_{}; }; // Internal representation of stream state. Encapsulates the stream state, mocks diff --git a/test/common/http/conn_manager_impl_test_2.cc b/test/common/http/conn_manager_impl_test_2.cc index 8e6ae982f0ef..b29a05d44e35 100644 --- a/test/common/http/conn_manager_impl_test_2.cc +++ b/test/common/http/conn_manager_impl_test_2.cc @@ -2989,7 +2989,7 @@ TEST_F(HttpConnectionManagerImplDeathTest, InvalidConnectionManagerConfig) { class RejectDetection : public Http::OriginalIPDetection { public: - RejectDetection() {} + RejectDetection() = default; Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams&) override { OriginalIPRejectRequestOptions reject_options = {Http::Code::Forbidden, "ip detection failed", @@ -3000,7 +3000,7 @@ class RejectDetection : public Http::OriginalIPDetection { TEST_F(HttpConnectionManagerImplTest, RequestRejectedViaIPDetection) { use_remote_address_ = false; - ip_detection_extension_ = std::make_shared(); + ip_detection_extensions_.push_back(std::make_shared()); setup(false, ""); diff --git a/test/common/http/conn_manager_impl_test_base.cc b/test/common/http/conn_manager_impl_test_base.cc index 01f60c85ec49..bbad3755fde7 100644 --- a/test/common/http/conn_manager_impl_test_base.cc +++ b/test/common/http/conn_manager_impl_test_base.cc @@ -21,7 +21,6 @@ HttpConnectionManagerImplTest::HttpConnectionManagerImplTest() listener_stats_({CONN_MAN_LISTENER_STATS(POOL_COUNTER(fake_listener_stats_))}), request_id_extension_(RequestIDExtensionFactory::defaultInstance(random_)), - default_detection_(std::make_shared(0)), local_reply_(LocalReply::Factory::createDefault()) { ON_CALL(route_config_provider_, lastUpdated()) @@ -31,6 +30,9 @@ HttpConnectionManagerImplTest::HttpConnectionManagerImplTest() // response_encoder_ is not a NiceMock on purpose. This prevents complaining about this // method only. EXPECT_CALL(response_encoder_, getStream()).Times(AtLeast(0)); + + ip_detection_extensions_.push_back( + std::make_shared(0)); } HttpConnectionManagerImplTest::~HttpConnectionManagerImplTest() { diff --git a/test/common/http/conn_manager_impl_test_base.h b/test/common/http/conn_manager_impl_test_base.h index 412c0d27d5e2..6e8086674335 100644 --- a/test/common/http/conn_manager_impl_test_base.h +++ b/test/common/http/conn_manager_impl_test_base.h @@ -141,10 +141,10 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan return headers_with_underscores_action_; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } - Http::OriginalIPDetectionSharedPtr originalIpDetection() override { - return ip_detection_extension_; + const std::vector& + originalIpDetectionExtensions() const override { + return ip_detection_extensions_; }; - Http::OriginalIPDetectionSharedPtr defaultIpDetection() override { return default_detection_; }; Envoy::Event::SimulatedTimeSystem test_time_; NiceMock route_config_provider_; @@ -210,8 +210,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan NiceMock upstream_conn_; // for websocket tests NiceMock conn_pool_; // for websocket tests RequestIDExtensionSharedPtr request_id_extension_; - Http::OriginalIPDetectionSharedPtr ip_detection_extension_{nullptr}; - Http::OriginalIPDetectionSharedPtr default_detection_; + std::vector ip_detection_extensions_{}; const LocalReply::LocalReplyPtr local_reply_; diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index 7900b98d8335..3958320ecc23 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -87,8 +87,6 @@ class ConnectionManagerUtilityTest : public testing::Test { public: ConnectionManagerUtilityTest() : request_id_extension_(std::make_shared>(random_)), - default_detection_( - std::make_shared(0)), local_reply_(LocalReply::Factory::createDefault()) { ON_CALL(config_, userAgent()).WillByDefault(ReturnRef(user_agent_)); @@ -104,7 +102,11 @@ class ConnectionManagerUtilityTest : public testing::Test { ON_CALL(config_, via()).WillByDefault(ReturnRef(via_)); ON_CALL(config_, requestIDExtension()).WillByDefault(Return(request_id_extension_)); - ON_CALL(config_, defaultIpDetection()).WillByDefault(Return(default_detection_)); + + detection_extensions_.push_back( + std::make_shared(0)); + ON_CALL(config_, originalIpDetectionExtensions()) + .WillByDefault(ReturnRef(detection_extensions_)); } struct MutateRequestRet { @@ -132,7 +134,7 @@ class ConnectionManagerUtilityTest : public testing::Test { NiceMock connection_; NiceMock random_; std::shared_ptr> request_id_extension_; - std::shared_ptr default_detection_; + std::vector detection_extensions_{}; NiceMock config_; NiceMock route_config_; NiceMock route_; @@ -321,8 +323,10 @@ TEST_F(ConnectionManagerUtilityTest, UseRemoteAddressWithXFFTrustedHops) { // Verify that xff_num_trusted_hops works when not using remote address. TEST_F(ConnectionManagerUtilityTest, UseXFFTrustedHopsWithoutRemoteAddress) { // Reconfigure XFF detection. - default_detection_ = std::make_shared(1); - ON_CALL(config_, defaultIpDetection()).WillByDefault(Return(default_detection_)); + detection_extensions_.clear(); + detection_extensions_.push_back( + std::make_shared(1)); + ON_CALL(config_, originalIpDetectionExtensions()).WillByDefault(ReturnRef(detection_extensions_)); connection_.stream_info_.downstream_address_provider_->setRemoteAddress( std::make_shared("127.0.0.1")); @@ -1576,8 +1580,9 @@ class CustomHeaderBasedDetection : public Http::OriginalIPDetection { TEST_F(ConnectionManagerUtilityTest, OriginalIPDetectionExtension) { const std::string header_name = "x-cdn-detected-ip"; auto detection_extension = std::make_shared(header_name); + const std::vector extensions = {detection_extension}; - ON_CALL(config_, originalIpDetection()).WillByDefault(Return(detection_extension)); + ON_CALL(config_, originalIpDetectionExtensions()).WillByDefault(ReturnRef(extensions)); ON_CALL(config_, useRemoteAddress()).WillByDefault(Return(false)); // Header is present. diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index e0c33c727cf0..f65cfdd59446 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -1747,8 +1747,8 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { stat_prefix: ingress_http route_config: name: local_route - original_ip_detection: - name: envoy.ip_detection.UnknownOriginalIPDetectionExtension + original_ip_detection_extensions: + - name: envoy.ip_detection.UnknownOriginalIPDetectionExtension typed_config: "@type": type.googleapis.com/google.protobuf.StringValue http_filters: @@ -1785,8 +1785,8 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { stat_prefix: ingress_http route_config: name: local_route - original_ip_detection: - name: envoy.ip_detection.OriginalIPDetectionExtension + original_ip_detection_extensions: + - name: envoy.ip_detection.OriginalIPDetectionExtension typed_config: "@type": type.googleapis.com/google.protobuf.StringValue http_filters: @@ -1797,9 +1797,12 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - auto original_ip_detection = - dynamic_cast(config.originalIpDetection().get()); - ASSERT_NE(nullptr, original_ip_detection); + + auto original_ip_detection_extensions = config.originalIpDetectionExtensions(); + EXPECT_EQ(1, original_ip_detection_extensions.size()); + + auto* extension = dynamic_cast(original_ip_detection_extensions[0].get()); + EXPECT_NE(nullptr, extension); } TEST_F(HttpConnectionManagerConfigTest, DynamicFilterWarmingNoDefault) { diff --git a/test/integration/original_ip_detection_integration_test.cc b/test/integration/original_ip_detection_integration_test.cc index deb1b0f90e8b..97e03f022c82 100644 --- a/test/integration/original_ip_detection_integration_test.cc +++ b/test/integration/original_ip_detection_integration_test.cc @@ -42,7 +42,6 @@ class HeaderDetectionFactory : public Http::OriginalIPDetectionFactory { return std::make_unique(); } std::string name() const override { return "CustomHeaderDetection"; } - std::string category() const override { return "OriginalIpDetection"; } }; TEST_F(OriginalIPDetectionIntegrationTest, HeaderBasedDetection) { @@ -56,7 +55,7 @@ TEST_F(OriginalIPDetectionIntegrationTest, HeaderBasedDetection) { hcm) -> void { ProtobufWkt::StringValue config; - auto* original_ip_detection = hcm.mutable_original_ip_detection(); + auto* original_ip_detection = hcm.mutable_original_ip_detection_extensions()->Add(); original_ip_detection->set_name("CustomHeaderDetection"); original_ip_detection->mutable_typed_config()->PackFrom(config); diff --git a/test/mocks/http/mocks.h b/test/mocks/http/mocks.h index d33f1b12eaf0..0670dceeb447 100644 --- a/test/mocks/http/mocks.h +++ b/test/mocks/http/mocks.h @@ -567,8 +567,8 @@ class MockConnectionManagerConfig : public ConnectionManagerConfig { MOCK_METHOD(envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction, headersWithUnderscoresAction, (), (const)); MOCK_METHOD(const LocalReply::LocalReply&, localReply, (), (const)); - MOCK_METHOD(OriginalIPDetectionSharedPtr, originalIpDetection, ()); - MOCK_METHOD(OriginalIPDetectionSharedPtr, defaultIpDetection, ()); + MOCK_METHOD(const std::vector&, originalIpDetectionExtensions, + (), (const)); std::unique_ptr internal_address_config_ = std::make_unique(); From 370c16de31d6eab8bb4f6f02c479558541b9dc3a Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 17 Feb 2021 12:08:30 -0500 Subject: [PATCH 035/100] clang tidy Signed-off-by: Raul Gutierrez Segales --- .../filters/network/http_connection_manager/config.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index f56d64ce5e68..b7392af69213 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -290,7 +290,7 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( // Check if IP detection extensions were configured. const auto& ip_detection_extensions = config.original_ip_detection_extensions(); - if (ip_detection_extensions.size() > 0) { + if (!ip_detection_extensions.empty()) { original_ip_detection_extensions_.reserve(ip_detection_extensions.size()); for (const auto& typed_config : ip_detection_extensions) { auto* factory = From 1e1ac79f67bf1073146085e48a4dddaea1fae9f5 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 17 Feb 2021 12:36:23 -0500 Subject: [PATCH 036/100] Drop mostly duplicated extension for test Signed-off-by: Raul Gutierrez Segales --- .../original_ip_detection/custom_header/BUILD | 2 ++ .../custom_header/custom_header.cc | 3 +++ .../custom_header/custom_header.h | 3 ++- test/common/http/BUILD | 1 + test/common/http/conn_manager_utility_test.cc | 23 ++++--------------- 5 files changed, 12 insertions(+), 20 deletions(-) diff --git a/source/extensions/original_ip_detection/custom_header/BUILD b/source/extensions/original_ip_detection/custom_header/BUILD index 9c5ee22d25c0..7fa5e0596311 100644 --- a/source/extensions/original_ip_detection/custom_header/BUILD +++ b/source/extensions/original_ip_detection/custom_header/BUILD @@ -13,6 +13,8 @@ envoy_cc_library( name = "custom_header_lib", srcs = ["custom_header.cc"], hdrs = ["custom_header.h"], + # This extensions is core code. + visibility = ["//visibility:public"], deps = [ "//include/envoy/http:original_ip_detection_interface", "//source/common/network:utility_lib", diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc index fa5da9df4bbf..286759e23abd 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -24,6 +24,9 @@ CustomHeaderIPDetection::CustomHeaderIPDetection( } } +CustomHeaderIPDetection::CustomHeaderIPDetection(const std::string& header_name) + : header_name_(header_name) {} + Http::OriginalIPDetectionResult CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { auto hdr = params.request_headers.get(Http::LowerCaseString(header_name_)); diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.h b/source/extensions/original_ip_detection/custom_header/custom_header.h index a8b51832078c..b68be1ac4dfc 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.h +++ b/source/extensions/original_ip_detection/custom_header/custom_header.h @@ -14,12 +14,13 @@ class CustomHeaderIPDetection : public Http::OriginalIPDetection { CustomHeaderIPDetection( const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& config); + CustomHeaderIPDetection(const std::string& header_name); Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override; private: std::string header_name_; - bool allow_trusted_address_checks_; + bool allow_trusted_address_checks_{false}; absl::optional reject_options_{absl::nullopt}; }; diff --git a/test/common/http/BUILD b/test/common/http/BUILD index 5382579c24c6..ff78eed6db42 100644 --- a/test/common/http/BUILD +++ b/test/common/http/BUILD @@ -246,6 +246,7 @@ envoy_cc_test( "//source/common/network:address_lib", "//source/common/network:utility_lib", "//source/common/runtime:runtime_lib", + "//source/extensions/original_ip_detection/custom_header:custom_header_lib", "//source/extensions/original_ip_detection/xff:xff_lib", "//test/mocks/http:http_mocks", "//test/mocks/local_info:local_info_mocks", diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index 3958320ecc23..17dc41776d3e 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -14,6 +14,7 @@ #include "common/runtime/runtime_impl.h" #include "extensions/original_ip_detection/xff/xff.h" +#include "extensions/original_ip_detection/custom_header/custom_header.h" #include "test/mocks/http/mocks.h" #include "test/mocks/local_info/mocks.h" @@ -1558,28 +1559,12 @@ TEST_F(ConnectionManagerUtilityTest, NoPreserveExternalRequestIdNoEdgeRequest) { } } -class CustomHeaderBasedDetection : public Http::OriginalIPDetection { -public: - CustomHeaderBasedDetection(const std::string& header_name) : header_name_(header_name) {} - - Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override { - auto hdr = params.request_headers.get(LowerCaseString(header_name_)); - if (hdr.empty()) { - return {nullptr, false, absl::nullopt}; - } - auto header_value = hdr[0]->value().getStringView(); - return {std::make_shared(std::string(header_value)), false, - absl::nullopt}; - } - -private: - std::string header_name_; -}; - // Test an extension to detect the original IP for the request. TEST_F(ConnectionManagerUtilityTest, OriginalIPDetectionExtension) { const std::string header_name = "x-cdn-detected-ip"; - auto detection_extension = std::make_shared(header_name); + auto detection_extension = + std::make_shared( + header_name); const std::vector extensions = {detection_extension}; ON_CALL(config_, originalIpDetectionExtensions()).WillByDefault(ReturnRef(extensions)); From e32eef61324247f699a0c74ba2ebcddb55de7684 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 17 Feb 2021 14:48:44 -0500 Subject: [PATCH 037/100] More CI fixes Signed-off-by: Raul Gutierrez Segales --- .../http_connection_manager/v3/http_connection_manager.proto | 1 + .../v4alpha/http_connection_manager.proto | 1 + .../http_connection_manager/v3/http_connection_manager.proto | 1 + .../v4alpha/http_connection_manager.proto | 1 + test/common/http/conn_manager_utility_test.cc | 2 +- 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index b689f0801e53..987ce0a83440 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -609,6 +609,7 @@ message HttpConnectionManager { // Two available extensions are the :ref:`xff // extension ` and the // :ref:`custom header extension `. + // [#extension-category: envoy.original_ip_detection] repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 43; } diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 8d52441006c8..70c8081ae5d9 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -607,6 +607,7 @@ message HttpConnectionManager { // Two available extensions are the :ref:`xff // extension ` and the // :ref:`custom header extension `. + // [#extension-category: envoy.original_ip_detection] repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 43; } diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index ce3b18e1e072..42c161dd4db5 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -613,6 +613,7 @@ message HttpConnectionManager { // Two available extensions are the :ref:`xff // extension ` and the // :ref:`custom header extension `. + // [#extension-category: envoy.original_ip_detection] repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 43; google.protobuf.Duration hidden_envoy_deprecated_idle_timeout = 11 diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 8d52441006c8..70c8081ae5d9 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -607,6 +607,7 @@ message HttpConnectionManager { // Two available extensions are the :ref:`xff // extension ` and the // :ref:`custom header extension `. + // [#extension-category: envoy.original_ip_detection] repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 43; } diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index 17dc41776d3e..958d1437f22a 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -13,8 +13,8 @@ #include "common/network/utility.h" #include "common/runtime/runtime_impl.h" -#include "extensions/original_ip_detection/xff/xff.h" #include "extensions/original_ip_detection/custom_header/custom_header.h" +#include "extensions/original_ip_detection/xff/xff.h" #include "test/mocks/http/mocks.h" #include "test/mocks/local_info/mocks.h" From f0e29ae4c340e5ab54a3ae02a4712ea0c1a64788 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 17 Feb 2021 14:52:33 -0500 Subject: [PATCH 038/100] Fix merge Signed-off-by: Raul Gutierrez Segales --- docs/root/version_history/current.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 9bd1acdafb75..dc5bdf72c62c 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -90,7 +90,6 @@ New Features * http: added support for :ref:`original IP detection extensions`. Two initial extensions were added, the :ref:`custom header ` extension and the :ref:`xff ` extension. -* http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 dispatching. Crashes while inside the dispatching loop should dump debug information. * http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 and HTTP/2 dispatching. Crashes while inside the dispatching loop should dump debug information. * http: added support for :ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. * http: change frame flood and abuse checks to the upstream HTTP/2 codec to ON by default. It can be disabled by setting the `envoy.reloadable_features.upstream_http2_flood_checks` runtime key to false. From 92c0ed4046238edd1ed1718dc8c5c2f3711765ab Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 17 Feb 2021 18:22:53 -0500 Subject: [PATCH 039/100] More cleanup * fix bug in HCM (message needed translation) * drop helper classes for tests, use real extensions directly Signed-off-by: Raul Gutierrez Segales --- .../network/http_connection_manager/config.cc | 7 ++- .../original_ip_detection/custom_header/BUILD | 2 + .../custom_header/config.h | 4 +- .../custom_header/custom_header.cc | 6 ++- .../custom_header/custom_header.h | 4 +- .../original_ip_detection/xff/config.h | 3 +- test/common/http/BUILD | 1 + test/common/http/conn_manager_impl_test_2.cc | 19 +++----- .../common/http/conn_manager_impl_test_base.h | 1 + .../network/http_connection_manager/BUILD | 2 + .../http_connection_manager/config_test.cc | 30 +++---------- test/integration/BUILD | 2 + .../original_ip_detection_integration_test.cc | 44 +++---------------- 13 files changed, 44 insertions(+), 81 deletions(-) diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index b7392af69213..f306fd9e9b6a 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -298,7 +298,12 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( if (!factory) { throw EnvoyException("Original IP detection extension not found"); } - original_ip_detection_extensions_.push_back(factory->createExtension(typed_config)); + + ProtobufTypes::MessagePtr message = factory->createEmptyConfigProto(); + Envoy::Config::Utility::translateOpaqueConfig(typed_config.typed_config(), + ProtobufWkt::Struct::default_instance(), + context_.messageValidationVisitor(), *message); + original_ip_detection_extensions_.push_back(factory->createExtension(*message)); } } else { original_ip_detection_extensions_.push_back( diff --git a/source/extensions/original_ip_detection/custom_header/BUILD b/source/extensions/original_ip_detection/custom_header/BUILD index 7fa5e0596311..3869c672aade 100644 --- a/source/extensions/original_ip_detection/custom_header/BUILD +++ b/source/extensions/original_ip_detection/custom_header/BUILD @@ -26,6 +26,8 @@ envoy_cc_extension( name = "config", srcs = ["config.cc"], hdrs = ["config.h"], + # This extensions is core code. + visibility = ["//visibility:public"], category = "envoy.original_ip_detection", security_posture = "robust_to_untrusted_downstream", deps = [ diff --git a/source/extensions/original_ip_detection/custom_header/config.h b/source/extensions/original_ip_detection/custom_header/config.h index 14e6819a7946..867c39529a0b 100644 --- a/source/extensions/original_ip_detection/custom_header/config.h +++ b/source/extensions/original_ip_detection/custom_header/config.h @@ -16,8 +16,8 @@ class CustomHeaderIPDetectionFactory : public Http::OriginalIPDetectionFactory { createExtension(const Protobuf::Message& message) const override; ProtobufTypes::MessagePtr createEmptyConfigProto() override { - return ProtobufTypes::MessagePtr( - new envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig()); + return std::make_unique< + envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig>(); } std::string name() const override { return "envoy.original_ip_detection.custom_header"; } diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc index 286759e23abd..9ef508f9e19d 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -24,8 +24,10 @@ CustomHeaderIPDetection::CustomHeaderIPDetection( } } -CustomHeaderIPDetection::CustomHeaderIPDetection(const std::string& header_name) - : header_name_(header_name) {} +CustomHeaderIPDetection::CustomHeaderIPDetection( + const std::string& header_name, + absl::optional reject_options) + : header_name_(header_name), reject_options_(reject_options) {} Http::OriginalIPDetectionResult CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.h b/source/extensions/original_ip_detection/custom_header/custom_header.h index b68be1ac4dfc..b2e8e3c82128 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.h +++ b/source/extensions/original_ip_detection/custom_header/custom_header.h @@ -14,7 +14,9 @@ class CustomHeaderIPDetection : public Http::OriginalIPDetection { CustomHeaderIPDetection( const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& config); - CustomHeaderIPDetection(const std::string& header_name); + CustomHeaderIPDetection( + const std::string& header_name, + absl::optional reject_options = absl::nullopt); Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override; diff --git a/source/extensions/original_ip_detection/xff/config.h b/source/extensions/original_ip_detection/xff/config.h index 1b21c1e91736..42c9c50e31fb 100644 --- a/source/extensions/original_ip_detection/xff/config.h +++ b/source/extensions/original_ip_detection/xff/config.h @@ -16,8 +16,7 @@ class XffIPDetectionFactory : public Http::OriginalIPDetectionFactory { createExtension(const Protobuf::Message& message) const override; ProtobufTypes::MessagePtr createEmptyConfigProto() override { - return ProtobufTypes::MessagePtr( - new envoy::extensions::original_ip_detection::xff::v3::XffConfig()); + return std::make_unique(); } std::string name() const override { return "envoy.original_ip_detection.xff"; } diff --git a/test/common/http/BUILD b/test/common/http/BUILD index ff78eed6db42..4635dd74c5af 100644 --- a/test/common/http/BUILD +++ b/test/common/http/BUILD @@ -218,6 +218,7 @@ envoy_cc_test( "//source/common/http:conn_manager_lib", "//source/common/http:context_lib", "//source/extensions/access_loggers/file:file_access_log_lib", + "//source/extensions/original_ip_detection/custom_header:custom_header_lib", "//source/extensions/original_ip_detection/xff:xff_lib", "//test/mocks/access_log:access_log_mocks", "//test/mocks/event:event_mocks", diff --git a/test/common/http/conn_manager_impl_test_2.cc b/test/common/http/conn_manager_impl_test_2.cc index b29a05d44e35..6f9b2d5d22b1 100644 --- a/test/common/http/conn_manager_impl_test_2.cc +++ b/test/common/http/conn_manager_impl_test_2.cc @@ -2987,20 +2987,15 @@ TEST_F(HttpConnectionManagerImplDeathTest, InvalidConnectionManagerConfig) { filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); } -class RejectDetection : public Http::OriginalIPDetection { -public: - RejectDetection() = default; - - Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams&) override { - OriginalIPRejectRequestOptions reject_options = {Http::Code::Forbidden, "ip detection failed", - "ip detection failed"}; - return {nullptr, false, reject_options}; - } -}; - TEST_F(HttpConnectionManagerImplTest, RequestRejectedViaIPDetection) { + OriginalIPRejectRequestOptions reject_options = {Http::Code::Forbidden, "ip detection failed", + "ip detection failed"}; + auto extension = + std::make_shared( + "x-ip", reject_options); + ip_detection_extensions_.push_back(extension); + use_remote_address_ = false; - ip_detection_extensions_.push_back(std::make_shared()); setup(false, ""); diff --git a/test/common/http/conn_manager_impl_test_base.h b/test/common/http/conn_manager_impl_test_base.h index 6e8086674335..487fc45942c1 100644 --- a/test/common/http/conn_manager_impl_test_base.h +++ b/test/common/http/conn_manager_impl_test_base.h @@ -7,6 +7,7 @@ #include "extensions/access_loggers/file/file_access_log_impl.h" #include "extensions/original_ip_detection/xff/xff.h" +#include "extensions/original_ip_detection/custom_header/custom_header.h" #include "test/mocks/access_log/mocks.h" #include "test/mocks/event/mocks.h" diff --git a/test/extensions/filters/network/http_connection_manager/BUILD b/test/extensions/filters/network/http_connection_manager/BUILD index 673c3f11e327..c710b9c1348a 100644 --- a/test/extensions/filters/network/http_connection_manager/BUILD +++ b/test/extensions/filters/network/http_connection_manager/BUILD @@ -31,6 +31,8 @@ envoy_extension_cc_test( "//source/extensions/filters/http/health_check:config", "//source/extensions/filters/http/router:config", "//source/extensions/filters/network/http_connection_manager:config", + "//source/extensions/original_ip_detection/custom_header:config", + "//source/extensions/original_ip_detection/custom_header:custom_header_lib", "//test/integration/filters:encoder_decoder_buffer_filter_lib", "//test/mocks/network:network_mocks", "//test/mocks/server:factory_context_mocks", diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index f65cfdd59446..f3a4ddc2a977 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -14,6 +14,7 @@ #include "common/network/address_impl.h" #include "extensions/filters/network/http_connection_manager/config.h" +#include "extensions/original_ip_detection/custom_header/custom_header.h" #include "test/extensions/filters/network/http_connection_manager/config.pb.h" #include "test/extensions/filters/network/http_connection_manager/config.pb.validate.h" @@ -1759,36 +1760,16 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { "Original IP detection extension not found"); } -class TestIPDetection : public Http::OriginalIPDetection { -public: - Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams&) override { - return {nullptr, false, absl::nullopt}; - } -}; - -class TestIPDetectionFactory : public Http::OriginalIPDetectionFactory { -public: - Http::OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message&) const override { - return std::make_shared(); - } - ProtobufTypes::MessagePtr createEmptyConfigProto() override { - return std::make_unique(); - } - std::string name() const override { return "TestFactory"; } - std::string category() const override { return "OriginalIpDetection"; } -}; - TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { - TestIPDetectionFactory factory; - Registry::InjectFactory ip_detection_register(factory); const std::string yaml_string = R"EOF( stat_prefix: ingress_http route_config: name: local_route original_ip_detection_extensions: - - name: envoy.ip_detection.OriginalIPDetectionExtension + - name: envoy.original_ip_detection.custom_header typed_config: - "@type": type.googleapis.com/google.protobuf.StringValue + "@type": type.googleapis.com/envoy.extensions.original_ip_detection.custom_header.v3.CustomHeaderConfig + header_name: x-ip-header http_filters: - name: envoy.filters.http.router )EOF"; @@ -1801,7 +1782,8 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { auto original_ip_detection_extensions = config.originalIpDetectionExtensions(); EXPECT_EQ(1, original_ip_detection_extensions.size()); - auto* extension = dynamic_cast(original_ip_detection_extensions[0].get()); + auto* extension = dynamic_cast( + original_ip_detection_extensions[0].get()); EXPECT_NE(nullptr, extension); } diff --git a/test/integration/BUILD b/test/integration/BUILD index 6a214ea275dd..e4135356edb3 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -1653,6 +1653,8 @@ envoy_cc_test( ], deps = [ ":http_integration_lib", + "//source/extensions/original_ip_detection/custom_header:config", "//test/test_common:utility_lib", + "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", ], ) diff --git a/test/integration/original_ip_detection_integration_test.cc b/test/integration/original_ip_detection_integration_test.cc index 97e03f022c82..9de88904a704 100644 --- a/test/integration/original_ip_detection_integration_test.cc +++ b/test/integration/original_ip_detection_integration_test.cc @@ -1,3 +1,5 @@ +#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" + #include "test/integration/http_integration.h" #include "test/test_common/registry.h" #include "test/test_common/utility.h" @@ -15,49 +17,17 @@ class OriginalIPDetectionIntegrationTest : public testing::Test, public HttpInte : HttpIntegrationTest(Http::CodecClient::Type::HTTP1, Network::Address::IpVersion::v4) {} }; -class CustomHeaderDetection : public Http::OriginalIPDetection { -public: - CustomHeaderDetection(const std::string& header_name) : header_name_(header_name) {} - - Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override { - auto hdr = params.request_headers.get(Http::LowerCaseString(header_name_)); - if (hdr.empty()) { - return {nullptr, false, absl::nullopt}; - } - auto header_value = hdr[0]->value().getStringView(); - return {std::make_shared(std::string(header_value)), false, - absl::nullopt}; - } - -private: - std::string header_name_; -}; - -class HeaderDetectionFactory : public Http::OriginalIPDetectionFactory { -public: - Http::OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message&) const override { - return std::make_shared("x-cdn-detected-ip"); - } - ProtobufTypes::MessagePtr createEmptyConfigProto() override { - return std::make_unique(); - } - std::string name() const override { return "CustomHeaderDetection"; } -}; - TEST_F(OriginalIPDetectionIntegrationTest, HeaderBasedDetection) { - HeaderDetectionFactory factory; - Registry::InjectFactory header_detection_factory_register( - factory); - useAccessLog("%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%"); config_helper_.addConfigModifier( [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm) -> void { - ProtobufWkt::StringValue config; + envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; + config.set_header_name("x-cdn-detected-ip"); - auto* original_ip_detection = hcm.mutable_original_ip_detection_extensions()->Add(); - original_ip_detection->set_name("CustomHeaderDetection"); - original_ip_detection->mutable_typed_config()->PackFrom(config); + auto* extension = hcm.add_original_ip_detection_extensions(); + extension->set_name("envoy.original_ip_detection.custom_header"); + extension->mutable_typed_config()->PackFrom(config); hcm.mutable_use_remote_address()->set_value(false); }); From ac430bbf2947c4af4b99f3ca3cd425d3ba7f8754 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 17 Feb 2021 21:05:33 -0500 Subject: [PATCH 040/100] Fix format Signed-off-by: Raul Gutierrez Segales --- source/extensions/original_ip_detection/custom_header/BUILD | 4 ++-- test/common/http/conn_manager_impl_test_base.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/extensions/original_ip_detection/custom_header/BUILD b/source/extensions/original_ip_detection/custom_header/BUILD index 3869c672aade..f1f74e6e4b3b 100644 --- a/source/extensions/original_ip_detection/custom_header/BUILD +++ b/source/extensions/original_ip_detection/custom_header/BUILD @@ -26,10 +26,10 @@ envoy_cc_extension( name = "config", srcs = ["config.cc"], hdrs = ["config.h"], - # This extensions is core code. - visibility = ["//visibility:public"], category = "envoy.original_ip_detection", security_posture = "robust_to_untrusted_downstream", + # This extensions is core code. + visibility = ["//visibility:public"], deps = [ ":custom_header_lib", "//include/envoy/http:original_ip_detection_interface", diff --git a/test/common/http/conn_manager_impl_test_base.h b/test/common/http/conn_manager_impl_test_base.h index 487fc45942c1..2245ee785c5a 100644 --- a/test/common/http/conn_manager_impl_test_base.h +++ b/test/common/http/conn_manager_impl_test_base.h @@ -6,8 +6,8 @@ #include "common/network/address_impl.h" #include "extensions/access_loggers/file/file_access_log_impl.h" -#include "extensions/original_ip_detection/xff/xff.h" #include "extensions/original_ip_detection/custom_header/custom_header.h" +#include "extensions/original_ip_detection/xff/xff.h" #include "test/mocks/access_log/mocks.h" #include "test/mocks/event/mocks.h" From 822aa25ea77366a0d5398264500b34f10467cac1 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 24 Feb 2021 09:42:42 -0500 Subject: [PATCH 041/100] Fixes * envoy.original_ip_detection -> envoy.http.... * get rid of common proto message * mark xff_num_trusted_hops as deprecated Signed-off-by: Raul Gutierrez Segales --- api/BUILD | 1 - .../v3/http_connection_manager.proto | 10 ++++- .../v4alpha/http_connection_manager.proto | 13 ++----- .../original_ip_detection/common/v3/BUILD | 12 ------ .../common/v3/original_ip_detection.proto | 38 ------------------- .../custom_header/v3/BUILD | 2 +- .../custom_header/v3/custom_header.proto | 27 +++++++++++-- .../original_ip_detection/xff/v3/xff.proto | 2 +- api/versioning/BUILD | 1 - bazel/envoy_library.bzl | 2 +- generated_api_shadow/BUILD | 2 - .../v3/http_connection_manager.proto | 10 ++++- .../v4alpha/http_connection_manager.proto | 10 ++++- .../original_ip_detection/common/v3/BUILD | 12 ------ .../common/v3/original_ip_detection.proto | 38 ------------------- .../custom_header/v3/BUILD | 2 +- .../custom_header/v3/custom_header.proto | 27 +++++++++++-- .../original_ip_detection/xff/v3/xff.proto | 2 +- include/envoy/http/original_ip_detection.h | 2 +- source/extensions/extensions_build_config.bzl | 4 +- .../original_ip_detection/custom_header/BUILD | 2 +- .../custom_header/config.h | 2 +- .../custom_header/custom_header.cc | 12 +++--- .../original_ip_detection/xff/BUILD | 2 +- .../original_ip_detection/xff/config.h | 2 +- .../http_connection_manager/config_test.cc | 2 +- .../original_ip_detection/custom_header/BUILD | 4 +- .../custom_header/config_test.cc | 2 +- .../custom_header/custom_header_test.cc | 12 +++--- .../original_ip_detection/xff/BUILD | 4 +- .../original_ip_detection/xff/config_test.cc | 2 +- .../original_ip_detection_integration_test.cc | 2 +- 32 files changed, 104 insertions(+), 161 deletions(-) delete mode 100644 api/envoy/extensions/original_ip_detection/common/v3/BUILD delete mode 100644 api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto delete mode 100644 generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/BUILD delete mode 100644 generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto diff --git a/api/BUILD b/api/BUILD index a5df18fecb63..e7fa4e782e9b 100644 --- a/api/BUILD +++ b/api/BUILD @@ -244,7 +244,6 @@ proto_library( "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", - "//envoy/extensions/original_ip_detection/common/v3:pkg", "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", "//envoy/extensions/original_ip_detection/xff/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 987ce0a83440..76493a052ec4 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -431,7 +431,13 @@ message HttpConnectionManager { // determining the origin client's IP address. The default is zero if this option // is not specified. See the documentation for // :ref:`config_http_conn_man_headers_x-forwarded-for` for more information. - uint32 xff_num_trusted_hops = 19; + // + // .. note:: + // This field is deprecated and instead :ref:`original_ip_detection_extensions + // ` + // should be used to configure the :ref:`xff extension ` + // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. + uint32 xff_num_trusted_hops = 19 [deprecated = true]; // Configures what network addresses are considered internal for stats and header sanitation // purposes. If unspecified, only RFC1918 IP addresses will be considered internal. @@ -609,7 +615,7 @@ message HttpConnectionManager { // Two available extensions are the :ref:`xff // extension ` and the // :ref:`custom header extension `. - // [#extension-category: envoy.original_ip_detection] + // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 43; } diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 70c8081ae5d9..87aaf9b52694 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -237,9 +237,9 @@ message HttpConnectionManager { google.protobuf.BoolValue enabled = 3; } - reserved 27, 11; + reserved 27, 11, 19; - reserved "idle_timeout"; + reserved "idle_timeout", "xff_num_trusted_hops"; // Supplies the type of codec that the connection manager should use. CodecType codec_type = 1 [(validate.rules).enum = {defined_only: true}]; @@ -425,13 +425,6 @@ message HttpConnectionManager { google.protobuf.BoolValue use_remote_address = 14 [(udpa.annotations.security).configure_for_untrusted_downstream = true]; - // The number of additional ingress proxy hops from the right side of the - // :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header to trust when - // determining the origin client's IP address. The default is zero if this option - // is not specified. See the documentation for - // :ref:`config_http_conn_man_headers_x-forwarded-for` for more information. - uint32 xff_num_trusted_hops = 19; - // Configures what network addresses are considered internal for stats and header sanitation // purposes. If unspecified, only RFC1918 IP addresses will be considered internal. // See the documentation for :ref:`config_http_conn_man_headers_x-envoy-internal` for more @@ -607,7 +600,7 @@ message HttpConnectionManager { // Two available extensions are the :ref:`xff // extension ` and the // :ref:`custom header extension `. - // [#extension-category: envoy.original_ip_detection] + // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 43; } diff --git a/api/envoy/extensions/original_ip_detection/common/v3/BUILD b/api/envoy/extensions/original_ip_detection/common/v3/BUILD deleted file mode 100644 index 9a76b7e148e0..000000000000 --- a/api/envoy/extensions/original_ip_detection/common/v3/BUILD +++ /dev/null @@ -1,12 +0,0 @@ -# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. - -load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") - -licenses(["notice"]) # Apache 2 - -api_proto_package( - deps = [ - "//envoy/type/v3:pkg", - "@com_github_cncf_udpa//udpa/annotations:pkg", - ], -) diff --git a/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto b/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto deleted file mode 100644 index 6d31c78db943..000000000000 --- a/api/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto +++ /dev/null @@ -1,38 +0,0 @@ -syntax = "proto3"; - -package envoy.extensions.original_ip_detection.common.v3; - -import "envoy/type/v3/http_status.proto"; - -import "udpa/annotations/status.proto"; - -option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.common.v3"; -option java_outer_classname = "OriginalIpDetectionProto"; -option java_multiple_files = true; -option (udpa.annotations.file_status).package_version_status = ACTIVE; - -// [#protodoc-title: Common original IP detection types] - -// Common configuration for IP detection extensions. -// -// [#next-free-field: 6] -message OriginalIPDetectionCommonConfig { - // Is the detected address trusted (e.g.: can it be used to determine if this is an internal - // request). - bool allow_trusted_address_checks = 1; - - // If true, requests for which either the configured header is missing or parsing an IP from its - // value fails will be rejected. - bool reject_request_if_detection_fails = 2; - - // If reject_request_if_detection_fails is set, this sets the HTTP status that is returned to the client - // when detection fails. The default status is HTTP 403 Forbidden. - type.v3.HttpStatus status_on_error = 3; - - // If reject_request_if_detection_fails is set, this sets the HTTP body that is returned to the client - // when detection fails. - string body_on_error = 4; - - // If reject_request_if_detection_fails is set, this sets the a string detailing why this local reply was sent. - string details_on_error = 5; -} diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD b/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD index 5e7ea3961cc3..9a76b7e148e0 100644 --- a/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD @@ -6,7 +6,7 @@ licenses(["notice"]) # Apache 2 api_proto_package( deps = [ - "//envoy/extensions/original_ip_detection/common/v3:pkg", + "//envoy/type/v3:pkg", "@com_github_cncf_udpa//udpa/annotations:pkg", ], ) diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index 7fe80600ac7d..48f5ba385a6d 100644 --- a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package envoy.extensions.original_ip_detection.custom_header.v3; -import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; +import "envoy/type/v3/http_status.proto"; import "udpa/annotations/status.proto"; import "validate/validate.proto"; @@ -19,11 +19,30 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // as an IP, it'll be treated as the effective downstream remote address and seen as such // by all filters. // -// [#extension: envoy.original_ip_detection.custom_header] +// [#extension: envoy.http.original_ip_detection.custom_header] message CustomHeaderConfig { + // Configuration options for rejecting requests when detection fails. + message RejectOptions { + // If reject_request_if_detection_fails is set, this sets the HTTP status that is returned to the client + // when detection fails. The default status is HTTP 403 Forbidden. + type.v3.HttpStatus status_on_error = 1; + + // If reject_request_if_detection_fails is set, this sets the HTTP body that is returned to the client + // when detection fails. + string body_on_error = 2; + + // If reject_request_if_detection_fails is set, this sets the a string detailing why this local reply was sent. + string details_on_error = 3; + } + // The header name containing the original downstream remote address, if present. string header_name = 1 [(validate.rules).string = {min_len: 1}]; - // Common configuration across detection extensions. - common.v3.OriginalIPDetectionCommonConfig common_config = 2; + // Is the detected address trusted (e.g.: can it be used to determine if this is an internal + // request). + bool allow_trusted_address_checks = 2; + + // If set, requests for which either the configured header is missing or parsing an IP from its + // value fails will be rejected with these options. + RejectOptions reject_options = 3; } diff --git a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto index 84e2bcba67b8..c5bd63cf00ab 100644 --- a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -14,7 +14,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // This extension allows for the original downstream remote IP to be detected // by reading the :ref:`config_http_conn_man_headers_x-forwarded-for` header. // -// [#extension: envoy.original_ip_detection.xff] +// [#extension: envoy.http.original_ip_detection.xff] message XffConfig { // The number of additional ingress proxy hops from the right side of the // :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header to trust when diff --git a/api/versioning/BUILD b/api/versioning/BUILD index 3ee1a045ad85..f6824b3e579c 100644 --- a/api/versioning/BUILD +++ b/api/versioning/BUILD @@ -127,7 +127,6 @@ proto_library( "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", - "//envoy/extensions/original_ip_detection/common/v3:pkg", "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", "//envoy/extensions/original_ip_detection/xff/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", diff --git a/bazel/envoy_library.bzl b/bazel/envoy_library.bzl index 5027fb720b24..05967a6ccdb4 100644 --- a/bazel/envoy_library.bzl +++ b/bazel/envoy_library.bzl @@ -82,7 +82,7 @@ EXTENSION_CATEGORIES = [ "envoy.health_checkers", "envoy.internal_redirect_predicates", "envoy.io_socket", - "envoy.original_ip_detection", + "envoy.http.original_ip_detection", "envoy.rate_limit_descriptors", "envoy.resource_monitors", "envoy.retry_host_predicates", diff --git a/generated_api_shadow/BUILD b/generated_api_shadow/BUILD index 9e9a97eed0f9..e7fa4e782e9b 100644 --- a/generated_api_shadow/BUILD +++ b/generated_api_shadow/BUILD @@ -145,7 +145,6 @@ proto_library( "//envoy/config/resource_monitor/injected_resource/v2alpha:pkg", "//envoy/config/retry/omit_canary_hosts/v2:pkg", "//envoy/config/retry/previous_hosts/v2:pkg", - "//envoy/config/retry/previous_hosts/v3:pkg", "//envoy/config/route/v3:pkg", "//envoy/config/tap/v3:pkg", "//envoy/config/trace/v3:pkg", @@ -245,7 +244,6 @@ proto_library( "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", - "//envoy/extensions/original_ip_detection/common/v3:pkg", "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", "//envoy/extensions/original_ip_detection/xff/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 42c161dd4db5..7dd9cf1a82b7 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -435,7 +435,13 @@ message HttpConnectionManager { // determining the origin client's IP address. The default is zero if this option // is not specified. See the documentation for // :ref:`config_http_conn_man_headers_x-forwarded-for` for more information. - uint32 xff_num_trusted_hops = 19; + // + // .. note:: + // This field is deprecated and instead :ref:`original_ip_detection_extensions + // ` + // should be used to configure the :ref:`xff extension ` + // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. + uint32 xff_num_trusted_hops = 19 [deprecated = true]; // Configures what network addresses are considered internal for stats and header sanitation // purposes. If unspecified, only RFC1918 IP addresses will be considered internal. @@ -613,7 +619,7 @@ message HttpConnectionManager { // Two available extensions are the :ref:`xff // extension ` and the // :ref:`custom header extension `. - // [#extension-category: envoy.original_ip_detection] + // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 43; google.protobuf.Duration hidden_envoy_deprecated_idle_timeout = 11 diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 70c8081ae5d9..dc7385b9c4df 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -430,7 +430,13 @@ message HttpConnectionManager { // determining the origin client's IP address. The default is zero if this option // is not specified. See the documentation for // :ref:`config_http_conn_man_headers_x-forwarded-for` for more information. - uint32 xff_num_trusted_hops = 19; + // + // .. note:: + // This field is deprecated and instead :ref:`original_ip_detection_extensions + // ` + // should be used to configure the :ref:`xff extension ` + // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. + uint32 hidden_envoy_deprecated_xff_num_trusted_hops = 19 [deprecated = true]; // Configures what network addresses are considered internal for stats and header sanitation // purposes. If unspecified, only RFC1918 IP addresses will be considered internal. @@ -607,7 +613,7 @@ message HttpConnectionManager { // Two available extensions are the :ref:`xff // extension ` and the // :ref:`custom header extension `. - // [#extension-category: envoy.original_ip_detection] + // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 43; } diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/BUILD b/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/BUILD deleted file mode 100644 index 9a76b7e148e0..000000000000 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/BUILD +++ /dev/null @@ -1,12 +0,0 @@ -# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. - -load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") - -licenses(["notice"]) # Apache 2 - -api_proto_package( - deps = [ - "//envoy/type/v3:pkg", - "@com_github_cncf_udpa//udpa/annotations:pkg", - ], -) diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto deleted file mode 100644 index 6d31c78db943..000000000000 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto +++ /dev/null @@ -1,38 +0,0 @@ -syntax = "proto3"; - -package envoy.extensions.original_ip_detection.common.v3; - -import "envoy/type/v3/http_status.proto"; - -import "udpa/annotations/status.proto"; - -option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.common.v3"; -option java_outer_classname = "OriginalIpDetectionProto"; -option java_multiple_files = true; -option (udpa.annotations.file_status).package_version_status = ACTIVE; - -// [#protodoc-title: Common original IP detection types] - -// Common configuration for IP detection extensions. -// -// [#next-free-field: 6] -message OriginalIPDetectionCommonConfig { - // Is the detected address trusted (e.g.: can it be used to determine if this is an internal - // request). - bool allow_trusted_address_checks = 1; - - // If true, requests for which either the configured header is missing or parsing an IP from its - // value fails will be rejected. - bool reject_request_if_detection_fails = 2; - - // If reject_request_if_detection_fails is set, this sets the HTTP status that is returned to the client - // when detection fails. The default status is HTTP 403 Forbidden. - type.v3.HttpStatus status_on_error = 3; - - // If reject_request_if_detection_fails is set, this sets the HTTP body that is returned to the client - // when detection fails. - string body_on_error = 4; - - // If reject_request_if_detection_fails is set, this sets the a string detailing why this local reply was sent. - string details_on_error = 5; -} diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD index 5e7ea3961cc3..9a76b7e148e0 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD @@ -6,7 +6,7 @@ licenses(["notice"]) # Apache 2 api_proto_package( deps = [ - "//envoy/extensions/original_ip_detection/common/v3:pkg", + "//envoy/type/v3:pkg", "@com_github_cncf_udpa//udpa/annotations:pkg", ], ) diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index 7fe80600ac7d..48f5ba385a6d 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package envoy.extensions.original_ip_detection.custom_header.v3; -import "envoy/extensions/original_ip_detection/common/v3/original_ip_detection.proto"; +import "envoy/type/v3/http_status.proto"; import "udpa/annotations/status.proto"; import "validate/validate.proto"; @@ -19,11 +19,30 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // as an IP, it'll be treated as the effective downstream remote address and seen as such // by all filters. // -// [#extension: envoy.original_ip_detection.custom_header] +// [#extension: envoy.http.original_ip_detection.custom_header] message CustomHeaderConfig { + // Configuration options for rejecting requests when detection fails. + message RejectOptions { + // If reject_request_if_detection_fails is set, this sets the HTTP status that is returned to the client + // when detection fails. The default status is HTTP 403 Forbidden. + type.v3.HttpStatus status_on_error = 1; + + // If reject_request_if_detection_fails is set, this sets the HTTP body that is returned to the client + // when detection fails. + string body_on_error = 2; + + // If reject_request_if_detection_fails is set, this sets the a string detailing why this local reply was sent. + string details_on_error = 3; + } + // The header name containing the original downstream remote address, if present. string header_name = 1 [(validate.rules).string = {min_len: 1}]; - // Common configuration across detection extensions. - common.v3.OriginalIPDetectionCommonConfig common_config = 2; + // Is the detected address trusted (e.g.: can it be used to determine if this is an internal + // request). + bool allow_trusted_address_checks = 2; + + // If set, requests for which either the configured header is missing or parsing an IP from its + // value fails will be rejected with these options. + RejectOptions reject_options = 3; } diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto index 84e2bcba67b8..c5bd63cf00ab 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto @@ -14,7 +14,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // This extension allows for the original downstream remote IP to be detected // by reading the :ref:`config_http_conn_man_headers_x-forwarded-for` header. // -// [#extension: envoy.original_ip_detection.xff] +// [#extension: envoy.http.original_ip_detection.xff] message XffConfig { // The number of additional ingress proxy hops from the right side of the // :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header to trust when diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index ee94e0f882f2..4a1b9f561c3e 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -78,7 +78,7 @@ class OriginalIPDetectionFactory : public Envoy::Config::TypedFactory { */ virtual OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message& config) const PURE; - std::string category() const override { return "envoy.original_ip_detection"; } + std::string category() const override { return "envoy.http.original_ip_detection"; } }; using OriginalIPDetectionFactoryPtr = std::unique_ptr; diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index a635130b41b1..9769250896e9 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -254,8 +254,8 @@ EXTENSIONS = { # Original IP detection # - "envoy.original_ip_detection.custom_header": "//source/extensions/original_ip_detection/custom_header:config", - "envoy.original_ip_detection.xff": "//source/extensions/original_ip_detection/xff:config", + "envoy.http.original_ip_detection.custom_header": "//source/extensions/original_ip_detection/custom_header:config", + "envoy.http.original_ip_detection.xff": "//source/extensions/original_ip_detection/xff:config", } # These can be changed to ["//visibility:public"], for downstream builds which diff --git a/source/extensions/original_ip_detection/custom_header/BUILD b/source/extensions/original_ip_detection/custom_header/BUILD index f1f74e6e4b3b..d31275894ed0 100644 --- a/source/extensions/original_ip_detection/custom_header/BUILD +++ b/source/extensions/original_ip_detection/custom_header/BUILD @@ -26,7 +26,7 @@ envoy_cc_extension( name = "config", srcs = ["config.cc"], hdrs = ["config.h"], - category = "envoy.original_ip_detection", + category = "envoy.http.original_ip_detection", security_posture = "robust_to_untrusted_downstream", # This extensions is core code. visibility = ["//visibility:public"], diff --git a/source/extensions/original_ip_detection/custom_header/config.h b/source/extensions/original_ip_detection/custom_header/config.h index 867c39529a0b..07b5643de47e 100644 --- a/source/extensions/original_ip_detection/custom_header/config.h +++ b/source/extensions/original_ip_detection/custom_header/config.h @@ -20,7 +20,7 @@ class CustomHeaderIPDetectionFactory : public Http::OriginalIPDetectionFactory { envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig>(); } - std::string name() const override { return "envoy.original_ip_detection.custom_header"; } + std::string name() const override { return "envoy.http.original_ip_detection.custom_header"; } }; } // namespace CustomHeader diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc index 9ef508f9e19d..6fa118ce47b5 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -10,17 +10,17 @@ namespace CustomHeader { CustomHeaderIPDetection::CustomHeaderIPDetection( const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& config) : header_name_(config.header_name()), - allow_trusted_address_checks_(config.common_config().allow_trusted_address_checks()) { + allow_trusted_address_checks_(config.allow_trusted_address_checks()) { - if (config.has_common_config() && config.common_config().reject_request_if_detection_fails()) { + if (config.has_reject_options()) { Http::Code reject_code = Http::Code::Forbidden; - if (config.common_config().has_status_on_error()) { - reject_code = static_cast(config.common_config().status_on_error().code()); + if (config.reject_options().has_status_on_error()) { + reject_code = static_cast(config.reject_options().status_on_error().code()); } - reject_options_ = {reject_code, config.common_config().body_on_error(), - config.common_config().details_on_error()}; + reject_options_ = {reject_code, config.reject_options().body_on_error(), + config.reject_options().details_on_error()}; } } diff --git a/source/extensions/original_ip_detection/xff/BUILD b/source/extensions/original_ip_detection/xff/BUILD index 86f3626edf5d..87fc1dad202f 100644 --- a/source/extensions/original_ip_detection/xff/BUILD +++ b/source/extensions/original_ip_detection/xff/BUILD @@ -26,7 +26,7 @@ envoy_cc_extension( name = "config", srcs = ["config.cc"], hdrs = ["config.h"], - category = "envoy.original_ip_detection", + category = "envoy.http.original_ip_detection", security_posture = "robust_to_untrusted_downstream", deps = [ ":xff_lib", diff --git a/source/extensions/original_ip_detection/xff/config.h b/source/extensions/original_ip_detection/xff/config.h index 42c9c50e31fb..fe7c8cd26ce5 100644 --- a/source/extensions/original_ip_detection/xff/config.h +++ b/source/extensions/original_ip_detection/xff/config.h @@ -19,7 +19,7 @@ class XffIPDetectionFactory : public Http::OriginalIPDetectionFactory { return std::make_unique(); } - std::string name() const override { return "envoy.original_ip_detection.xff"; } + std::string name() const override { return "envoy.http.original_ip_detection.xff"; } }; } // namespace Xff diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 5b9f7bc14a50..074bee84cfe1 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -1737,7 +1737,7 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { route_config: name: local_route original_ip_detection_extensions: - - name: envoy.original_ip_detection.custom_header + - name: envoy.http.original_ip_detection.custom_header typed_config: "@type": type.googleapis.com/envoy.extensions.original_ip_detection.custom_header.v3.CustomHeaderConfig header_name: x-ip-header diff --git a/test/extensions/original_ip_detection/custom_header/BUILD b/test/extensions/original_ip_detection/custom_header/BUILD index 7cad806dbe62..6b18b282142d 100644 --- a/test/extensions/original_ip_detection/custom_header/BUILD +++ b/test/extensions/original_ip_detection/custom_header/BUILD @@ -14,7 +14,7 @@ envoy_package() envoy_extension_cc_test( name = "custom_header_detection_test", srcs = ["custom_header_test.cc"], - extension_name = "envoy.original_ip_detection.custom_header", + extension_name = "envoy.http.original_ip_detection.custom_header", deps = [ "//source/common/network:utility_lib", "//source/extensions/original_ip_detection/custom_header:custom_header_lib", @@ -26,7 +26,7 @@ envoy_extension_cc_test( envoy_extension_cc_test( name = "config_test", srcs = ["config_test.cc"], - extension_name = "envoy.original_ip_detection.custom_header", + extension_name = "envoy.http.original_ip_detection.custom_header", deps = [ "//include/envoy/registry", "//source/extensions/original_ip_detection/custom_header:config", diff --git a/test/extensions/original_ip_detection/custom_header/config_test.cc b/test/extensions/original_ip_detection/custom_header/config_test.cc index 6d33dcc96a8a..51d86884fb22 100644 --- a/test/extensions/original_ip_detection/custom_header/config_test.cc +++ b/test/extensions/original_ip_detection/custom_header/config_test.cc @@ -14,7 +14,7 @@ namespace CustomHeader { TEST(CustomHeaderFactoryTest, Basic) { auto* factory = Registry::FactoryRegistry::getFactory( - "envoy.original_ip_detection.custom_header"); + "envoy.http.original_ip_detection.custom_header"); ASSERT_NE(factory, nullptr); auto empty = factory->createEmptyConfigProto(); diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index c66387fea2d5..1490d2642afe 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -18,14 +18,12 @@ class CustomHeaderTest : public testing::Test { CustomHeaderTest() { envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; config.set_header_name("x-real-ip"); + config.set_allow_trusted_address_checks(true); - auto* common_config = config.mutable_common_config(); - common_config->set_allow_trusted_address_checks(true); - common_config->set_reject_request_if_detection_fails(true); - common_config->set_body_on_error("detection failed"); - common_config->set_details_on_error("rejecting because detection failed"); - - auto* status_on_error = common_config->mutable_status_on_error(); + auto* reject_options = config.mutable_reject_options(); + reject_options->set_body_on_error("detection failed"); + reject_options->set_details_on_error("rejecting because detection failed"); + auto* status_on_error = reject_options->mutable_status_on_error(); status_on_error->set_code(envoy::type::v3::StatusCode::Unauthorized); custom_header_extension_ = std::make_shared(config); diff --git a/test/extensions/original_ip_detection/xff/BUILD b/test/extensions/original_ip_detection/xff/BUILD index cbca6ea4d968..f66b1cb3a389 100644 --- a/test/extensions/original_ip_detection/xff/BUILD +++ b/test/extensions/original_ip_detection/xff/BUILD @@ -14,7 +14,7 @@ envoy_package() envoy_extension_cc_test( name = "xff_detection_test", srcs = ["xff_test.cc"], - extension_name = "envoy.original_ip_detection.xff", + extension_name = "envoy.http.original_ip_detection.xff", deps = [ "//source/common/http:utility_lib", "//source/extensions/original_ip_detection/xff:xff_lib", @@ -26,7 +26,7 @@ envoy_extension_cc_test( envoy_extension_cc_test( name = "config_test", srcs = ["config_test.cc"], - extension_name = "envoy.original_ip_detection.xff", + extension_name = "envoy.http.original_ip_detection.xff", deps = [ "//include/envoy/registry", "//source/extensions/original_ip_detection/xff:config", diff --git a/test/extensions/original_ip_detection/xff/config_test.cc b/test/extensions/original_ip_detection/xff/config_test.cc index c51f330068a4..7d06984dde82 100644 --- a/test/extensions/original_ip_detection/xff/config_test.cc +++ b/test/extensions/original_ip_detection/xff/config_test.cc @@ -14,7 +14,7 @@ namespace Xff { TEST(CustomHeaderFactoryTest, Basic) { auto* factory = Registry::FactoryRegistry::getFactory( - "envoy.original_ip_detection.xff"); + "envoy.http.original_ip_detection.xff"); ASSERT_NE(factory, nullptr); auto empty = factory->createEmptyConfigProto(); diff --git a/test/integration/original_ip_detection_integration_test.cc b/test/integration/original_ip_detection_integration_test.cc index 9de88904a704..3ef732388df6 100644 --- a/test/integration/original_ip_detection_integration_test.cc +++ b/test/integration/original_ip_detection_integration_test.cc @@ -26,7 +26,7 @@ TEST_F(OriginalIPDetectionIntegrationTest, HeaderBasedDetection) { config.set_header_name("x-cdn-detected-ip"); auto* extension = hcm.add_original_ip_detection_extensions(); - extension->set_name("envoy.original_ip_detection.custom_header"); + extension->set_name("envoy.http.original_ip_detection.custom_header"); extension->mutable_typed_config()->PackFrom(config); hcm.mutable_use_remote_address()->set_value(false); From 8ad18c6a963e5369098f0612aae47be33a985572 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 3 Mar 2021 15:05:44 -0500 Subject: [PATCH 042/100] Rename config param to allow_extension_to_set_address_as_trusted Signed-off-by: Raul Gutierrez Segales --- .../custom_header/v3/custom_header.proto | 7 ++++--- .../custom_header/v3/custom_header.proto | 7 ++++--- .../original_ip_detection/custom_header/custom_header.cc | 2 +- .../custom_header/custom_header_test.cc | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index 48f5ba385a6d..fffae909a8a1 100644 --- a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -38,9 +38,10 @@ message CustomHeaderConfig { // The header name containing the original downstream remote address, if present. string header_name = 1 [(validate.rules).string = {min_len: 1}]; - // Is the detected address trusted (e.g.: can it be used to determine if this is an internal - // request). - bool allow_trusted_address_checks = 2; + // If set to true, the extension is allowed to decide if the detected address should be treated as + // trusted. If a detected address is considered trusted, it might be used as input to determine + // if the request is internal (among other things). + bool allow_extension_to_set_address_as_trusted = 2; // If set, requests for which either the configured header is missing or parsing an IP from its // value fails will be rejected with these options. diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index 48f5ba385a6d..fffae909a8a1 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -38,9 +38,10 @@ message CustomHeaderConfig { // The header name containing the original downstream remote address, if present. string header_name = 1 [(validate.rules).string = {min_len: 1}]; - // Is the detected address trusted (e.g.: can it be used to determine if this is an internal - // request). - bool allow_trusted_address_checks = 2; + // If set to true, the extension is allowed to decide if the detected address should be treated as + // trusted. If a detected address is considered trusted, it might be used as input to determine + // if the request is internal (among other things). + bool allow_extension_to_set_address_as_trusted = 2; // If set, requests for which either the configured header is missing or parsing an IP from its // value fails will be rejected with these options. diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc index 6fa118ce47b5..f294794a0255 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -10,7 +10,7 @@ namespace CustomHeader { CustomHeaderIPDetection::CustomHeaderIPDetection( const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& config) : header_name_(config.header_name()), - allow_trusted_address_checks_(config.allow_trusted_address_checks()) { + allow_trusted_address_checks_(config.allow_extension_to_set_address_as_trusted()) { if (config.has_reject_options()) { Http::Code reject_code = Http::Code::Forbidden; diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index 1490d2642afe..b5279051e118 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -18,7 +18,7 @@ class CustomHeaderTest : public testing::Test { CustomHeaderTest() { envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; config.set_header_name("x-real-ip"); - config.set_allow_trusted_address_checks(true); + config.set_allow_extension_to_set_address_as_trusted(true); auto* reject_options = config.mutable_reject_options(); reject_options->set_body_on_error("detection failed"); From 9a0d41b4b08f9c6afffc84e085a29d725eaa0406 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 3 Mar 2021 15:36:27 -0500 Subject: [PATCH 043/100] Update header to reflect we now support a list of extensions Signed-off-by: Raul Gutierrez Segales --- include/envoy/http/original_ip_detection.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index 4a1b9f561c3e..7de8dd5f98df 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -49,10 +49,9 @@ class OriginalIPDetection { /** * Detect the final remote address. * - * Note that, when an extension is configured, this method will be called - * ahead of the attempt to extract the downstream remote address from the - * x-forwarded-for header. If the call fails to detect the original IP address, - * the HCM will then fallback to the standard IP detection mechanisms. + * If the call to this method succeeds in detecting the remote IP address or + * fails and is configured to reject the request in that case, no other + * configured extensions will be called (if any). * * @param param supplies the OriginalIPDetectionParams params for detection. * @return OriginalIPDetectionResult the result of the extension's attempt to detect From 4043a4ac2c63cf28b7be1b4742e1258950679d00 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 3 Mar 2021 16:25:08 -0500 Subject: [PATCH 044/100] Alyssa's feedback Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 18 ++++++++++-------- .../v4alpha/http_connection_manager.proto | 18 ++++++++++-------- .../v3/http_connection_manager.proto | 18 ++++++++++-------- .../v4alpha/http_connection_manager.proto | 18 ++++++++++-------- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 76493a052ec4..e935d7947c9a 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -594,27 +594,29 @@ message HttpConnectionManager { // By default, when the :ref:`use_remote_address // ` // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the :ref:`xff_num_trusted_hops + // and the deprecated :ref:`xff_num_trusted_hops // ` - // configuration option to detect the remote address. + // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops + // ` + // is removed, leaving this field empty will retain the default behavior when that field is unset. See + // the :ref:`xff extension ` for how to + // configure xff_num_trusted_hops when using extensions. // - // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` // header doesn't necessarily work for all network configurations. For instance, // if the number of trusted hops isn't consistent for requests flowing into // Envoy this mechanism cannot be used reliably. For such cases, the following // option allows for a list of custom extensions to be provided. // - // If configured, the custom extensions will be called along with the request headers + // When configured the extensions will be called along with the request headers // and information about the downstream connection, such as direct connected address, // when the HCM needs to populate the final remote address. Each extension will then rely // on these parameters to decide the value of the request's final remote address. // If an extension fails to detect the original IP address and isn't configured to reject // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. + // until one succeeds or the request is rejected. If the request isn't rejected nor any extension + // succeeds, the HCM will fallback to using the remote address. // - // Two available extensions are the :ref:`xff - // extension ` and the - // :ref:`custom header extension `. // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 43; } diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 87aaf9b52694..3c5a3cb852cf 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -579,27 +579,29 @@ message HttpConnectionManager { // By default, when the :ref:`use_remote_address // ` // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the :ref:`xff_num_trusted_hops + // and the deprecated :ref:`xff_num_trusted_hops // ` - // configuration option to detect the remote address. + // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops + // ` + // is removed, leaving this field empty will retain the default behavior when that field is unset. See + // the :ref:`xff extension ` for how to + // configure xff_num_trusted_hops when using extensions. // - // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` // header doesn't necessarily work for all network configurations. For instance, // if the number of trusted hops isn't consistent for requests flowing into // Envoy this mechanism cannot be used reliably. For such cases, the following // option allows for a list of custom extensions to be provided. // - // If configured, the custom extensions will be called along with the request headers + // When configured the extensions will be called along with the request headers // and information about the downstream connection, such as direct connected address, // when the HCM needs to populate the final remote address. Each extension will then rely // on these parameters to decide the value of the request's final remote address. // If an extension fails to detect the original IP address and isn't configured to reject // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. + // until one succeeds or the request is rejected. If the request isn't rejected nor any extension + // succeeds, the HCM will fallback to using the remote address. // - // Two available extensions are the :ref:`xff - // extension ` and the - // :ref:`custom header extension `. // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 43; } diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 7dd9cf1a82b7..26e25829cc13 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -598,27 +598,29 @@ message HttpConnectionManager { // By default, when the :ref:`use_remote_address // ` // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the :ref:`xff_num_trusted_hops + // and the deprecated :ref:`xff_num_trusted_hops // ` - // configuration option to detect the remote address. + // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops + // ` + // is removed, leaving this field empty will retain the default behavior when that field is unset. See + // the :ref:`xff extension ` for how to + // configure xff_num_trusted_hops when using extensions. // - // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` // header doesn't necessarily work for all network configurations. For instance, // if the number of trusted hops isn't consistent for requests flowing into // Envoy this mechanism cannot be used reliably. For such cases, the following // option allows for a list of custom extensions to be provided. // - // If configured, the custom extensions will be called along with the request headers + // When configured the extensions will be called along with the request headers // and information about the downstream connection, such as direct connected address, // when the HCM needs to populate the final remote address. Each extension will then rely // on these parameters to decide the value of the request's final remote address. // If an extension fails to detect the original IP address and isn't configured to reject // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. + // until one succeeds or the request is rejected. If the request isn't rejected nor any extension + // succeeds, the HCM will fallback to using the remote address. // - // Two available extensions are the :ref:`xff - // extension ` and the - // :ref:`custom header extension `. // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 43; diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index dc7385b9c4df..728061f8e796 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -592,27 +592,29 @@ message HttpConnectionManager { // By default, when the :ref:`use_remote_address // ` // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the :ref:`xff_num_trusted_hops + // and the deprecated :ref:`xff_num_trusted_hops // ` - // configuration option to detect the remote address. + // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops + // ` + // is removed, leaving this field empty will retain the default behavior when that field is unset. See + // the :ref:`xff extension ` for how to + // configure xff_num_trusted_hops when using extensions. // - // However, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` // header doesn't necessarily work for all network configurations. For instance, // if the number of trusted hops isn't consistent for requests flowing into // Envoy this mechanism cannot be used reliably. For such cases, the following // option allows for a list of custom extensions to be provided. // - // If configured, the custom extensions will be called along with the request headers + // When configured the extensions will be called along with the request headers // and information about the downstream connection, such as direct connected address, // when the HCM needs to populate the final remote address. Each extension will then rely // on these parameters to decide the value of the request's final remote address. // If an extension fails to detect the original IP address and isn't configured to reject // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. + // until one succeeds or the request is rejected. If the request isn't rejected nor any extension + // succeeds, the HCM will fallback to using the remote address. // - // Two available extensions are the :ref:`xff - // extension ` and the - // :ref:`custom header extension `. // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 43; } From f87300273f0720688fbcbc18f079490abdc2cd9e Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 3 Mar 2021 16:54:57 -0500 Subject: [PATCH 045/100] Fix deprecation error in test Signed-off-by: Raul Gutierrez Segales --- test/integration/header_integration_test.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/integration/header_integration_test.cc b/test/integration/header_integration_test.cc index 9cdf7e0f7203..ba80a2918aa0 100644 --- a/test/integration/header_integration_test.cc +++ b/test/integration/header_integration_test.cc @@ -42,7 +42,11 @@ const std::string http_connection_mgr_config = R"EOF( - name: envoy.filters.http.router codec_type: HTTP1 use_remote_address: false -xff_num_trusted_hops: 1 +original_ip_detection_extensions: +- name: envoy.http.original_ip_detection.xff + typed_config: + "@type": type.googleapis.com/envoy.extensions.original_ip_detection.xff.v3.XffConfig + xff_num_trusted_hops: 1 stat_prefix: header_test route_config: virtual_hosts: From 98bb064b36409068fc642c36ade0cb4d07f98d6b Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 4 Mar 2021 13:46:18 -0500 Subject: [PATCH 046/100] Force registration of the XFF extension Signed-off-by: Raul Gutierrez Segales --- test/integration/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/BUILD b/test/integration/BUILD index ccbdac7123a2..be1d343233ca 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -309,6 +309,7 @@ envoy_cc_test( ":http_integration_lib", "//source/common/config:api_version_lib", "//source/common/protobuf", + "//source/extensions/original_ip_detection/xff:config", "//test/test_common:utility_lib", "@envoy_api//envoy/api/v2:pkg_cc_proto", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", From a52359415c42045b13ceee4ce1e0d580f3296c18 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 4 Mar 2021 15:30:42 -0500 Subject: [PATCH 047/100] Visibility public for XFF config Signed-off-by: Raul Gutierrez Segales --- source/extensions/original_ip_detection/xff/BUILD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/extensions/original_ip_detection/xff/BUILD b/source/extensions/original_ip_detection/xff/BUILD index 87fc1dad202f..8728d8a4c0e7 100644 --- a/source/extensions/original_ip_detection/xff/BUILD +++ b/source/extensions/original_ip_detection/xff/BUILD @@ -28,6 +28,8 @@ envoy_cc_extension( hdrs = ["config.h"], category = "envoy.http.original_ip_detection", security_posture = "robust_to_untrusted_downstream", + # This extensions is core code. + visibility = ["//visibility:public"], deps = [ ":xff_lib", "//include/envoy/http:original_ip_detection_interface", From 63b8f2c8ec30e0f00b911d6cffa3691aab584f62 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 5 Mar 2021 07:44:00 -0500 Subject: [PATCH 048/100] Fix merge Signed-off-by: Raul Gutierrez Segales --- test/common/http/BUILD | 1 + test/common/http/conn_manager_utility_test.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/test/common/http/BUILD b/test/common/http/BUILD index cea23e539c4d..0064a7e7825c 100644 --- a/test/common/http/BUILD +++ b/test/common/http/BUILD @@ -247,6 +247,7 @@ envoy_cc_test( "//source/common/runtime:runtime_lib", "//source/extensions/original_ip_detection/custom_header:custom_header_lib", "//source/extensions/original_ip_detection/xff:xff_lib", + "//source/extensions/request_id/uuid:config", "//test/mocks/http:http_mocks", "//test/mocks/local_info:local_info_mocks", "//test/mocks/network:network_mocks", diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index 00faa6e8e684..9a62e5ea55a5 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -142,6 +142,7 @@ class ConnectionManagerUtilityTest : public testing::Test { NiceMock connection_; NiceMock random_; std::shared_ptr> request_id_extension_; + const std::shared_ptr request_id_extension_; const std::shared_ptr request_id_extension_to_return_; std::vector detection_extensions_{}; NiceMock config_; From 056db7c572727ab1abee9a3bd31f5e3f00d95d12 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 5 Mar 2021 12:37:26 -0500 Subject: [PATCH 049/100] Fix merge leftover Signed-off-by: Raul Gutierrez Segales --- test/common/http/conn_manager_utility_test.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index 9a62e5ea55a5..e0bfbe921b68 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -141,7 +141,6 @@ class ConnectionManagerUtilityTest : public testing::Test { NiceMock connection_; NiceMock random_; - std::shared_ptr> request_id_extension_; const std::shared_ptr request_id_extension_; const std::shared_ptr request_id_extension_to_return_; std::vector detection_extensions_{}; From d0a99c16738777d1da690027a24a133f5ba41a8b Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Sun, 14 Mar 2021 10:24:48 -0400 Subject: [PATCH 050/100] Fix merge Signed-off-by: Raul Gutierrez Segales --- source/common/network/utility.cc | 20 ++++++++++---------- source/common/network/utility.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source/common/network/utility.cc b/source/common/network/utility.cc index e46556a1e7c0..e13a4fbee0e7 100644 --- a/source/common/network/utility.cc +++ b/source/common/network/utility.cc @@ -125,16 +125,6 @@ uint32_t Utility::portFromUdpUrl(const std::string& url) { return portFromUrl(url, UDP_SCHEME, "UDP"); } -Address::InstanceConstSharedPtr Utility::parseInternetAddress(const std::string& ip_address, - uint16_t port, bool v6only) { - auto addr = parseInternetAddressNoThrow(ip_address, port, v6only); - if (addr) { - return addr; - } - throwWithMalformedIp(ip_address); - NOT_REACHED_GCOVR_EXCL_LINE; -} - Address::InstanceConstSharedPtr Utility::parseInternetAddressNoThrow(const std::string& ip_address, uint16_t port, bool v6only) { sockaddr_in sa4; @@ -153,6 +143,16 @@ Address::InstanceConstSharedPtr Utility::parseInternetAddressNoThrow(const std:: return nullptr; } +Address::InstanceConstSharedPtr Utility::parseInternetAddress(const std::string& ip_address, + uint16_t port, bool v6only) { + const Address::InstanceConstSharedPtr address = + parseInternetAddressNoThrow(ip_address, port, v6only); + if (address == nullptr) { + throwWithMalformedIp(ip_address); + } + return address; +} + Address::InstanceConstSharedPtr Utility::parseInternetAddressAndPortNoThrow(const std::string& ip_address, bool v6only) { if (ip_address.empty()) { diff --git a/source/common/network/utility.h b/source/common/network/utility.h index ef00cc6f456b..b6a351118b44 100644 --- a/source/common/network/utility.h +++ b/source/common/network/utility.h @@ -127,7 +127,7 @@ class Utility { /** * Parse an internet host address (IPv4 or IPv6) and create an Instance from it. The address must - * not include a port number. Throws EnvoyException if unable to parse the address. + * not include a port number. * @param ip_address string to be parsed as an internet address. * @param port optional port to include in Instance created from ip_address, 0 by default. * @param v6only disable IPv4-IPv6 mapping for IPv6 addresses? From 684c8af253e6bb9e0c55c09710939ba0dc8e44ae Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 17 Mar 2021 18:50:35 -0400 Subject: [PATCH 051/100] Fix merge Signed-off-by: Raul Gutierrez Segales --- docs/root/version_history/current.rst | 1 - source/common/network/utility.h | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 40db3532863b..4af55ec05389 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -126,7 +126,6 @@ New Features * http: added support for :ref:`original IP detection extensions`. Two initial extensions were added, the :ref:`custom header ` extension and the :ref:`xff ` extension. -* http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 and HTTP/2 dispatching. Crashes while inside the dispatching loop should dump debug information. * http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 and HTTP/2 dispatching. Crashes while inside the dispatching loop should dump debug information. Furthermore, HTTP/1 and HTTP/2 clients now dumps the originating request whose response from the upstream caused Envoy to crash. * http: added support for :ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. * http: added new runtime config `envoy.reloadable_features.check_unsupported_typed_per_filter_config`, the default value is true. When the value is true, envoy will reject virtual host-specific typed per filter config when the filter doesn't support it. diff --git a/source/common/network/utility.h b/source/common/network/utility.h index 089793ee889f..7aab902eb2ac 100644 --- a/source/common/network/utility.h +++ b/source/common/network/utility.h @@ -135,7 +135,7 @@ class Utility { /** * Parse an internet host address (IPv4 or IPv6) and create an Instance from it. The address must - * not include a port number. + * not include a port number. Throws EnvoyException if unable to parse the address. * @param ip_address string to be parsed as an internet address. * @param port optional port to include in Instance created from ip_address, 0 by default. * @param v6only disable IPv4-IPv6 mapping for IPv6 addresses? @@ -147,7 +147,7 @@ class Utility { /** * Parse an internet host address (IPv4 or IPv6) and create an Instance from it. The address must - * not include a port number. + * not include a port number. Throws EnvoyException if unable to parse the address. * @param ip_address string to be parsed as an internet address. * @param port optional port to include in Instance created from ip_address, 0 by default. * @param v6only disable IPv4-IPv6 mapping for IPv6 addresses? From 8a692d67232d5c4b05f387d4ed1ff6d78c806456 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 30 Mar 2021 11:38:15 -0400 Subject: [PATCH 052/100] Fix merge snafu Signed-off-by: Raul Gutierrez Segales --- source/extensions/extensions_build_config.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index 4eae27973e91..da11ee6a64ec 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -262,7 +262,7 @@ EXTENSIONS = { # HTTP header formatters # - "envoy.http.stateful_header_formatters.preserve_case": "//source/extensions/http/header_formatters/preserve_case:preserve_case_formatter" + "envoy.http.stateful_header_formatters.preserve_case": "//source/extensions/http/header_formatters/preserve_case:preserve_case_formatter", # # Original IP detection From 85684942d5a9f797d08e36f61caa4613ec70c2b3 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Mon, 5 Apr 2021 13:47:53 -0400 Subject: [PATCH 053/100] Add code block example for replacing xff_num_trusted_hops Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 11 ++++++++++- .../v3/http_connection_manager.proto | 11 ++++++++++- .../v4alpha/http_connection_manager.proto | 11 ++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index f4d7596a414c..1fa6f15daf0a 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -469,7 +469,16 @@ message HttpConnectionManager { // This field is deprecated and instead :ref:`original_ip_detection_extensions // ` // should be used to configure the :ref:`xff extension ` - // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. + // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. To replace + // this field use a config like the following: + // + // .. code-block:: yaml + // + // original_ip_detection_extensions: + // typed_config: + // "@type": type.googleapis.com/envoy.extensions.original_ip_detection.xff.v3.XffConfig + // xff_num_trusted_hops: 1 + // uint32 xff_num_trusted_hops = 19 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 255df665f5d2..e92f528e0b44 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -474,7 +474,16 @@ message HttpConnectionManager { // This field is deprecated and instead :ref:`original_ip_detection_extensions // ` // should be used to configure the :ref:`xff extension ` - // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. + // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. To replace + // this field use a config like the following: + // + // .. code-block:: yaml + // + // original_ip_detection_extensions: + // typed_config: + // "@type": type.googleapis.com/envoy.extensions.original_ip_detection.xff.v3.XffConfig + // xff_num_trusted_hops: 1 + // uint32 xff_num_trusted_hops = 19 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 7f2d271c4664..0e438b71164a 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -472,7 +472,16 @@ message HttpConnectionManager { // This field is deprecated and instead :ref:`original_ip_detection_extensions // ` // should be used to configure the :ref:`xff extension ` - // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. + // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. To replace + // this field use a config like the following: + // + // .. code-block:: yaml + // + // original_ip_detection_extensions: + // typed_config: + // "@type": type.googleapis.com/envoy.extensions.original_ip_detection.xff.v3.XffConfig + // xff_num_trusted_hops: 1 + // uint32 hidden_envoy_deprecated_xff_num_trusted_hops = 19 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; From cd9b36075a59778af0374fcdb05294870b48bfc8 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Mon, 5 Apr 2021 17:25:48 -0400 Subject: [PATCH 054/100] Alyssa's feedback (partial) There are 3 items pending, we'll discuss them offline or via comments. Signed-off-by: Raul Gutierrez Segales --- .../custom_header/v3/custom_header.proto | 16 +++++++++------- .../http/http_conn_man/response_code_details.rst | 1 + docs/root/version_history/current.rst | 1 + .../custom_header/v3/custom_header.proto | 16 +++++++++------- include/envoy/http/original_ip_detection.h | 3 ++- include/envoy/stream_info/stream_info.h | 4 +++- source/common/http/conn_manager_impl.cc | 3 ++- .../original_ip_detection/custom_header/config.h | 4 ++++ .../custom_header/custom_header.cc | 5 ++--- .../custom_header/custom_header.h | 5 ++++- .../original_ip_detection/xff/config.h | 4 ++++ .../extensions/original_ip_detection/xff/xff.h | 3 +++ .../custom_header/custom_header_test.cc | 1 - 13 files changed, 44 insertions(+), 22 deletions(-) diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index fffae909a8a1..44907fcdd602 100644 --- a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -17,25 +17,27 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // This extension allows for the original downstream remote IP to be detected // by reading the value from a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such -// by all filters. +// by all filters. See :ref:`original_ip_detection_extensions +// ` +// for an overview of how extensions operate and what happens when an extension fails +// to detect the remote IP. // // [#extension: envoy.http.original_ip_detection.custom_header] message CustomHeaderConfig { // Configuration options for rejecting requests when detection fails. message RejectOptions { - // If reject_request_if_detection_fails is set, this sets the HTTP status that is returned to the client + // If reject_request_if_detection_fails is set, this sets the HTTP status that is sent downstream // when detection fails. The default status is HTTP 403 Forbidden. type.v3.HttpStatus status_on_error = 1; - // If reject_request_if_detection_fails is set, this sets the HTTP body that is returned to the client - // when detection fails. + // If reject_request_if_detection_fails is set, this sets the HTTP body in the response + // when detection fails. If not set, an empty body is used. string body_on_error = 2; - - // If reject_request_if_detection_fails is set, this sets the a string detailing why this local reply was sent. - string details_on_error = 3; } // The header name containing the original downstream remote address, if present. + // + // Note: in the case of a multi-valued header, only the first value is tried and the rest are ignored. string header_name = 1 [(validate.rules).string = {min_len: 1}]; // If set to true, the extension is allowed to decide if the detected address should be treated as diff --git a/docs/root/configuration/http/http_conn_man/response_code_details.rst b/docs/root/configuration/http/http_conn_man/response_code_details.rst index 54d6e10eb2cd..009ee6e8cb7f 100644 --- a/docs/root/configuration/http/http_conn_man/response_code_details.rst +++ b/docs/root/configuration/http/http_conn_man/response_code_details.rst @@ -35,6 +35,7 @@ Below are the list of reasons the HttpConnectionManager or Router filter may sen missing_path_rejected, The request was rejected due to a missing Path or :path header field. no_healthy_upstream, The request was rejected by the router filter because there was no healthy upstream found. overload, The request was rejected due to the Overload Manager reaching configured resource limits. + original_ip_detection_failed, The request was rejected because the original IP couldn't be detected. path_normalization_failed, "The request was rejected because path normalization was configured on and failed, probably due to an invalid path." request_headers_failed_strict_check, The request was rejected due to x-envoy-* headers failing strict header validation. request_overall_timeout, The per-stream total request timeout was exceeded. diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 54c5d5220f43..dcdfa1fb2376 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -185,4 +185,5 @@ Deprecated ---------- * admin: :ref:`access_log_path ` is deprecated in favor for :ref:`access loggers `. +* http: :ref:`xff_num_trusted_hops ` is deprecated in favor of :ref:`original IP detection extensions`. diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto index fffae909a8a1..44907fcdd602 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto @@ -17,25 +17,27 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // This extension allows for the original downstream remote IP to be detected // by reading the value from a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such -// by all filters. +// by all filters. See :ref:`original_ip_detection_extensions +// ` +// for an overview of how extensions operate and what happens when an extension fails +// to detect the remote IP. // // [#extension: envoy.http.original_ip_detection.custom_header] message CustomHeaderConfig { // Configuration options for rejecting requests when detection fails. message RejectOptions { - // If reject_request_if_detection_fails is set, this sets the HTTP status that is returned to the client + // If reject_request_if_detection_fails is set, this sets the HTTP status that is sent downstream // when detection fails. The default status is HTTP 403 Forbidden. type.v3.HttpStatus status_on_error = 1; - // If reject_request_if_detection_fails is set, this sets the HTTP body that is returned to the client - // when detection fails. + // If reject_request_if_detection_fails is set, this sets the HTTP body in the response + // when detection fails. If not set, an empty body is used. string body_on_error = 2; - - // If reject_request_if_detection_fails is set, this sets the a string detailing why this local reply was sent. - string details_on_error = 3; } // The header name containing the original downstream remote address, if present. + // + // Note: in the case of a multi-valued header, only the first value is tried and the rest are ignored. string header_name = 1 [(validate.rules).string = {min_len: 1}]; // If set to true, the extension is allowed to decide if the detected address should be treated as diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index 7de8dd5f98df..0c9972aa824e 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -13,6 +13,8 @@ namespace Envoy { namespace Http { struct OriginalIPDetectionParams { + // The request headers from downstream. + // // Note that while extensions can modify the headers, they will undergo standard Envoy // sanitation after the detect() call so additions made here may be removed before // filters have access to headers. @@ -25,7 +27,6 @@ struct OriginalIPDetectionParams { struct OriginalIPRejectRequestOptions { Code response_code; std::string body; - std::string details; }; struct OriginalIPDetectionResult { diff --git a/include/envoy/stream_info/stream_info.h b/include/envoy/stream_info/stream_info.h index 71d4fdbb2886..acf84800d730 100644 --- a/include/envoy/stream_info/stream_info.h +++ b/include/envoy/stream_info/stream_info.h @@ -181,8 +181,10 @@ struct ResponseCodeDetailValues { const std::string InternalRedirect = "internal_redirect"; // The request was rejected because configured filters erroneously removed required headers. const std::string FilterRemovedRequiredHeaders = "filter_removed_required_headers"; + // The request was rejected because the original IP couldn't be detected. + const std::string OriginalIPDetectionFailed = "rejecting because detection failed"; // Changes or additions to details should be reflected in - // docs/root/configuration/http/http_conn_man/response_code_details_details.rst + // docs/root/configuration/http/http_conn_man/response_code_details.rst }; using ResponseCodeDetails = ConstSingleton; diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc index 99563c54afb4..311f5e8346bf 100644 --- a/source/common/http/conn_manager_impl.cc +++ b/source/common/http/conn_manager_impl.cc @@ -986,7 +986,8 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(RequestHeaderMapPtr&& he connection_manager_.stats_.named_.downstream_rq_rejected_via_ip_detection_.inc(); sendLocalReply(Grpc::Common::isGrpcRequestHeaders(*request_headers_), reject_request_params.response_code, reject_request_params.body, nullptr, - absl::nullopt, reject_request_params.details); + absl::nullopt, + StreamInfo::ResponseCodeDetails::get().OriginalIPDetectionFailed); return; } diff --git a/source/extensions/original_ip_detection/custom_header/config.h b/source/extensions/original_ip_detection/custom_header/config.h index 07b5643de47e..57655accd174 100644 --- a/source/extensions/original_ip_detection/custom_header/config.h +++ b/source/extensions/original_ip_detection/custom_header/config.h @@ -10,6 +10,10 @@ namespace Extensions { namespace OriginalIPDetection { namespace CustomHeader { +/** + * Config registration for the custom header IP detection extension. + * @see OriginalIPDetectionFactory. + */ class CustomHeaderIPDetectionFactory : public Http::OriginalIPDetectionFactory { public: Http::OriginalIPDetectionSharedPtr diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc index f294794a0255..7b134efea8bb 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -19,8 +19,7 @@ CustomHeaderIPDetection::CustomHeaderIPDetection( reject_code = static_cast(config.reject_options().status_on_error().code()); } - reject_options_ = {reject_code, config.reject_options().body_on_error(), - config.reject_options().details_on_error()}; + reject_options_ = {reject_code, config.reject_options().body_on_error()}; } } @@ -31,7 +30,7 @@ CustomHeaderIPDetection::CustomHeaderIPDetection( Http::OriginalIPDetectionResult CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { - auto hdr = params.request_headers.get(Http::LowerCaseString(header_name_)); + auto hdr = params.request_headers.get(header_name_); if (hdr.empty()) { return {nullptr, false, reject_options_}; } diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.h b/source/extensions/original_ip_detection/custom_header/custom_header.h index b2e8e3c82128..bdb22baebc32 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.h +++ b/source/extensions/original_ip_detection/custom_header/custom_header.h @@ -9,6 +9,9 @@ namespace Extensions { namespace OriginalIPDetection { namespace CustomHeader { +/** + * Custom header IP detection extension. + */ class CustomHeaderIPDetection : public Http::OriginalIPDetection { public: CustomHeaderIPDetection( @@ -21,7 +24,7 @@ class CustomHeaderIPDetection : public Http::OriginalIPDetection { Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override; private: - std::string header_name_; + Http::LowerCaseString header_name_; bool allow_trusted_address_checks_{false}; absl::optional reject_options_{absl::nullopt}; }; diff --git a/source/extensions/original_ip_detection/xff/config.h b/source/extensions/original_ip_detection/xff/config.h index fe7c8cd26ce5..4046c143c041 100644 --- a/source/extensions/original_ip_detection/xff/config.h +++ b/source/extensions/original_ip_detection/xff/config.h @@ -10,6 +10,10 @@ namespace Extensions { namespace OriginalIPDetection { namespace Xff { +/** + * Config registration for the x-forwarded-for IP detection extension. + * @see OriginalIPDetectionFactory. + */ class XffIPDetectionFactory : public Http::OriginalIPDetectionFactory { public: Http::OriginalIPDetectionSharedPtr diff --git a/source/extensions/original_ip_detection/xff/xff.h b/source/extensions/original_ip_detection/xff/xff.h index efda8f47ccad..7eef8cf8589d 100644 --- a/source/extensions/original_ip_detection/xff/xff.h +++ b/source/extensions/original_ip_detection/xff/xff.h @@ -8,6 +8,9 @@ namespace Extensions { namespace OriginalIPDetection { namespace Xff { +/** + * XFF (x-forwarded-for) IP detection extension. + */ class XffIPDetection : public Http::OriginalIPDetection { public: XffIPDetection(const envoy::extensions::original_ip_detection::xff::v3::XffConfig& config); diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index b5279051e118..66c6d7d75b8a 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -22,7 +22,6 @@ class CustomHeaderTest : public testing::Test { auto* reject_options = config.mutable_reject_options(); reject_options->set_body_on_error("detection failed"); - reject_options->set_details_on_error("rejecting because detection failed"); auto* status_on_error = reject_options->mutable_status_on_error(); status_on_error->set_code(envoy::type::v3::StatusCode::Unauthorized); From 57443bde20f3618aaa1e048f64ebe413da037e91 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 6 Apr 2021 09:43:47 -0400 Subject: [PATCH 055/100] Fix build Signed-off-by: Raul Gutierrez Segales --- .../original_ip_detection/custom_header/custom_header_test.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index 66c6d7d75b8a..55fd520386b9 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -45,7 +45,6 @@ TEST_F(CustomHeaderTest, Detection) { const auto& reject_options = result.reject_options.value(); EXPECT_EQ(reject_options.response_code, Http::Code::Unauthorized); EXPECT_EQ(reject_options.body, "detection failed"); - EXPECT_EQ(reject_options.details, "rejecting because detection failed"); } // Bad IP in the header. @@ -61,7 +60,6 @@ TEST_F(CustomHeaderTest, Detection) { const auto& reject_options = result.reject_options.value(); EXPECT_EQ(reject_options.response_code, Http::Code::Unauthorized); EXPECT_EQ(reject_options.body, "detection failed"); - EXPECT_EQ(reject_options.details, "rejecting because detection failed"); } // Good IP. From 99bd132d64644ca202878cde78ef686e63a74515 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 6 Apr 2021 10:28:02 -0400 Subject: [PATCH 056/100] Fix Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 64 +++++++++---------- .../v4alpha/http_connection_manager.proto | 64 +++++++++---------- .../v3/http_connection_manager.proto | 64 +++++++++---------- .../v4alpha/http_connection_manager.proto | 64 +++++++++---------- 4 files changed, 128 insertions(+), 128 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 6413170db2a0..f34b5ef5790f 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -35,7 +35,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 45] +// [#next-free-field: 46] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"; @@ -486,6 +486,37 @@ message HttpConnectionManager { uint32 xff_num_trusted_hops = 19 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + // The configuration for the original-IP detection extensions. + // + // By default, when the :ref:`use_remote_address + // ` + // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header + // and the deprecated :ref:`xff_num_trusted_hops + // ` + // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops + // ` + // is removed, leaving this field empty will retain the default behavior when that field is unset. See + // the :ref:`xff extension ` for how to + // configure xff_num_trusted_hops when using extensions. + // + // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // header doesn't necessarily work for all network configurations. For instance, + // if the number of trusted hops isn't consistent for requests flowing into + // Envoy this mechanism cannot be used reliably. For such cases, the following + // option allows for a list of custom extensions to be provided. + // + // When configured the extensions will be called along with the request headers + // and information about the downstream connection, such as direct connected address, + // when the HCM needs to populate the final remote address. Each extension will then rely + // on these parameters to decide the value of the request's final remote address. + // If an extension fails to detect the original IP address and isn't configured to reject + // the request when this happens, the HCM will then try the remaining configured extensions + // until one succeeds or the request is rejected. If the request isn't rejected nor any extension + // succeeds, the HCM will fallback to using the remote address. + // + // [#extension-category: envoy.http.original_ip_detection] + repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 45; + // Configures what network addresses are considered internal for stats and header sanitation // purposes. If unspecified, only RFC1918 IP addresses will be considered internal. // See the documentation for :ref:`config_http_conn_man_headers_x-envoy-internal` for more @@ -651,37 +682,6 @@ message HttpConnectionManager { // ` // for details. PathNormalizationOptions path_normalization_options = 43; - - // The configuration for the original-IP detection extensions. - // - // By default, when the :ref:`use_remote_address - // ` - // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the deprecated :ref:`xff_num_trusted_hops - // ` - // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops - // ` - // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to - // configure xff_num_trusted_hops when using extensions. - // - // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` - // header doesn't necessarily work for all network configurations. For instance, - // if the number of trusted hops isn't consistent for requests flowing into - // Envoy this mechanism cannot be used reliably. For such cases, the following - // option allows for a list of custom extensions to be provided. - // - // When configured the extensions will be called along with the request headers - // and information about the downstream connection, such as direct connected address, - // when the HCM needs to populate the final remote address. Each extension will then rely - // on these parameters to decide the value of the request's final remote address. - // If an extension fails to detect the original IP address and isn't configured to reject - // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. If the request isn't rejected nor any extension - // succeeds, the HCM will fallback to using the remote address. - // - // [#extension-category: envoy.http.original_ip_detection] - repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 44; } // The configuration to customize local reply returned by Envoy. diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index c8359e416d38..42e234b1d084 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -33,7 +33,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 45] +// [#next-free-field: 46] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"; @@ -465,6 +465,37 @@ message HttpConnectionManager { google.protobuf.BoolValue use_remote_address = 14 [(udpa.annotations.security).configure_for_untrusted_downstream = true]; + // The configuration for the original-IP detection extensions. + // + // By default, when the :ref:`use_remote_address + // ` + // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header + // and the deprecated :ref:`xff_num_trusted_hops + // ` + // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops + // ` + // is removed, leaving this field empty will retain the default behavior when that field is unset. See + // the :ref:`xff extension ` for how to + // configure xff_num_trusted_hops when using extensions. + // + // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // header doesn't necessarily work for all network configurations. For instance, + // if the number of trusted hops isn't consistent for requests flowing into + // Envoy this mechanism cannot be used reliably. For such cases, the following + // option allows for a list of custom extensions to be provided. + // + // When configured the extensions will be called along with the request headers + // and information about the downstream connection, such as direct connected address, + // when the HCM needs to populate the final remote address. Each extension will then rely + // on these parameters to decide the value of the request's final remote address. + // If an extension fails to detect the original IP address and isn't configured to reject + // the request when this happens, the HCM will then try the remaining configured extensions + // until one succeeds or the request is rejected. If the request isn't rejected nor any extension + // succeeds, the HCM will fallback to using the remote address. + // + // [#extension-category: envoy.http.original_ip_detection] + repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 45; + // Configures what network addresses are considered internal for stats and header sanitation // purposes. If unspecified, only RFC1918 IP addresses will be considered internal. // See the documentation for :ref:`config_http_conn_man_headers_x-envoy-internal` for more @@ -629,37 +660,6 @@ message HttpConnectionManager { // ` // for details. PathNormalizationOptions path_normalization_options = 43; - - // The configuration for the original-IP detection extensions. - // - // By default, when the :ref:`use_remote_address - // ` - // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the deprecated :ref:`xff_num_trusted_hops - // ` - // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops - // ` - // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to - // configure xff_num_trusted_hops when using extensions. - // - // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` - // header doesn't necessarily work for all network configurations. For instance, - // if the number of trusted hops isn't consistent for requests flowing into - // Envoy this mechanism cannot be used reliably. For such cases, the following - // option allows for a list of custom extensions to be provided. - // - // When configured the extensions will be called along with the request headers - // and information about the downstream connection, such as direct connected address, - // when the HCM needs to populate the final remote address. Each extension will then rely - // on these parameters to decide the value of the request's final remote address. - // If an extension fails to detect the original IP address and isn't configured to reject - // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. If the request isn't rejected nor any extension - // succeeds, the HCM will fallback to using the remote address. - // - // [#extension-category: envoy.http.original_ip_detection] - repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 44; } // The configuration to customize local reply returned by Envoy. diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index f2c18bc7381e..b89d3820ebcf 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -36,7 +36,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 45] +// [#next-free-field: 46] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"; @@ -491,6 +491,37 @@ message HttpConnectionManager { uint32 xff_num_trusted_hops = 19 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + // The configuration for the original-IP detection extensions. + // + // By default, when the :ref:`use_remote_address + // ` + // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header + // and the deprecated :ref:`xff_num_trusted_hops + // ` + // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops + // ` + // is removed, leaving this field empty will retain the default behavior when that field is unset. See + // the :ref:`xff extension ` for how to + // configure xff_num_trusted_hops when using extensions. + // + // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // header doesn't necessarily work for all network configurations. For instance, + // if the number of trusted hops isn't consistent for requests flowing into + // Envoy this mechanism cannot be used reliably. For such cases, the following + // option allows for a list of custom extensions to be provided. + // + // When configured the extensions will be called along with the request headers + // and information about the downstream connection, such as direct connected address, + // when the HCM needs to populate the final remote address. Each extension will then rely + // on these parameters to decide the value of the request's final remote address. + // If an extension fails to detect the original IP address and isn't configured to reject + // the request when this happens, the HCM will then try the remaining configured extensions + // until one succeeds or the request is rejected. If the request isn't rejected nor any extension + // succeeds, the HCM will fallback to using the remote address. + // + // [#extension-category: envoy.http.original_ip_detection] + repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 45; + // Configures what network addresses are considered internal for stats and header sanitation // purposes. If unspecified, only RFC1918 IP addresses will be considered internal. // See the documentation for :ref:`config_http_conn_man_headers_x-envoy-internal` for more @@ -657,37 +688,6 @@ message HttpConnectionManager { // for details. PathNormalizationOptions path_normalization_options = 43; - // The configuration for the original-IP detection extensions. - // - // By default, when the :ref:`use_remote_address - // ` - // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the deprecated :ref:`xff_num_trusted_hops - // ` - // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops - // ` - // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to - // configure xff_num_trusted_hops when using extensions. - // - // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` - // header doesn't necessarily work for all network configurations. For instance, - // if the number of trusted hops isn't consistent for requests flowing into - // Envoy this mechanism cannot be used reliably. For such cases, the following - // option allows for a list of custom extensions to be provided. - // - // When configured the extensions will be called along with the request headers - // and information about the downstream connection, such as direct connected address, - // when the HCM needs to populate the final remote address. Each extension will then rely - // on these parameters to decide the value of the request's final remote address. - // If an extension fails to detect the original IP address and isn't configured to reject - // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. If the request isn't rejected nor any extension - // succeeds, the HCM will fallback to using the remote address. - // - // [#extension-category: envoy.http.original_ip_detection] - repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 44; - google.protobuf.Duration hidden_envoy_deprecated_idle_timeout = 11 [ deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0", diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 7bfde7be2ded..c49f9cbc4149 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -34,7 +34,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 45] +// [#next-free-field: 46] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"; @@ -489,6 +489,37 @@ message HttpConnectionManager { uint32 hidden_envoy_deprecated_xff_num_trusted_hops = 19 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; + // The configuration for the original-IP detection extensions. + // + // By default, when the :ref:`use_remote_address + // ` + // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header + // and the deprecated :ref:`xff_num_trusted_hops + // ` + // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops + // ` + // is removed, leaving this field empty will retain the default behavior when that field is unset. See + // the :ref:`xff extension ` for how to + // configure xff_num_trusted_hops when using extensions. + // + // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` + // header doesn't necessarily work for all network configurations. For instance, + // if the number of trusted hops isn't consistent for requests flowing into + // Envoy this mechanism cannot be used reliably. For such cases, the following + // option allows for a list of custom extensions to be provided. + // + // When configured the extensions will be called along with the request headers + // and information about the downstream connection, such as direct connected address, + // when the HCM needs to populate the final remote address. Each extension will then rely + // on these parameters to decide the value of the request's final remote address. + // If an extension fails to detect the original IP address and isn't configured to reject + // the request when this happens, the HCM will then try the remaining configured extensions + // until one succeeds or the request is rejected. If the request isn't rejected nor any extension + // succeeds, the HCM will fallback to using the remote address. + // + // [#extension-category: envoy.http.original_ip_detection] + repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 45; + // Configures what network addresses are considered internal for stats and header sanitation // purposes. If unspecified, only RFC1918 IP addresses will be considered internal. // See the documentation for :ref:`config_http_conn_man_headers_x-envoy-internal` for more @@ -653,37 +684,6 @@ message HttpConnectionManager { // ` // for details. PathNormalizationOptions path_normalization_options = 43; - - // The configuration for the original-IP detection extensions. - // - // By default, when the :ref:`use_remote_address - // ` - // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the deprecated :ref:`xff_num_trusted_hops - // ` - // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops - // ` - // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to - // configure xff_num_trusted_hops when using extensions. - // - // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` - // header doesn't necessarily work for all network configurations. For instance, - // if the number of trusted hops isn't consistent for requests flowing into - // Envoy this mechanism cannot be used reliably. For such cases, the following - // option allows for a list of custom extensions to be provided. - // - // When configured the extensions will be called along with the request headers - // and information about the downstream connection, such as direct connected address, - // when the HCM needs to populate the final remote address. Each extension will then rely - // on these parameters to decide the value of the request's final remote address. - // If an extension fails to detect the original IP address and isn't configured to reject - // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. If the request isn't rejected nor any extension - // succeeds, the HCM will fallback to using the remote address. - // - // [#extension-category: envoy.http.original_ip_detection] - repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 44; } // The configuration to customize local reply returned by Envoy. From ea48936dba244b108b9159cf21ae86188d105694 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 6 Apr 2021 12:06:16 -0400 Subject: [PATCH 057/100] Fix test Signed-off-by: Raul Gutierrez Segales --- test/common/http/conn_manager_impl_test_2.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/common/http/conn_manager_impl_test_2.cc b/test/common/http/conn_manager_impl_test_2.cc index 09214eafe374..a91150ab041e 100644 --- a/test/common/http/conn_manager_impl_test_2.cc +++ b/test/common/http/conn_manager_impl_test_2.cc @@ -2985,8 +2985,7 @@ TEST_F(HttpConnectionManagerImplDeathTest, InvalidConnectionManagerConfig) { } TEST_F(HttpConnectionManagerImplTest, RequestRejectedViaIPDetection) { - OriginalIPRejectRequestOptions reject_options = {Http::Code::Forbidden, "ip detection failed", - "ip detection failed"}; + OriginalIPRejectRequestOptions reject_options = {Http::Code::Forbidden, "ip detection failed"}; auto extension = std::make_shared( "x-ip", reject_options); From a823d949eff55345d43fc9267f2d47da4f12e7af Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 7 Apr 2021 09:08:44 -0400 Subject: [PATCH 058/100] Address latest batch of comments Left a comment/TODO about the proper protobuf type the createExtension() method should receive. Signed-off-by: Raul Gutierrez Segales --- include/envoy/http/original_ip_detection.h | 5 ++++- .../network/http_connection_manager/config.cc | 11 ++++------ .../original_ip_detection/custom_header/BUILD | 1 + .../custom_header/config.cc | 19 ++++++++++++----- .../custom_header/config.h | 3 ++- .../custom_header/custom_header.cc | 8 +------ .../custom_header/custom_header.h | 8 +++++++ .../original_ip_detection/xff/BUILD | 1 + .../original_ip_detection/xff/config.cc | 16 +++++++++++--- .../original_ip_detection/xff/config.h | 3 ++- .../original_ip_detection/custom_header/BUILD | 1 + .../custom_header/config_test.cc | 21 +++++++++++-------- .../original_ip_detection/xff/BUILD | 1 + .../original_ip_detection/xff/config_test.cc | 20 +++++++++++------- 14 files changed, 76 insertions(+), 42 deletions(-) diff --git a/include/envoy/http/original_ip_detection.h b/include/envoy/http/original_ip_detection.h index 0c9972aa824e..27d52d59e2f2 100644 --- a/include/envoy/http/original_ip_detection.h +++ b/include/envoy/http/original_ip_detection.h @@ -8,6 +8,7 @@ #include "envoy/http/codes.h" #include "envoy/http/header_map.h" #include "envoy/network/address.h" +#include "envoy/server/factory_context.h" namespace Envoy { namespace Http { @@ -76,7 +77,9 @@ class OriginalIPDetectionFactory : public Envoy::Config::TypedFactory { * @param config supplies the configuration for the original IP detection extension. * @return OriginalIPDetectionSharedPtr the extension instance. */ - virtual OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message& config) const PURE; + virtual OriginalIPDetectionSharedPtr + createExtension(const Protobuf::Message& config, + Server::Configuration::FactoryContext& context) PURE; std::string category() const override { return "envoy.http.original_ip_detection"; } }; diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 2fa4874ea8e1..9edb24103255 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -303,18 +303,15 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( const auto& ip_detection_extensions = config.original_ip_detection_extensions(); if (!ip_detection_extensions.empty()) { original_ip_detection_extensions_.reserve(ip_detection_extensions.size()); - for (const auto& typed_config : ip_detection_extensions) { + for (const auto& extension_config : ip_detection_extensions) { auto* factory = - Envoy::Config::Utility::getFactory(typed_config); + Envoy::Config::Utility::getFactory(extension_config); if (!factory) { throw EnvoyException("Original IP detection extension not found"); } - ProtobufTypes::MessagePtr message = factory->createEmptyConfigProto(); - Envoy::Config::Utility::translateOpaqueConfig(typed_config.typed_config(), - ProtobufWkt::Struct::default_instance(), - context_.messageValidationVisitor(), *message); - original_ip_detection_extensions_.push_back(factory->createExtension(*message)); + original_ip_detection_extensions_.push_back( + factory->createExtension(extension_config, context_)); } } else { original_ip_detection_extensions_.push_back( diff --git a/source/extensions/original_ip_detection/custom_header/BUILD b/source/extensions/original_ip_detection/custom_header/BUILD index d31275894ed0..f9a0936c5e71 100644 --- a/source/extensions/original_ip_detection/custom_header/BUILD +++ b/source/extensions/original_ip_detection/custom_header/BUILD @@ -34,6 +34,7 @@ envoy_cc_extension( ":custom_header_lib", "//include/envoy/http:original_ip_detection_interface", "//include/envoy/registry", + "//source/common/config:utility_lib", "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/original_ip_detection/custom_header/config.cc b/source/extensions/original_ip_detection/custom_header/config.cc index 6a3d7e22021d..23cd7725b95a 100644 --- a/source/extensions/original_ip_detection/custom_header/config.cc +++ b/source/extensions/original_ip_detection/custom_header/config.cc @@ -5,6 +5,8 @@ #include "envoy/http/original_ip_detection.h" #include "envoy/registry/registry.h" +#include "common/config/utility.h" + #include "extensions/original_ip_detection/custom_header/custom_header.h" namespace Envoy { @@ -13,11 +15,18 @@ namespace OriginalIPDetection { namespace CustomHeader { Http::OriginalIPDetectionSharedPtr -CustomHeaderIPDetectionFactory::createExtension(const Protobuf::Message& message) const { - return std::make_shared( - dynamic_cast< - const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig&>( - message)); +CustomHeaderIPDetectionFactory::createExtension(const Protobuf::Message& message, + Server::Configuration::FactoryContext& context) { + // TODO(rgs1): change message's type to TypedExtensionConfig and use translateAnyToFactoryConfig() + // here along with downcastAndValidate(). + auto config = createEmptyConfigProto(); + Envoy::Config::Utility::translateOpaqueConfig(dynamic_cast(message), + ProtobufWkt::Struct::default_instance(), + context.messageValidationVisitor(), *config); + const auto& custom_header_config = dynamic_cast< + const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig&>( + *config); + return std::make_shared(custom_header_config); } REGISTER_FACTORY(CustomHeaderIPDetectionFactory, Http::OriginalIPDetectionFactory); diff --git a/source/extensions/original_ip_detection/custom_header/config.h b/source/extensions/original_ip_detection/custom_header/config.h index 57655accd174..18a49a2734d2 100644 --- a/source/extensions/original_ip_detection/custom_header/config.h +++ b/source/extensions/original_ip_detection/custom_header/config.h @@ -17,7 +17,8 @@ namespace CustomHeader { class CustomHeaderIPDetectionFactory : public Http::OriginalIPDetectionFactory { public: Http::OriginalIPDetectionSharedPtr - createExtension(const Protobuf::Message& message) const override; + createExtension(const Protobuf::Message& message, + Server::Configuration::FactoryContext& context) override; ProtobufTypes::MessagePtr createEmptyConfigProto() override { return std::make_unique< diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/original_ip_detection/custom_header/custom_header.cc index 7b134efea8bb..1612cdb4db44 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/original_ip_detection/custom_header/custom_header.cc @@ -11,14 +11,8 @@ CustomHeaderIPDetection::CustomHeaderIPDetection( const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& config) : header_name_(config.header_name()), allow_trusted_address_checks_(config.allow_extension_to_set_address_as_trusted()) { - if (config.has_reject_options()) { - Http::Code reject_code = Http::Code::Forbidden; - - if (config.reject_options().has_status_on_error()) { - reject_code = static_cast(config.reject_options().status_on_error().code()); - } - + const auto reject_code = toErrorCode(config.reject_options().status_on_error().code()); reject_options_ = {reject_code, config.reject_options().body_on_error()}; } } diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.h b/source/extensions/original_ip_detection/custom_header/custom_header.h index bdb22baebc32..1c81a451d21d 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.h +++ b/source/extensions/original_ip_detection/custom_header/custom_header.h @@ -24,6 +24,14 @@ class CustomHeaderIPDetection : public Http::OriginalIPDetection { Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override; private: + static Http::Code toErrorCode(uint64_t status) { + const auto code = static_cast(status); + if (code >= Http::Code::BadRequest && code <= Http::Code::NetworkAuthenticationRequired) { + return code; + } + return Http::Code::Forbidden; + } + Http::LowerCaseString header_name_; bool allow_trusted_address_checks_{false}; absl::optional reject_options_{absl::nullopt}; diff --git a/source/extensions/original_ip_detection/xff/BUILD b/source/extensions/original_ip_detection/xff/BUILD index 8728d8a4c0e7..51c1cf44e632 100644 --- a/source/extensions/original_ip_detection/xff/BUILD +++ b/source/extensions/original_ip_detection/xff/BUILD @@ -34,6 +34,7 @@ envoy_cc_extension( ":xff_lib", "//include/envoy/http:original_ip_detection_interface", "//include/envoy/registry", + "//source/common/config:utility_lib", "@envoy_api//envoy/extensions/original_ip_detection/xff/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/original_ip_detection/xff/config.cc b/source/extensions/original_ip_detection/xff/config.cc index 9b0f77a2ae9a..c2b1a50d645a 100644 --- a/source/extensions/original_ip_detection/xff/config.cc +++ b/source/extensions/original_ip_detection/xff/config.cc @@ -5,6 +5,8 @@ #include "envoy/http/original_ip_detection.h" #include "envoy/registry/registry.h" +#include "common/config/utility.h" + #include "extensions/original_ip_detection/xff/xff.h" namespace Envoy { @@ -13,9 +15,17 @@ namespace OriginalIPDetection { namespace Xff { Http::OriginalIPDetectionSharedPtr -XffIPDetectionFactory::createExtension(const Protobuf::Message& message) const { - return std::make_shared( - dynamic_cast(message)); +XffIPDetectionFactory::createExtension(const Protobuf::Message& message, + Server::Configuration::FactoryContext& context) { + // TODO(rgs1): change message's type to TypedExtensionConfig and use translateAnyToFactoryConfig() + // here along with downcastAndValidate(). + auto config = createEmptyConfigProto(); + Envoy::Config::Utility::translateOpaqueConfig(dynamic_cast(message), + ProtobufWkt::Struct::default_instance(), + context.messageValidationVisitor(), *config); + const auto& xff_config = + dynamic_cast(*config); + return std::make_shared(xff_config); } REGISTER_FACTORY(XffIPDetectionFactory, Http::OriginalIPDetectionFactory); diff --git a/source/extensions/original_ip_detection/xff/config.h b/source/extensions/original_ip_detection/xff/config.h index 4046c143c041..d632e18e94c2 100644 --- a/source/extensions/original_ip_detection/xff/config.h +++ b/source/extensions/original_ip_detection/xff/config.h @@ -17,7 +17,8 @@ namespace Xff { class XffIPDetectionFactory : public Http::OriginalIPDetectionFactory { public: Http::OriginalIPDetectionSharedPtr - createExtension(const Protobuf::Message& message) const override; + createExtension(const Protobuf::Message& message, + Server::Configuration::FactoryContext& context) override; ProtobufTypes::MessagePtr createEmptyConfigProto() override { return std::make_unique(); diff --git a/test/extensions/original_ip_detection/custom_header/BUILD b/test/extensions/original_ip_detection/custom_header/BUILD index 6b18b282142d..5963aaa97afe 100644 --- a/test/extensions/original_ip_detection/custom_header/BUILD +++ b/test/extensions/original_ip_detection/custom_header/BUILD @@ -31,6 +31,7 @@ envoy_extension_cc_test( "//include/envoy/registry", "//source/extensions/original_ip_detection/custom_header:config", "//source/extensions/original_ip_detection/custom_header:custom_header_lib", + "//test/mocks/server:factory_context_mocks", "//test/test_common:utility_lib", "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", ], diff --git a/test/extensions/original_ip_detection/custom_header/config_test.cc b/test/extensions/original_ip_detection/custom_header/config_test.cc index 51d86884fb22..6b9dc6299fe9 100644 --- a/test/extensions/original_ip_detection/custom_header/config_test.cc +++ b/test/extensions/original_ip_detection/custom_header/config_test.cc @@ -3,6 +3,7 @@ #include "extensions/original_ip_detection/custom_header/config.h" +#include "test/mocks/server/factory_context.h" #include "test/test_common/utility.h" #include "gtest/gtest.h" @@ -17,15 +18,17 @@ TEST(CustomHeaderFactoryTest, Basic) { "envoy.http.original_ip_detection.custom_header"); ASSERT_NE(factory, nullptr); - auto empty = factory->createEmptyConfigProto(); - EXPECT_NE(empty, nullptr); - - auto config = *dynamic_cast< - envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig*>( - empty.get()); - config.set_header_name("x-real-ip"); - - EXPECT_NE(factory->createExtension(config), nullptr); + envoy::config::core::v3::TypedExtensionConfig typed_config; + const std::string yaml = R"EOF( + name: envoy.formatter.TestFormatter + typed_config: + "@type": type.googleapis.com/envoy.extensions.original_ip_detection.custom_header.v3.CustomHeaderConfig + header_name: x-real-ip +)EOF"; + TestUtility::loadFromYaml(yaml, typed_config); + + NiceMock context; + EXPECT_NE(factory->createExtension(typed_config.typed_config(), context), nullptr); } } // namespace CustomHeader diff --git a/test/extensions/original_ip_detection/xff/BUILD b/test/extensions/original_ip_detection/xff/BUILD index f66b1cb3a389..910320bc6473 100644 --- a/test/extensions/original_ip_detection/xff/BUILD +++ b/test/extensions/original_ip_detection/xff/BUILD @@ -31,6 +31,7 @@ envoy_extension_cc_test( "//include/envoy/registry", "//source/extensions/original_ip_detection/xff:config", "//source/extensions/original_ip_detection/xff:xff_lib", + "//test/mocks/server:factory_context_mocks", "//test/test_common:utility_lib", "@envoy_api//envoy/extensions/original_ip_detection/xff/v3:pkg_cc_proto", ], diff --git a/test/extensions/original_ip_detection/xff/config_test.cc b/test/extensions/original_ip_detection/xff/config_test.cc index 7d06984dde82..9ea824801e55 100644 --- a/test/extensions/original_ip_detection/xff/config_test.cc +++ b/test/extensions/original_ip_detection/xff/config_test.cc @@ -3,6 +3,7 @@ #include "extensions/original_ip_detection/xff/config.h" +#include "test/mocks/server/factory_context.h" #include "test/test_common/utility.h" #include "gtest/gtest.h" @@ -17,14 +18,17 @@ TEST(CustomHeaderFactoryTest, Basic) { "envoy.http.original_ip_detection.xff"); ASSERT_NE(factory, nullptr); - auto empty = factory->createEmptyConfigProto(); - EXPECT_NE(empty, nullptr); - - auto config = - *dynamic_cast(empty.get()); - config.set_xff_num_trusted_hops(1); - - EXPECT_NE(factory->createExtension(config), nullptr); + envoy::config::core::v3::TypedExtensionConfig typed_config; + const std::string yaml = R"EOF( + name: envoy.formatter.TestFormatter + typed_config: + "@type": type.googleapis.com/envoy.extensions.original_ip_detection.xff.v3.XffConfig + xff_num_trusted_hops: 1 +)EOF"; + TestUtility::loadFromYaml(yaml, typed_config); + + NiceMock context; + EXPECT_NE(factory->createExtension(typed_config.typed_config(), context), nullptr); } } // namespace Xff From e4b99bc6a8fc59a351c0e376c68be61c08ee9c88 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 7 Apr 2021 09:39:08 -0400 Subject: [PATCH 059/100] Test for createExtension() returning nullptr Also, the HCM test broke in my last change so this fixes it. Signed-off-by: Raul Gutierrez Segales --- .../network/http_connection_manager/config.cc | 7 +++- .../http_connection_manager/config_test.cc | 40 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 9edb24103255..45dee336e539 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -310,8 +310,11 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( throw EnvoyException("Original IP detection extension not found"); } - original_ip_detection_extensions_.push_back( - factory->createExtension(extension_config, context_)); + auto extension = factory->createExtension(extension_config.typed_config(), context_); + if (!extension) { + throw EnvoyException("Original IP detection extension could not be created"); + } + original_ip_detection_extensions_.push_back(extension); } } else { original_ip_detection_extensions_.push_back( diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index c3f449a16e8e..570172cb4d0e 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -1790,6 +1790,46 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { "Original IP detection extension not found"); } +namespace { + +class OriginalIPDetectionExtensionNotCreatedFactory : public Http::OriginalIPDetectionFactory { +public: + Http::OriginalIPDetectionSharedPtr + createExtension(const Protobuf::Message&, Server::Configuration::FactoryContext&) override { + return nullptr; + } + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return std::make_unique(); + } + + std::string name() const override { + return "envoy.http.original_ip_detection.OriginalIPDetectionExtensionNotCreated"; + } +}; + +} // namespace + +TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtensionNotCreated) { + OriginalIPDetectionExtensionNotCreatedFactory factory; + Registry::InjectFactory registration(factory); + + const std::string yaml_string = R"EOF( + stat_prefix: ingress_http + route_config: + name: local_route + original_ip_detection_extensions: + - name: envoy.http.ip_detection.OriginalIPDetectionExtensionNotCreated + typed_config: + "@type": type.googleapis.com/google.protobuf.UInt32Value + http_filters: + - name: envoy.filters.http.router + )EOF"; + + EXPECT_THROW_WITH_REGEX(createHttpConnectionManagerConfig(yaml_string), EnvoyException, + "Original IP detection extension could not be created"); +} + TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { const std::string yaml_string = R"EOF( stat_prefix: ingress_http From f8df690b8bb5c7ef1b03bfb4b7599e7d62433f51 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 7 Apr 2021 10:04:13 -0400 Subject: [PATCH 060/100] Add extension name to the exception message Signed-off-by: Raul Gutierrez Segales --- .../filters/network/http_connection_manager/config.cc | 6 ++++-- .../filters/network/http_connection_manager/config_test.cc | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 45dee336e539..73b2f6940987 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -307,12 +307,14 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( auto* factory = Envoy::Config::Utility::getFactory(extension_config); if (!factory) { - throw EnvoyException("Original IP detection extension not found"); + throw EnvoyException(fmt::format("Original IP detection extension not found: '{}'", + extension_config.name())); } auto extension = factory->createExtension(extension_config.typed_config(), context_); if (!extension) { - throw EnvoyException("Original IP detection extension could not be created"); + throw EnvoyException(fmt::format( + "Original IP detection extension could not be created: '{}'", extension_config.name())); } original_ip_detection_extensions_.push_back(extension); } diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 570172cb4d0e..63d007289220 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -1787,7 +1787,8 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { )EOF"; EXPECT_THROW_WITH_REGEX(createHttpConnectionManagerConfig(yaml_string), EnvoyException, - "Original IP detection extension not found"); + "Original IP detection extension not found: " + "'envoy.ip_detection.UnknownOriginalIPDetectionExtension'"); } namespace { @@ -1827,7 +1828,8 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtensionNotCreated) )EOF"; EXPECT_THROW_WITH_REGEX(createHttpConnectionManagerConfig(yaml_string), EnvoyException, - "Original IP detection extension could not be created"); + "Original IP detection extension could not be created: " + "'envoy.http.ip_detection.OriginalIPDetectionExtensionNotCreated'"); } TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { From 7ce524ef172851734cee88f8fc425e54d30eb436 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 7 Apr 2021 12:49:01 -0400 Subject: [PATCH 061/100] Test case for v6 Signed-off-by: Raul Gutierrez Segales --- .../custom_header/custom_header_test.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index 55fd520386b9..237373891688 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -62,7 +62,7 @@ TEST_F(CustomHeaderTest, Detection) { EXPECT_EQ(reject_options.body, "detection failed"); } - // Good IP. + // Good IPv4. { Http::TestRequestHeaderMapImpl headers{{"x-real-ip", "1.2.3.4"}}; Http::OriginalIPDetectionParams params = {headers, nullptr}; @@ -72,6 +72,17 @@ TEST_F(CustomHeaderTest, Detection) { EXPECT_TRUE(result.allow_trusted_address_checks); EXPECT_FALSE(result.reject_options.has_value()); } + + // Good IPv6. + { + Http::TestRequestHeaderMapImpl headers{{"x-real-ip", "fc00::1"}}; + Http::OriginalIPDetectionParams params = {headers, nullptr}; + auto result = custom_header_extension_->detect(params); + + EXPECT_EQ("[fc00::1]:0", result.detected_remote_address->asString()); + EXPECT_TRUE(result.allow_trusted_address_checks); + EXPECT_FALSE(result.reject_options.has_value()); + } } } // namespace CustomHeader From bd05e1a6fbabda0846098f68439038cdcda961c5 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 7 Apr 2021 12:56:54 -0400 Subject: [PATCH 062/100] clang-tidy Signed-off-by: Raul Gutierrez Segales --- include/envoy/http/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/include/envoy/http/BUILD b/include/envoy/http/BUILD index a95eb15e4847..a37ddf1b1e76 100644 --- a/include/envoy/http/BUILD +++ b/include/envoy/http/BUILD @@ -160,5 +160,6 @@ envoy_cc_library( ":header_map_interface", "//include/envoy/config:typed_config_interface", "//include/envoy/network:address_interface", + "//include/envoy/server:factory_context_interface", ], ) From 95779afb08aee7a71f873302bd242aebc603a988 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 7 Apr 2021 13:11:25 -0400 Subject: [PATCH 063/100] custom header: improve coverage Signed-off-by: Raul Gutierrez Segales --- .../custom_header/custom_header_test.cc | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc index 237373891688..6a0e0cc2bab6 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/original_ip_detection/custom_header/custom_header_test.cc @@ -15,7 +15,9 @@ namespace CustomHeader { class CustomHeaderTest : public testing::Test { protected: - CustomHeaderTest() { + CustomHeaderTest() { configure(); } + + void configure(envoy::type::v3::StatusCode code = envoy::type::v3::StatusCode::Unauthorized) { envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; config.set_header_name("x-real-ip"); config.set_allow_extension_to_set_address_as_trusted(true); @@ -23,7 +25,7 @@ class CustomHeaderTest : public testing::Test { auto* reject_options = config.mutable_reject_options(); reject_options->set_body_on_error("detection failed"); auto* status_on_error = reject_options->mutable_status_on_error(); - status_on_error->set_code(envoy::type::v3::StatusCode::Unauthorized); + status_on_error->set_code(code); custom_header_extension_ = std::make_shared(config); } @@ -85,6 +87,22 @@ TEST_F(CustomHeaderTest, Detection) { } } +TEST_F(CustomHeaderTest, FallbacksToDefaultResponseCode) { + configure(envoy::type::v3::StatusCode::OK); + + Http::TestRequestHeaderMapImpl headers{{"x-other", "abc"}}; + Http::OriginalIPDetectionParams params = {headers, nullptr}; + auto result = custom_header_extension_->detect(params); + + EXPECT_EQ(nullptr, result.detected_remote_address); + EXPECT_FALSE(result.allow_trusted_address_checks); + EXPECT_TRUE(result.reject_options.has_value()); + + const auto& reject_options = result.reject_options.value(); + EXPECT_EQ(reject_options.response_code, Http::Code::Forbidden); + EXPECT_EQ(reject_options.body, "detection failed"); +} + } // namespace CustomHeader } // namespace OriginalIPDetection } // namespace Extensions From 516de724712f14c5cd88c4a61deb5e0a40ea3279 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 7 Apr 2021 18:46:43 -0400 Subject: [PATCH 064/100] Set the custom header extension to out by default Signed-off-by: Raul Gutierrez Segales --- source/extensions/extensions_build_config.bzl | 1 + source/extensions/original_ip_detection/custom_header/BUILD | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index 62bd32f8d459..97e0491b86c7 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -274,6 +274,7 @@ EXTENSIONS = { # Original IP detection # + # Disabled by default "envoy.http.original_ip_detection.custom_header": "//source/extensions/original_ip_detection/custom_header:config", "envoy.http.original_ip_detection.xff": "//source/extensions/original_ip_detection/xff:config", diff --git a/source/extensions/original_ip_detection/custom_header/BUILD b/source/extensions/original_ip_detection/custom_header/BUILD index f9a0936c5e71..cb55be8e9fe6 100644 --- a/source/extensions/original_ip_detection/custom_header/BUILD +++ b/source/extensions/original_ip_detection/custom_header/BUILD @@ -7,7 +7,7 @@ load( licenses(["notice"]) # Apache 2 -envoy_extension_package() +envoy_extension_package(enabled_default = False) envoy_cc_library( name = "custom_header_lib", From 63a3987b402d2b96fef31ac5f554a7518150fd12 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 7 Apr 2021 20:28:10 -0400 Subject: [PATCH 065/100] Update headers.rst to reflect the use of IP detection extensions I probably still need to update the configuration examples in that file, otherwise they'll go stale soon. Signed-off-by: Raul Gutierrez Segales --- .../root/configuration/http/http_conn_man/headers.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/root/configuration/http/http_conn_man/headers.rst b/docs/root/configuration/http/http_conn_man/headers.rst index 110b9e15b7c3..67163047845e 100644 --- a/docs/root/configuration/http/http_conn_man/headers.rst +++ b/docs/root/configuration/http/http_conn_man/headers.rst @@ -189,7 +189,9 @@ Given an HTTP request that has traveled through a series of zero or more proxies Envoy, the trusted client address is the earliest source IP address that is known to be accurate. The source IP address of the immediate downstream node's connection to Envoy is trusted. XFF *sometimes* can be trusted. Malicious clients can forge XFF, but the last -address in XFF can be trusted if it was put there by a trusted proxy. +address in XFF can be trusted if it was put there by a trusted proxy. Alternatively, Envoy +supports :ref:`extensions ` +for determining the *trusted client address* or original IP address. Envoy's default rules for determining the trusted client address (*before* appending anything to XFF) are: @@ -200,8 +202,11 @@ to XFF) are: node's connection to Envoy. In an environment where there are one or more trusted proxies in front of an edge -Envoy instance, the *xff_num_trusted_hops* configuration option can be used to trust -additional addresses from XFF: +Envoy instance, the :ref:`XFF extension ` +can be configured via the :ref:`original_ip_detection_extensions field +` +to set the *xff_num_trusted_hops* option which controls the number of additional +addresses that are to be trusted: * If *use_remote_address* is false and *xff_num_trusted_hops* is set to a value *N* that is greater than zero, the trusted client address is the (N+1)th address from the right end From 305f2edc67834728fa0c1c1d303d8548055dbdb5 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 8 Apr 2021 13:07:46 -0400 Subject: [PATCH 066/100] extensions/ -> extensions/http/ Signed-off-by: Raul Gutierrez Segales --- CODEOWNERS | 4 +- api/BUILD | 4 +- .../v3/http_connection_manager.proto | 6 +-- .../v4alpha/http_connection_manager.proto | 2 +- .../custom_header/v3/BUILD | 0 .../custom_header/v3/custom_header.proto | 4 +- .../original_ip_detection/xff/v3/BUILD | 0 .../original_ip_detection/xff/v3/xff.proto | 4 +- api/versioning/BUILD | 4 +- docs/root/api-v3/config/config.rst | 2 +- .../original_ip_detection.rst | 2 +- .../http/http_conn_man/headers.rst | 2 +- .../other_features/ip_transparency.rst | 4 +- docs/root/version_history/current.rst | 4 +- generated_api_shadow/BUILD | 4 +- .../v3/http_connection_manager.proto | 6 +-- .../v4alpha/http_connection_manager.proto | 6 +-- .../custom_header/v3/BUILD | 0 .../custom_header/v3/custom_header.proto | 4 +- .../original_ip_detection/xff/v3/BUILD | 0 .../original_ip_detection/xff/v3/xff.proto | 4 +- source/extensions/extensions_build_config.bzl | 4 +- .../network/http_connection_manager/BUILD | 2 +- .../network/http_connection_manager/config.cc | 2 +- .../original_ip_detection/custom_header/BUILD | 4 +- .../custom_header/config.cc | 16 ++++--- .../custom_header/config.h | 10 ++-- .../custom_header/custom_header.cc | 13 +++-- .../custom_header/custom_header.h | 47 +++++++++++++++++++ .../original_ip_detection/xff/BUILD | 4 +- .../original_ip_detection/xff/config.cc | 17 ++++--- .../original_ip_detection/xff/config.h | 10 ++-- .../original_ip_detection/xff/xff.cc | 12 +++-- .../original_ip_detection/xff/xff.h | 11 +++-- .../custom_header/custom_header.h | 43 ----------------- test/common/http/BUILD | 8 ++-- test/common/http/conn_manager_impl_test_2.cc | 6 +-- .../http/conn_manager_impl_test_base.cc | 2 +- .../common/http/conn_manager_impl_test_base.h | 4 +- test/common/http/conn_manager_utility_test.cc | 13 +++-- .../network/http_connection_manager/BUILD | 4 +- .../http_connection_manager/config_test.cc | 17 +++---- .../original_ip_detection/custom_header/BUILD | 10 ++-- .../custom_header/config_test.cc | 8 ++-- .../custom_header/custom_header_test.cc | 34 +++++++------- .../original_ip_detection/xff/BUILD | 10 ++-- .../original_ip_detection/xff/config_test.cc | 8 ++-- .../original_ip_detection/xff/xff_test.cc | 16 ++++--- test/integration/BUILD | 6 +-- test/integration/header_integration_test.cc | 2 +- .../original_ip_detection_integration_test.cc | 5 +- 51 files changed, 223 insertions(+), 191 deletions(-) rename api/envoy/extensions/{ => http}/original_ip_detection/custom_header/v3/BUILD (100%) rename api/envoy/extensions/{ => http}/original_ip_detection/custom_header/v3/custom_header.proto (93%) rename api/envoy/extensions/{ => http}/original_ip_detection/xff/v3/BUILD (100%) rename {generated_api_shadow/envoy/extensions => api/envoy/extensions/http}/original_ip_detection/xff/v3/xff.proto (85%) rename docs/root/api-v3/config/{original_ip_detection => http}/original_ip_detection.rst (61%) rename generated_api_shadow/envoy/extensions/{ => http}/original_ip_detection/custom_header/v3/BUILD (100%) rename generated_api_shadow/envoy/extensions/{ => http}/original_ip_detection/custom_header/v3/custom_header.proto (93%) rename generated_api_shadow/envoy/extensions/{ => http}/original_ip_detection/xff/v3/BUILD (100%) rename {api/envoy/extensions => generated_api_shadow/envoy/extensions/http}/original_ip_detection/xff/v3/xff.proto (85%) rename source/extensions/{ => http}/original_ip_detection/custom_header/BUILD (83%) rename source/extensions/{ => http}/original_ip_detection/custom_header/config.cc (64%) rename source/extensions/{ => http}/original_ip_detection/custom_header/config.h (67%) rename source/extensions/{ => http}/original_ip_detection/custom_header/custom_header.cc (73%) create mode 100644 source/extensions/http/original_ip_detection/custom_header/custom_header.h rename source/extensions/{ => http}/original_ip_detection/xff/BUILD (84%) rename source/extensions/{ => http}/original_ip_detection/xff/config.cc (65%) rename source/extensions/{ => http}/original_ip_detection/xff/config.h (68%) rename source/extensions/{ => http}/original_ip_detection/xff/xff.cc (59%) rename source/extensions/{ => http}/original_ip_detection/xff/xff.h (52%) delete mode 100644 source/extensions/original_ip_detection/custom_header/custom_header.h rename test/extensions/{ => http}/original_ip_detection/custom_header/BUILD (64%) rename test/extensions/{ => http}/original_ip_detection/custom_header/config_test.cc (75%) rename test/extensions/{ => http}/original_ip_detection/custom_header/custom_header_test.cc (68%) rename test/extensions/{ => http}/original_ip_detection/xff/BUILD (66%) rename test/extensions/{ => http}/original_ip_detection/xff/config_test.cc (78%) rename test/extensions/{ => http}/original_ip_detection/xff/xff_test.cc (62%) diff --git a/CODEOWNERS b/CODEOWNERS index df50930a049a..acca337472f1 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -183,5 +183,5 @@ extensions/filters/http/oauth2 @rgs1 @derekargueta @snowp /*/extensions/filters/http/ext_authz @esmet @gsagula @dio /*/extensions/filters/network/ext_authz @esmet @gsagula @dio # Original IP detection -/*/extensions/original_ip_detection/custom_header @rgs1 @alyssawilk @antoniovicente -/*/extensions/original_ip_detection/xff @rgs1 @alyssawilk @antoniovicente +/*/extensions/http/original_ip_detection/custom_header @rgs1 @alyssawilk @antoniovicente +/*/extensions/http/original_ip_detection/xff @rgs1 @alyssawilk @antoniovicente diff --git a/api/BUILD b/api/BUILD index 6bc4b9563b55..38113f762fa5 100644 --- a/api/BUILD +++ b/api/BUILD @@ -243,14 +243,14 @@ proto_library( "//envoy/extensions/filters/udp/udp_proxy/v3:pkg", "//envoy/extensions/health_checkers/redis/v3:pkg", "//envoy/extensions/http/header_formatters/preserve_case/v3:pkg", + "//envoy/extensions/http/original_ip_detection/custom_header/v3:pkg", + "//envoy/extensions/http/original_ip_detection/xff/v3:pkg", "//envoy/extensions/internal_redirect/allow_listed_routes/v3:pkg", "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/matching/common_inputs/environment_variable/v3:pkg", "//envoy/extensions/matching/input_matchers/consistent_hashing/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", - "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", - "//envoy/extensions/original_ip_detection/xff/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/request_id/uuid/v3:pkg", "//envoy/extensions/resource_monitors/fixed_heap/v3:pkg", diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index f34b5ef5790f..3e31f3ad49ab 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -472,7 +472,7 @@ message HttpConnectionManager { // .. note:: // This field is deprecated and instead :ref:`original_ip_detection_extensions // ` - // should be used to configure the :ref:`xff extension ` + // should be used to configure the :ref:`xff extension ` // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. To replace // this field use a config like the following: // @@ -480,7 +480,7 @@ message HttpConnectionManager { // // original_ip_detection_extensions: // typed_config: - // "@type": type.googleapis.com/envoy.extensions.original_ip_detection.xff.v3.XffConfig + // "@type": type.googleapis.com/envoy.extensions.http.original_ip_detection.xff.v3.XffConfig // xff_num_trusted_hops: 1 // uint32 xff_num_trusted_hops = 19 @@ -496,7 +496,7 @@ message HttpConnectionManager { // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops // ` // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to + // the :ref:`xff extension ` for how to // configure xff_num_trusted_hops when using extensions. // // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 42e234b1d084..a70fe73b3c34 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -475,7 +475,7 @@ message HttpConnectionManager { // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops // ` // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to + // the :ref:`xff extension ` for how to // configure xff_num_trusted_hops when using extensions. // // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/BUILD similarity index 100% rename from api/envoy/extensions/original_ip_detection/custom_header/v3/BUILD rename to api/envoy/extensions/http/original_ip_detection/custom_header/v3/BUILD diff --git a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto similarity index 93% rename from api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto rename to api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 44907fcdd602..7b1d060e378c 100644 --- a/api/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -1,13 +1,13 @@ syntax = "proto3"; -package envoy.extensions.original_ip_detection.custom_header.v3; +package envoy.extensions.http.original_ip_detection.custom_header.v3; import "envoy/type/v3/http_status.proto"; import "udpa/annotations/status.proto"; import "validate/validate.proto"; -option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.custom_header.v3"; +option java_package = "io.envoyproxy.envoy.extensions.http.original_ip_detection.custom_header.v3"; option java_outer_classname = "CustomHeaderProto"; option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; diff --git a/api/envoy/extensions/original_ip_detection/xff/v3/BUILD b/api/envoy/extensions/http/original_ip_detection/xff/v3/BUILD similarity index 100% rename from api/envoy/extensions/original_ip_detection/xff/v3/BUILD rename to api/envoy/extensions/http/original_ip_detection/xff/v3/BUILD diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/api/envoy/extensions/http/original_ip_detection/xff/v3/xff.proto similarity index 85% rename from generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto rename to api/envoy/extensions/http/original_ip_detection/xff/v3/xff.proto index c5bd63cf00ab..6864788f9f18 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/api/envoy/extensions/http/original_ip_detection/xff/v3/xff.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -package envoy.extensions.original_ip_detection.xff.v3; +package envoy.extensions.http.original_ip_detection.xff.v3; import "udpa/annotations/status.proto"; -option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.xff.v3"; +option java_package = "io.envoyproxy.envoy.extensions.http.original_ip_detection.xff.v3"; option java_outer_classname = "XffProto"; option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; diff --git a/api/versioning/BUILD b/api/versioning/BUILD index 9abaf29f5453..0db13a17fb8b 100644 --- a/api/versioning/BUILD +++ b/api/versioning/BUILD @@ -126,14 +126,14 @@ proto_library( "//envoy/extensions/filters/udp/udp_proxy/v3:pkg", "//envoy/extensions/health_checkers/redis/v3:pkg", "//envoy/extensions/http/header_formatters/preserve_case/v3:pkg", + "//envoy/extensions/http/original_ip_detection/custom_header/v3:pkg", + "//envoy/extensions/http/original_ip_detection/xff/v3:pkg", "//envoy/extensions/internal_redirect/allow_listed_routes/v3:pkg", "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/matching/common_inputs/environment_variable/v3:pkg", "//envoy/extensions/matching/input_matchers/consistent_hashing/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", - "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", - "//envoy/extensions/original_ip_detection/xff/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/request_id/uuid/v3:pkg", "//envoy/extensions/resource_monitors/fixed_heap/v3:pkg", diff --git a/docs/root/api-v3/config/config.rst b/docs/root/api-v3/config/config.rst index ef4cdc091200..712ed03fa278 100644 --- a/docs/root/api-v3/config/config.rst +++ b/docs/root/api-v3/config/config.rst @@ -27,4 +27,4 @@ Extensions descriptors/descriptors request_id/request_id http/header_formatters - original_ip_detection/original_ip_detection + http/original_ip_detection diff --git a/docs/root/api-v3/config/original_ip_detection/original_ip_detection.rst b/docs/root/api-v3/config/http/original_ip_detection.rst similarity index 61% rename from docs/root/api-v3/config/original_ip_detection/original_ip_detection.rst rename to docs/root/api-v3/config/http/original_ip_detection.rst index 0bfaa28c804c..1d333c2f53c9 100644 --- a/docs/root/api-v3/config/original_ip_detection/original_ip_detection.rst +++ b/docs/root/api-v3/config/http/original_ip_detection.rst @@ -5,4 +5,4 @@ Original IP Detection :glob: :maxdepth: 2 - ../../extensions/original_ip_detection/*/v3/* + ../../extensions/http/original_ip_detection/*/v3/* diff --git a/docs/root/configuration/http/http_conn_man/headers.rst b/docs/root/configuration/http/http_conn_man/headers.rst index 67163047845e..93d32444f6b2 100644 --- a/docs/root/configuration/http/http_conn_man/headers.rst +++ b/docs/root/configuration/http/http_conn_man/headers.rst @@ -202,7 +202,7 @@ to XFF) are: node's connection to Envoy. In an environment where there are one or more trusted proxies in front of an edge -Envoy instance, the :ref:`XFF extension ` +Envoy instance, the :ref:`XFF extension ` can be configured via the :ref:`original_ip_detection_extensions field ` to set the *xff_num_trusted_hops* option which controls the number of additional diff --git a/docs/root/intro/arch_overview/other_features/ip_transparency.rst b/docs/root/intro/arch_overview/other_features/ip_transparency.rst index 5868d7064d7f..92b519421c3f 100644 --- a/docs/root/intro/arch_overview/other_features/ip_transparency.rst +++ b/docs/root/intro/arch_overview/other_features/ip_transparency.rst @@ -24,8 +24,8 @@ Envoy also supports :ref:`extensions ` for detecting the original IP address. This might be useful if none of the techniques below is applicable to your setup. Two available extensions are the :ref:`custom header -` -extension and the :ref:`xff ` +` +extension and the :ref:`xff ` extension. HTTP Headers diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 83d7adcd9f34..09a16316788c 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -140,8 +140,8 @@ New Features * grpc_json_transcoder: added :ref:`request_validation_options ` to reject invalid requests early. * grpc_json_transcoder: filter can now be configured on per-route/per-vhost level as well. Leaving empty list of services in the filter configuration disables transcoding on the specific route. * http: added support for :ref:`original IP detection extensions`. - Two initial extensions were added, the :ref:`custom header ` extension and the - :ref:`xff ` extension. + Two initial extensions were added, the :ref:`custom header ` extension and the + :ref:`xff ` extension. * http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 and HTTP/2 dispatching. Crashes while inside the dispatching loop should dump debug information. Furthermore, HTTP/1 and HTTP/2 clients now dumps the originating request whose response from the upstream caused Envoy to crash. * http: added support for :ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. * http: added new runtime config `envoy.reloadable_features.check_unsupported_typed_per_filter_config`, the default value is true. When the value is true, envoy will reject virtual host-specific typed per filter config when the filter doesn't support it. diff --git a/generated_api_shadow/BUILD b/generated_api_shadow/BUILD index 6bc4b9563b55..38113f762fa5 100644 --- a/generated_api_shadow/BUILD +++ b/generated_api_shadow/BUILD @@ -243,14 +243,14 @@ proto_library( "//envoy/extensions/filters/udp/udp_proxy/v3:pkg", "//envoy/extensions/health_checkers/redis/v3:pkg", "//envoy/extensions/http/header_formatters/preserve_case/v3:pkg", + "//envoy/extensions/http/original_ip_detection/custom_header/v3:pkg", + "//envoy/extensions/http/original_ip_detection/xff/v3:pkg", "//envoy/extensions/internal_redirect/allow_listed_routes/v3:pkg", "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", "//envoy/extensions/matching/common_inputs/environment_variable/v3:pkg", "//envoy/extensions/matching/input_matchers/consistent_hashing/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", - "//envoy/extensions/original_ip_detection/custom_header/v3:pkg", - "//envoy/extensions/original_ip_detection/xff/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/request_id/uuid/v3:pkg", "//envoy/extensions/resource_monitors/fixed_heap/v3:pkg", diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index b89d3820ebcf..c2e47aeee332 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -477,7 +477,7 @@ message HttpConnectionManager { // .. note:: // This field is deprecated and instead :ref:`original_ip_detection_extensions // ` - // should be used to configure the :ref:`xff extension ` + // should be used to configure the :ref:`xff extension ` // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. To replace // this field use a config like the following: // @@ -485,7 +485,7 @@ message HttpConnectionManager { // // original_ip_detection_extensions: // typed_config: - // "@type": type.googleapis.com/envoy.extensions.original_ip_detection.xff.v3.XffConfig + // "@type": type.googleapis.com/envoy.extensions.http.original_ip_detection.xff.v3.XffConfig // xff_num_trusted_hops: 1 // uint32 xff_num_trusted_hops = 19 @@ -501,7 +501,7 @@ message HttpConnectionManager { // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops // ` // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to + // the :ref:`xff extension ` for how to // configure xff_num_trusted_hops when using extensions. // // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index c49f9cbc4149..3cf5e73c94b9 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -475,7 +475,7 @@ message HttpConnectionManager { // .. note:: // This field is deprecated and instead :ref:`original_ip_detection_extensions // ` - // should be used to configure the :ref:`xff extension ` + // should be used to configure the :ref:`xff extension ` // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. To replace // this field use a config like the following: // @@ -483,7 +483,7 @@ message HttpConnectionManager { // // original_ip_detection_extensions: // typed_config: - // "@type": type.googleapis.com/envoy.extensions.original_ip_detection.xff.v3.XffConfig + // "@type": type.googleapis.com/envoy.extensions.http.original_ip_detection.xff.v3.XffConfig // xff_num_trusted_hops: 1 // uint32 hidden_envoy_deprecated_xff_num_trusted_hops = 19 @@ -499,7 +499,7 @@ message HttpConnectionManager { // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops // ` // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to + // the :ref:`xff extension ` for how to // configure xff_num_trusted_hops when using extensions. // // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/BUILD similarity index 100% rename from generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/BUILD rename to generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/BUILD diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto similarity index 93% rename from generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto rename to generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 44907fcdd602..7b1d060e378c 100644 --- a/generated_api_shadow/envoy/extensions/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -1,13 +1,13 @@ syntax = "proto3"; -package envoy.extensions.original_ip_detection.custom_header.v3; +package envoy.extensions.http.original_ip_detection.custom_header.v3; import "envoy/type/v3/http_status.proto"; import "udpa/annotations/status.proto"; import "validate/validate.proto"; -option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.custom_header.v3"; +option java_package = "io.envoyproxy.envoy.extensions.http.original_ip_detection.custom_header.v3"; option java_outer_classname = "CustomHeaderProto"; option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; diff --git a/generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/BUILD b/generated_api_shadow/envoy/extensions/http/original_ip_detection/xff/v3/BUILD similarity index 100% rename from generated_api_shadow/envoy/extensions/original_ip_detection/xff/v3/BUILD rename to generated_api_shadow/envoy/extensions/http/original_ip_detection/xff/v3/BUILD diff --git a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto b/generated_api_shadow/envoy/extensions/http/original_ip_detection/xff/v3/xff.proto similarity index 85% rename from api/envoy/extensions/original_ip_detection/xff/v3/xff.proto rename to generated_api_shadow/envoy/extensions/http/original_ip_detection/xff/v3/xff.proto index c5bd63cf00ab..6864788f9f18 100644 --- a/api/envoy/extensions/original_ip_detection/xff/v3/xff.proto +++ b/generated_api_shadow/envoy/extensions/http/original_ip_detection/xff/v3/xff.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -package envoy.extensions.original_ip_detection.xff.v3; +package envoy.extensions.http.original_ip_detection.xff.v3; import "udpa/annotations/status.proto"; -option java_package = "io.envoyproxy.envoy.extensions.original_ip_detection.xff.v3"; +option java_package = "io.envoyproxy.envoy.extensions.http.original_ip_detection.xff.v3"; option java_outer_classname = "XffProto"; option java_multiple_files = true; option (udpa.annotations.file_status).package_version_status = ACTIVE; diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index 97e0491b86c7..186fd2559836 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -275,8 +275,8 @@ EXTENSIONS = { # # Disabled by default - "envoy.http.original_ip_detection.custom_header": "//source/extensions/original_ip_detection/custom_header:config", - "envoy.http.original_ip_detection.xff": "//source/extensions/original_ip_detection/xff:config", + "envoy.http.original_ip_detection.custom_header": "//source/extensions/http/original_ip_detection/custom_header:config", + "envoy.http.original_ip_detection.xff": "//source/extensions/http/original_ip_detection/xff:config", } diff --git a/source/extensions/filters/network/http_connection_manager/BUILD b/source/extensions/filters/network/http_connection_manager/BUILD index 6dc24ec3a0aa..8f791c20d3fb 100644 --- a/source/extensions/filters/network/http_connection_manager/BUILD +++ b/source/extensions/filters/network/http_connection_manager/BUILD @@ -58,7 +58,7 @@ envoy_cc_extension( "//source/extensions/filters/http/common:pass_through_filter_lib", "//source/extensions/filters/network:well_known_names", "//source/extensions/filters/network/common:factory_base_lib", - "//source/extensions/original_ip_detection/xff:xff_lib", + "//source/extensions/http/original_ip_detection/xff:xff_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/request_id/uuid/v3:pkg_cc_proto", diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 73b2f6940987..1bee5418afe7 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -41,7 +41,7 @@ #endif #include "extensions/filters/http/common/pass_through_filter.h" -#include "extensions/original_ip_detection/xff/xff.h" +#include "extensions/http/original_ip_detection/xff/xff.h" namespace Envoy { namespace Extensions { diff --git a/source/extensions/original_ip_detection/custom_header/BUILD b/source/extensions/http/original_ip_detection/custom_header/BUILD similarity index 83% rename from source/extensions/original_ip_detection/custom_header/BUILD rename to source/extensions/http/original_ip_detection/custom_header/BUILD index cb55be8e9fe6..f9c141d12ad5 100644 --- a/source/extensions/original_ip_detection/custom_header/BUILD +++ b/source/extensions/http/original_ip_detection/custom_header/BUILD @@ -18,7 +18,7 @@ envoy_cc_library( deps = [ "//include/envoy/http:original_ip_detection_interface", "//source/common/network:utility_lib", - "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/http/original_ip_detection/custom_header/v3:pkg_cc_proto", ], ) @@ -35,6 +35,6 @@ envoy_cc_extension( "//include/envoy/http:original_ip_detection_interface", "//include/envoy/registry", "//source/common/config:utility_lib", - "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/http/original_ip_detection/custom_header/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/original_ip_detection/custom_header/config.cc b/source/extensions/http/original_ip_detection/custom_header/config.cc similarity index 64% rename from source/extensions/original_ip_detection/custom_header/config.cc rename to source/extensions/http/original_ip_detection/custom_header/config.cc index 23cd7725b95a..1922ea04c02e 100644 --- a/source/extensions/original_ip_detection/custom_header/config.cc +++ b/source/extensions/http/original_ip_detection/custom_header/config.cc @@ -1,20 +1,21 @@ -#include "extensions/original_ip_detection/custom_header/config.h" +#include "extensions/http/original_ip_detection/custom_header/config.h" -#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" -#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.validate.h" +#include "envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.pb.h" +#include "envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.pb.validate.h" #include "envoy/http/original_ip_detection.h" #include "envoy/registry/registry.h" #include "common/config/utility.h" -#include "extensions/original_ip_detection/custom_header/custom_header.h" +#include "extensions/http/original_ip_detection/custom_header/custom_header.h" namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace CustomHeader { -Http::OriginalIPDetectionSharedPtr +Envoy::Http::OriginalIPDetectionSharedPtr CustomHeaderIPDetectionFactory::createExtension(const Protobuf::Message& message, Server::Configuration::FactoryContext& context) { // TODO(rgs1): change message's type to TypedExtensionConfig and use translateAnyToFactoryConfig() @@ -24,14 +25,15 @@ CustomHeaderIPDetectionFactory::createExtension(const Protobuf::Message& message ProtobufWkt::Struct::default_instance(), context.messageValidationVisitor(), *config); const auto& custom_header_config = dynamic_cast< - const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig&>( + const envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig&>( *config); return std::make_shared(custom_header_config); } -REGISTER_FACTORY(CustomHeaderIPDetectionFactory, Http::OriginalIPDetectionFactory); +REGISTER_FACTORY(CustomHeaderIPDetectionFactory, Envoy::Http::OriginalIPDetectionFactory); } // namespace CustomHeader } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/original_ip_detection/custom_header/config.h b/source/extensions/http/original_ip_detection/custom_header/config.h similarity index 67% rename from source/extensions/original_ip_detection/custom_header/config.h rename to source/extensions/http/original_ip_detection/custom_header/config.h index 18a49a2734d2..05e28c07b30e 100644 --- a/source/extensions/original_ip_detection/custom_header/config.h +++ b/source/extensions/http/original_ip_detection/custom_header/config.h @@ -1,12 +1,13 @@ #pragma once -#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" +#include "envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.pb.h" #include "envoy/http/original_ip_detection.h" #include "common/protobuf/protobuf.h" namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace CustomHeader { @@ -14,15 +15,15 @@ namespace CustomHeader { * Config registration for the custom header IP detection extension. * @see OriginalIPDetectionFactory. */ -class CustomHeaderIPDetectionFactory : public Http::OriginalIPDetectionFactory { +class CustomHeaderIPDetectionFactory : public Envoy::Http::OriginalIPDetectionFactory { public: - Http::OriginalIPDetectionSharedPtr + Envoy::Http::OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message& message, Server::Configuration::FactoryContext& context) override; ProtobufTypes::MessagePtr createEmptyConfigProto() override { return std::make_unique< - envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig>(); + envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig>(); } std::string name() const override { return "envoy.http.original_ip_detection.custom_header"; } @@ -30,5 +31,6 @@ class CustomHeaderIPDetectionFactory : public Http::OriginalIPDetectionFactory { } // namespace CustomHeader } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.cc b/source/extensions/http/original_ip_detection/custom_header/custom_header.cc similarity index 73% rename from source/extensions/original_ip_detection/custom_header/custom_header.cc rename to source/extensions/http/original_ip_detection/custom_header/custom_header.cc index 1612cdb4db44..8ff33b99bb75 100644 --- a/source/extensions/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/http/original_ip_detection/custom_header/custom_header.cc @@ -1,14 +1,16 @@ -#include "extensions/original_ip_detection/custom_header/custom_header.h" +#include "extensions/http/original_ip_detection/custom_header/custom_header.h" #include "common/network/utility.h" namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace CustomHeader { CustomHeaderIPDetection::CustomHeaderIPDetection( - const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& config) + const envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig& + config) : header_name_(config.header_name()), allow_trusted_address_checks_(config.allow_extension_to_set_address_as_trusted()) { if (config.has_reject_options()) { @@ -19,11 +21,11 @@ CustomHeaderIPDetection::CustomHeaderIPDetection( CustomHeaderIPDetection::CustomHeaderIPDetection( const std::string& header_name, - absl::optional reject_options) + absl::optional reject_options) : header_name_(header_name), reject_options_(reject_options) {} -Http::OriginalIPDetectionResult -CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { +Envoy::Http::OriginalIPDetectionResult +CustomHeaderIPDetection::detect(Envoy::Http::OriginalIPDetectionParams& params) { auto hdr = params.request_headers.get(header_name_); if (hdr.empty()) { return {nullptr, false, reject_options_}; @@ -40,5 +42,6 @@ CustomHeaderIPDetection::detect(Http::OriginalIPDetectionParams& params) { } // namespace CustomHeader } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/http/original_ip_detection/custom_header/custom_header.h b/source/extensions/http/original_ip_detection/custom_header/custom_header.h new file mode 100644 index 000000000000..4a820b2c5beb --- /dev/null +++ b/source/extensions/http/original_ip_detection/custom_header/custom_header.h @@ -0,0 +1,47 @@ +#pragma once + +#include "envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.pb.h" +#include "envoy/http/codes.h" +#include "envoy/http/original_ip_detection.h" + +namespace Envoy { +namespace Extensions { +namespace Http { +namespace OriginalIPDetection { +namespace CustomHeader { + +/** + * Custom header IP detection extension. + */ +class CustomHeaderIPDetection : public Envoy::Http::OriginalIPDetection { +public: + CustomHeaderIPDetection( + const envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig& + config); + CustomHeaderIPDetection( + const std::string& header_name, + absl::optional reject_options = absl::nullopt); + + Envoy::Http::OriginalIPDetectionResult + detect(Envoy::Http::OriginalIPDetectionParams& params) override; + +private: + static Envoy::Http::Code toErrorCode(uint64_t status) { + const auto code = static_cast(status); + if (code >= Envoy::Http::Code::BadRequest && + code <= Envoy::Http::Code::NetworkAuthenticationRequired) { + return code; + } + return Envoy::Http::Code::Forbidden; + } + + Envoy::Http::LowerCaseString header_name_; + bool allow_trusted_address_checks_{false}; + absl::optional reject_options_{absl::nullopt}; +}; + +} // namespace CustomHeader +} // namespace OriginalIPDetection +} // namespace Http +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/original_ip_detection/xff/BUILD b/source/extensions/http/original_ip_detection/xff/BUILD similarity index 84% rename from source/extensions/original_ip_detection/xff/BUILD rename to source/extensions/http/original_ip_detection/xff/BUILD index 51c1cf44e632..1065cbe6a9a9 100644 --- a/source/extensions/original_ip_detection/xff/BUILD +++ b/source/extensions/http/original_ip_detection/xff/BUILD @@ -18,7 +18,7 @@ envoy_cc_library( deps = [ "//include/envoy/http:original_ip_detection_interface", "//source/common/http:utility_lib", - "@envoy_api//envoy/extensions/original_ip_detection/xff/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/http/original_ip_detection/xff/v3:pkg_cc_proto", ], ) @@ -35,6 +35,6 @@ envoy_cc_extension( "//include/envoy/http:original_ip_detection_interface", "//include/envoy/registry", "//source/common/config:utility_lib", - "@envoy_api//envoy/extensions/original_ip_detection/xff/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/http/original_ip_detection/xff/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/original_ip_detection/xff/config.cc b/source/extensions/http/original_ip_detection/xff/config.cc similarity index 65% rename from source/extensions/original_ip_detection/xff/config.cc rename to source/extensions/http/original_ip_detection/xff/config.cc index c2b1a50d645a..39f72a7b4e9c 100644 --- a/source/extensions/original_ip_detection/xff/config.cc +++ b/source/extensions/http/original_ip_detection/xff/config.cc @@ -1,20 +1,21 @@ -#include "extensions/original_ip_detection/xff/config.h" +#include "extensions/http/original_ip_detection/xff/config.h" -#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" -#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.validate.h" +#include "envoy/extensions/http/original_ip_detection/xff/v3/xff.pb.h" +#include "envoy/extensions/http/original_ip_detection/xff/v3/xff.pb.validate.h" #include "envoy/http/original_ip_detection.h" #include "envoy/registry/registry.h" #include "common/config/utility.h" -#include "extensions/original_ip_detection/xff/xff.h" +#include "extensions/http/original_ip_detection/xff/xff.h" namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace Xff { -Http::OriginalIPDetectionSharedPtr +Envoy::Http::OriginalIPDetectionSharedPtr XffIPDetectionFactory::createExtension(const Protobuf::Message& message, Server::Configuration::FactoryContext& context) { // TODO(rgs1): change message's type to TypedExtensionConfig and use translateAnyToFactoryConfig() @@ -24,13 +25,15 @@ XffIPDetectionFactory::createExtension(const Protobuf::Message& message, ProtobufWkt::Struct::default_instance(), context.messageValidationVisitor(), *config); const auto& xff_config = - dynamic_cast(*config); + dynamic_cast( + *config); return std::make_shared(xff_config); } -REGISTER_FACTORY(XffIPDetectionFactory, Http::OriginalIPDetectionFactory); +REGISTER_FACTORY(XffIPDetectionFactory, Envoy::Http::OriginalIPDetectionFactory); } // namespace Xff } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/original_ip_detection/xff/config.h b/source/extensions/http/original_ip_detection/xff/config.h similarity index 68% rename from source/extensions/original_ip_detection/xff/config.h rename to source/extensions/http/original_ip_detection/xff/config.h index d632e18e94c2..df3872adbab0 100644 --- a/source/extensions/original_ip_detection/xff/config.h +++ b/source/extensions/http/original_ip_detection/xff/config.h @@ -1,12 +1,13 @@ #pragma once -#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" +#include "envoy/extensions/http/original_ip_detection/xff/v3/xff.pb.h" #include "envoy/http/original_ip_detection.h" #include "common/protobuf/protobuf.h" namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace Xff { @@ -14,14 +15,14 @@ namespace Xff { * Config registration for the x-forwarded-for IP detection extension. * @see OriginalIPDetectionFactory. */ -class XffIPDetectionFactory : public Http::OriginalIPDetectionFactory { +class XffIPDetectionFactory : public Envoy::Http::OriginalIPDetectionFactory { public: - Http::OriginalIPDetectionSharedPtr + Envoy::Http::OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message& message, Server::Configuration::FactoryContext& context) override; ProtobufTypes::MessagePtr createEmptyConfigProto() override { - return std::make_unique(); + return std::make_unique(); } std::string name() const override { return "envoy.http.original_ip_detection.xff"; } @@ -29,5 +30,6 @@ class XffIPDetectionFactory : public Http::OriginalIPDetectionFactory { } // namespace Xff } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/original_ip_detection/xff/xff.cc b/source/extensions/http/original_ip_detection/xff/xff.cc similarity index 59% rename from source/extensions/original_ip_detection/xff/xff.cc rename to source/extensions/http/original_ip_detection/xff/xff.cc index 820f25514047..4600fb6774e7 100644 --- a/source/extensions/original_ip_detection/xff/xff.cc +++ b/source/extensions/http/original_ip_detection/xff/xff.cc @@ -1,25 +1,29 @@ -#include "extensions/original_ip_detection/xff/xff.h" +#include "extensions/http/original_ip_detection/xff/xff.h" #include "common/http/utility.h" namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace Xff { XffIPDetection::XffIPDetection( - const envoy::extensions::original_ip_detection::xff::v3::XffConfig& config) + const envoy::extensions::http::original_ip_detection::xff::v3::XffConfig& config) : xff_num_trusted_hops_(config.xff_num_trusted_hops()) {} XffIPDetection::XffIPDetection(uint32_t xff_num_trusted_hops) : xff_num_trusted_hops_(xff_num_trusted_hops) {} -Http::OriginalIPDetectionResult XffIPDetection::detect(Http::OriginalIPDetectionParams& params) { - auto ret = Http::Utility::getLastAddressFromXFF(params.request_headers, xff_num_trusted_hops_); +Envoy::Http::OriginalIPDetectionResult +XffIPDetection::detect(Envoy::Http::OriginalIPDetectionParams& params) { + auto ret = + Envoy::Http::Utility::getLastAddressFromXFF(params.request_headers, xff_num_trusted_hops_); return {ret.address_, ret.single_address_, absl::nullopt}; } } // namespace Xff } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/original_ip_detection/xff/xff.h b/source/extensions/http/original_ip_detection/xff/xff.h similarity index 52% rename from source/extensions/original_ip_detection/xff/xff.h rename to source/extensions/http/original_ip_detection/xff/xff.h index 7eef8cf8589d..82d58a1aeaa8 100644 --- a/source/extensions/original_ip_detection/xff/xff.h +++ b/source/extensions/http/original_ip_detection/xff/xff.h @@ -1,22 +1,24 @@ #pragma once -#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" +#include "envoy/extensions/http/original_ip_detection/xff/v3/xff.pb.h" #include "envoy/http/original_ip_detection.h" namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace Xff { /** * XFF (x-forwarded-for) IP detection extension. */ -class XffIPDetection : public Http::OriginalIPDetection { +class XffIPDetection : public Envoy::Http::OriginalIPDetection { public: - XffIPDetection(const envoy::extensions::original_ip_detection::xff::v3::XffConfig& config); + XffIPDetection(const envoy::extensions::http::original_ip_detection::xff::v3::XffConfig& config); XffIPDetection(uint32_t xff_num_trusted_hops); - Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override; + Envoy::Http::OriginalIPDetectionResult + detect(Envoy::Http::OriginalIPDetectionParams& params) override; private: const uint32_t xff_num_trusted_hops_; @@ -24,5 +26,6 @@ class XffIPDetection : public Http::OriginalIPDetection { } // namespace Xff } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/original_ip_detection/custom_header/custom_header.h b/source/extensions/original_ip_detection/custom_header/custom_header.h deleted file mode 100644 index 1c81a451d21d..000000000000 --- a/source/extensions/original_ip_detection/custom_header/custom_header.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" -#include "envoy/http/codes.h" -#include "envoy/http/original_ip_detection.h" - -namespace Envoy { -namespace Extensions { -namespace OriginalIPDetection { -namespace CustomHeader { - -/** - * Custom header IP detection extension. - */ -class CustomHeaderIPDetection : public Http::OriginalIPDetection { -public: - CustomHeaderIPDetection( - const envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig& - config); - CustomHeaderIPDetection( - const std::string& header_name, - absl::optional reject_options = absl::nullopt); - - Http::OriginalIPDetectionResult detect(Http::OriginalIPDetectionParams& params) override; - -private: - static Http::Code toErrorCode(uint64_t status) { - const auto code = static_cast(status); - if (code >= Http::Code::BadRequest && code <= Http::Code::NetworkAuthenticationRequired) { - return code; - } - return Http::Code::Forbidden; - } - - Http::LowerCaseString header_name_; - bool allow_trusted_address_checks_{false}; - absl::optional reject_options_{absl::nullopt}; -}; - -} // namespace CustomHeader -} // namespace OriginalIPDetection -} // namespace Extensions -} // namespace Envoy diff --git a/test/common/http/BUILD b/test/common/http/BUILD index e9818dc4a35b..85c587f0403e 100644 --- a/test/common/http/BUILD +++ b/test/common/http/BUILD @@ -217,8 +217,8 @@ envoy_cc_test( "//source/common/http:conn_manager_lib", "//source/common/http:context_lib", "//source/extensions/access_loggers/common:file_access_log_lib", - "//source/extensions/original_ip_detection/custom_header:custom_header_lib", - "//source/extensions/original_ip_detection/xff:xff_lib", + "//source/extensions/http/original_ip_detection/custom_header:custom_header_lib", + "//source/extensions/http/original_ip_detection/xff:xff_lib", "//source/extensions/request_id/uuid:config", "//test/mocks/access_log:access_log_mocks", "//test/mocks/event:event_mocks", @@ -246,8 +246,8 @@ envoy_cc_test( "//source/common/network:address_lib", "//source/common/network:utility_lib", "//source/common/runtime:runtime_lib", - "//source/extensions/original_ip_detection/custom_header:custom_header_lib", - "//source/extensions/original_ip_detection/xff:xff_lib", + "//source/extensions/http/original_ip_detection/custom_header:custom_header_lib", + "//source/extensions/http/original_ip_detection/xff:xff_lib", "//source/extensions/request_id/uuid:config", "//test/mocks/http:http_mocks", "//test/mocks/local_info:local_info_mocks", diff --git a/test/common/http/conn_manager_impl_test_2.cc b/test/common/http/conn_manager_impl_test_2.cc index 2cb748fdc1df..0f6374b5aeff 100644 --- a/test/common/http/conn_manager_impl_test_2.cc +++ b/test/common/http/conn_manager_impl_test_2.cc @@ -2990,9 +2990,9 @@ TEST_F(HttpConnectionManagerImplDeathTest, InvalidConnectionManagerConfig) { TEST_F(HttpConnectionManagerImplTest, RequestRejectedViaIPDetection) { OriginalIPRejectRequestOptions reject_options = {Http::Code::Forbidden, "ip detection failed"}; - auto extension = - std::make_shared( - "x-ip", reject_options); + auto extension = std::make_shared< + Extensions::Http::OriginalIPDetection::CustomHeader::CustomHeaderIPDetection>("x-ip", + reject_options); ip_detection_extensions_.push_back(extension); use_remote_address_ = false; diff --git a/test/common/http/conn_manager_impl_test_base.cc b/test/common/http/conn_manager_impl_test_base.cc index b2c72b317418..c2d02d6e6ab1 100644 --- a/test/common/http/conn_manager_impl_test_base.cc +++ b/test/common/http/conn_manager_impl_test_base.cc @@ -35,7 +35,7 @@ HttpConnectionManagerImplTest::HttpConnectionManagerImplTest() EXPECT_CALL(response_encoder_, getStream()).Times(AtLeast(0)); ip_detection_extensions_.push_back( - std::make_shared(0)); + std::make_shared(0)); } HttpConnectionManagerImplTest::~HttpConnectionManagerImplTest() { diff --git a/test/common/http/conn_manager_impl_test_base.h b/test/common/http/conn_manager_impl_test_base.h index 22f0c6d69ee3..1dc3a86e3ec3 100644 --- a/test/common/http/conn_manager_impl_test_base.h +++ b/test/common/http/conn_manager_impl_test_base.h @@ -6,8 +6,8 @@ #include "common/network/address_impl.h" #include "extensions/access_loggers/common/file_access_log_impl.h" -#include "extensions/original_ip_detection/custom_header/custom_header.h" -#include "extensions/original_ip_detection/xff/xff.h" +#include "extensions/http/original_ip_detection/custom_header/custom_header.h" +#include "extensions/http/original_ip_detection/xff/xff.h" #include "test/mocks/access_log/mocks.h" #include "test/mocks/event/mocks.h" diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index e0bfbe921b68..b166681c4c4f 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -12,8 +12,8 @@ #include "common/network/utility.h" #include "common/runtime/runtime_impl.h" -#include "extensions/original_ip_detection/custom_header/custom_header.h" -#include "extensions/original_ip_detection/xff/xff.h" +#include "extensions/http/original_ip_detection/custom_header/custom_header.h" +#include "extensions/http/original_ip_detection/xff/xff.h" #include "extensions/request_id/uuid/config.h" #include "test/mocks/http/mocks.h" @@ -109,7 +109,7 @@ class ConnectionManagerUtilityTest : public testing::Test { .WillByDefault(ReturnRef(request_id_extension_to_return_)); detection_extensions_.push_back( - std::make_shared(0)); + std::make_shared(0)); ON_CALL(config_, originalIpDetectionExtensions()) .WillByDefault(ReturnRef(detection_extensions_)); } @@ -375,7 +375,7 @@ TEST_F(ConnectionManagerUtilityTest, UseXFFTrustedHopsWithoutRemoteAddress) { // Reconfigure XFF detection. detection_extensions_.clear(); detection_extensions_.push_back( - std::make_shared(1)); + std::make_shared(1)); ON_CALL(config_, originalIpDetectionExtensions()).WillByDefault(ReturnRef(detection_extensions_)); connection_.stream_info_.downstream_address_provider_->setRemoteAddress( @@ -1601,9 +1601,8 @@ TEST_F(ConnectionManagerUtilityTest, NoPreserveExternalRequestIdNoEdgeRequest) { // Test an extension to detect the original IP for the request. TEST_F(ConnectionManagerUtilityTest, OriginalIPDetectionExtension) { const std::string header_name = "x-cdn-detected-ip"; - auto detection_extension = - std::make_shared( - header_name); + auto detection_extension = std::make_shared< + Extensions::Http::OriginalIPDetection::CustomHeader::CustomHeaderIPDetection>(header_name); const std::vector extensions = {detection_extension}; ON_CALL(config_, originalIpDetectionExtensions()).WillByDefault(ReturnRef(extensions)); diff --git a/test/extensions/filters/network/http_connection_manager/BUILD b/test/extensions/filters/network/http_connection_manager/BUILD index 5df40282c309..eeebd5c27a66 100644 --- a/test/extensions/filters/network/http_connection_manager/BUILD +++ b/test/extensions/filters/network/http_connection_manager/BUILD @@ -47,8 +47,8 @@ envoy_extension_cc_test( "//source/common/buffer:buffer_lib", "//source/extensions/access_loggers/file:config", "//source/extensions/filters/network/http_connection_manager:config", - "//source/extensions/original_ip_detection/custom_header:config", - "//source/extensions/original_ip_detection/custom_header:custom_header_lib", + "//source/extensions/http/original_ip_detection/custom_header:config", + "//source/extensions/http/original_ip_detection/custom_header:custom_header_lib", "//test/integration/filters:encoder_decoder_buffer_filter_lib", "//test/mocks/network:network_mocks", "//test/mocks/server:factory_context_mocks", diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 63d007289220..4b440704b668 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -10,7 +10,7 @@ #include "common/network/address_impl.h" #include "extensions/filters/network/http_connection_manager/config.h" -#include "extensions/original_ip_detection/custom_header/custom_header.h" +#include "extensions/http/original_ip_detection/custom_header/custom_header.h" #include "extensions/request_id/uuid/config.h" #include "test/extensions/filters/network/http_connection_manager/config.pb.h" @@ -1779,7 +1779,7 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { route_config: name: local_route original_ip_detection_extensions: - - name: envoy.ip_detection.UnknownOriginalIPDetectionExtension + - name: envoy.http.original_ip_detection.UnknownOriginalIPDetectionExtension typed_config: "@type": type.googleapis.com/google.protobuf.StringValue http_filters: @@ -1788,7 +1788,7 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { EXPECT_THROW_WITH_REGEX(createHttpConnectionManagerConfig(yaml_string), EnvoyException, "Original IP detection extension not found: " - "'envoy.ip_detection.UnknownOriginalIPDetectionExtension'"); + "'envoy.http.original_ip_detection.UnknownOriginalIPDetectionExtension'"); } namespace { @@ -1820,16 +1820,17 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtensionNotCreated) route_config: name: local_route original_ip_detection_extensions: - - name: envoy.http.ip_detection.OriginalIPDetectionExtensionNotCreated + - name: envoy.http.original_ip_detection.OriginalIPDetectionExtensionNotCreated typed_config: "@type": type.googleapis.com/google.protobuf.UInt32Value http_filters: - name: envoy.filters.http.router )EOF"; - EXPECT_THROW_WITH_REGEX(createHttpConnectionManagerConfig(yaml_string), EnvoyException, - "Original IP detection extension could not be created: " - "'envoy.http.ip_detection.OriginalIPDetectionExtensionNotCreated'"); + EXPECT_THROW_WITH_REGEX( + createHttpConnectionManagerConfig(yaml_string), EnvoyException, + "Original IP detection extension could not be created: " + "'envoy.http.original_ip_detection.OriginalIPDetectionExtensionNotCreated'"); } TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { @@ -1840,7 +1841,7 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { original_ip_detection_extensions: - name: envoy.http.original_ip_detection.custom_header typed_config: - "@type": type.googleapis.com/envoy.extensions.original_ip_detection.custom_header.v3.CustomHeaderConfig + "@type": type.googleapis.com/envoy.extensions.http.original_ip_detection.custom_header.v3.CustomHeaderConfig header_name: x-ip-header http_filters: - name: envoy.filters.http.router diff --git a/test/extensions/original_ip_detection/custom_header/BUILD b/test/extensions/http/original_ip_detection/custom_header/BUILD similarity index 64% rename from test/extensions/original_ip_detection/custom_header/BUILD rename to test/extensions/http/original_ip_detection/custom_header/BUILD index 5963aaa97afe..7a02e5ec778f 100644 --- a/test/extensions/original_ip_detection/custom_header/BUILD +++ b/test/extensions/http/original_ip_detection/custom_header/BUILD @@ -17,9 +17,9 @@ envoy_extension_cc_test( extension_name = "envoy.http.original_ip_detection.custom_header", deps = [ "//source/common/network:utility_lib", - "//source/extensions/original_ip_detection/custom_header:custom_header_lib", + "//source/extensions/http/original_ip_detection/custom_header:custom_header_lib", "//test/test_common:utility_lib", - "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/http/original_ip_detection/custom_header/v3:pkg_cc_proto", ], ) @@ -29,10 +29,10 @@ envoy_extension_cc_test( extension_name = "envoy.http.original_ip_detection.custom_header", deps = [ "//include/envoy/registry", - "//source/extensions/original_ip_detection/custom_header:config", - "//source/extensions/original_ip_detection/custom_header:custom_header_lib", + "//source/extensions/http/original_ip_detection/custom_header:config", + "//source/extensions/http/original_ip_detection/custom_header:custom_header_lib", "//test/mocks/server:factory_context_mocks", "//test/test_common:utility_lib", - "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/http/original_ip_detection/custom_header/v3:pkg_cc_proto", ], ) diff --git a/test/extensions/original_ip_detection/custom_header/config_test.cc b/test/extensions/http/original_ip_detection/custom_header/config_test.cc similarity index 75% rename from test/extensions/original_ip_detection/custom_header/config_test.cc rename to test/extensions/http/original_ip_detection/custom_header/config_test.cc index 6b9dc6299fe9..e617c465948a 100644 --- a/test/extensions/original_ip_detection/custom_header/config_test.cc +++ b/test/extensions/http/original_ip_detection/custom_header/config_test.cc @@ -1,7 +1,7 @@ -#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" +#include "envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.pb.h" #include "envoy/registry/registry.h" -#include "extensions/original_ip_detection/custom_header/config.h" +#include "extensions/http/original_ip_detection/custom_header/config.h" #include "test/mocks/server/factory_context.h" #include "test/test_common/utility.h" @@ -10,6 +10,7 @@ namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace CustomHeader { @@ -22,7 +23,7 @@ TEST(CustomHeaderFactoryTest, Basic) { const std::string yaml = R"EOF( name: envoy.formatter.TestFormatter typed_config: - "@type": type.googleapis.com/envoy.extensions.original_ip_detection.custom_header.v3.CustomHeaderConfig + "@type": type.googleapis.com/envoy.extensions.http.original_ip_detection.custom_header.v3.CustomHeaderConfig header_name: x-real-ip )EOF"; TestUtility::loadFromYaml(yaml, typed_config); @@ -33,5 +34,6 @@ TEST(CustomHeaderFactoryTest, Basic) { } // namespace CustomHeader } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc similarity index 68% rename from test/extensions/original_ip_detection/custom_header/custom_header_test.cc rename to test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc index 6a0e0cc2bab6..05c84233d79b 100644 --- a/test/extensions/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc @@ -1,8 +1,8 @@ -#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" +#include "envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.pb.h" #include "common/network/utility.h" -#include "extensions/original_ip_detection/custom_header/custom_header.h" +#include "extensions/http/original_ip_detection/custom_header/custom_header.h" #include "test/test_common/utility.h" @@ -10,6 +10,7 @@ namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace CustomHeader { @@ -18,7 +19,7 @@ class CustomHeaderTest : public testing::Test { CustomHeaderTest() { configure(); } void configure(envoy::type::v3::StatusCode code = envoy::type::v3::StatusCode::Unauthorized) { - envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; + envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig config; config.set_header_name("x-real-ip"); config.set_allow_extension_to_set_address_as_trusted(true); @@ -36,8 +37,8 @@ class CustomHeaderTest : public testing::Test { TEST_F(CustomHeaderTest, Detection) { // Header missing. { - Http::TestRequestHeaderMapImpl headers{{"x-other", "abc"}}; - Http::OriginalIPDetectionParams params = {headers, nullptr}; + Envoy::Http::TestRequestHeaderMapImpl headers{{"x-other", "abc"}}; + Envoy::Http::OriginalIPDetectionParams params = {headers, nullptr}; auto result = custom_header_extension_->detect(params); EXPECT_EQ(nullptr, result.detected_remote_address); @@ -45,14 +46,14 @@ TEST_F(CustomHeaderTest, Detection) { EXPECT_TRUE(result.reject_options.has_value()); const auto& reject_options = result.reject_options.value(); - EXPECT_EQ(reject_options.response_code, Http::Code::Unauthorized); + EXPECT_EQ(reject_options.response_code, Envoy::Http::Code::Unauthorized); EXPECT_EQ(reject_options.body, "detection failed"); } // Bad IP in the header. { - Http::TestRequestHeaderMapImpl headers{{"x-real-ip", "not-a-real-ip"}}; - Http::OriginalIPDetectionParams params = {headers, nullptr}; + Envoy::Http::TestRequestHeaderMapImpl headers{{"x-real-ip", "not-a-real-ip"}}; + Envoy::Http::OriginalIPDetectionParams params = {headers, nullptr}; auto result = custom_header_extension_->detect(params); EXPECT_EQ(nullptr, result.detected_remote_address); @@ -60,14 +61,14 @@ TEST_F(CustomHeaderTest, Detection) { EXPECT_TRUE(result.reject_options.has_value()); const auto& reject_options = result.reject_options.value(); - EXPECT_EQ(reject_options.response_code, Http::Code::Unauthorized); + EXPECT_EQ(reject_options.response_code, Envoy::Http::Code::Unauthorized); EXPECT_EQ(reject_options.body, "detection failed"); } // Good IPv4. { - Http::TestRequestHeaderMapImpl headers{{"x-real-ip", "1.2.3.4"}}; - Http::OriginalIPDetectionParams params = {headers, nullptr}; + Envoy::Http::TestRequestHeaderMapImpl headers{{"x-real-ip", "1.2.3.4"}}; + Envoy::Http::OriginalIPDetectionParams params = {headers, nullptr}; auto result = custom_header_extension_->detect(params); EXPECT_EQ("1.2.3.4:0", result.detected_remote_address->asString()); @@ -77,8 +78,8 @@ TEST_F(CustomHeaderTest, Detection) { // Good IPv6. { - Http::TestRequestHeaderMapImpl headers{{"x-real-ip", "fc00::1"}}; - Http::OriginalIPDetectionParams params = {headers, nullptr}; + Envoy::Http::TestRequestHeaderMapImpl headers{{"x-real-ip", "fc00::1"}}; + Envoy::Http::OriginalIPDetectionParams params = {headers, nullptr}; auto result = custom_header_extension_->detect(params); EXPECT_EQ("[fc00::1]:0", result.detected_remote_address->asString()); @@ -90,8 +91,8 @@ TEST_F(CustomHeaderTest, Detection) { TEST_F(CustomHeaderTest, FallbacksToDefaultResponseCode) { configure(envoy::type::v3::StatusCode::OK); - Http::TestRequestHeaderMapImpl headers{{"x-other", "abc"}}; - Http::OriginalIPDetectionParams params = {headers, nullptr}; + Envoy::Http::TestRequestHeaderMapImpl headers{{"x-other", "abc"}}; + Envoy::Http::OriginalIPDetectionParams params = {headers, nullptr}; auto result = custom_header_extension_->detect(params); EXPECT_EQ(nullptr, result.detected_remote_address); @@ -99,11 +100,12 @@ TEST_F(CustomHeaderTest, FallbacksToDefaultResponseCode) { EXPECT_TRUE(result.reject_options.has_value()); const auto& reject_options = result.reject_options.value(); - EXPECT_EQ(reject_options.response_code, Http::Code::Forbidden); + EXPECT_EQ(reject_options.response_code, Envoy::Http::Code::Forbidden); EXPECT_EQ(reject_options.body, "detection failed"); } } // namespace CustomHeader } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/test/extensions/original_ip_detection/xff/BUILD b/test/extensions/http/original_ip_detection/xff/BUILD similarity index 66% rename from test/extensions/original_ip_detection/xff/BUILD rename to test/extensions/http/original_ip_detection/xff/BUILD index 910320bc6473..14d79ac5cb50 100644 --- a/test/extensions/original_ip_detection/xff/BUILD +++ b/test/extensions/http/original_ip_detection/xff/BUILD @@ -17,9 +17,9 @@ envoy_extension_cc_test( extension_name = "envoy.http.original_ip_detection.xff", deps = [ "//source/common/http:utility_lib", - "//source/extensions/original_ip_detection/xff:xff_lib", + "//source/extensions/http/original_ip_detection/xff:xff_lib", "//test/test_common:utility_lib", - "@envoy_api//envoy/extensions/original_ip_detection/xff/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/http/original_ip_detection/xff/v3:pkg_cc_proto", ], ) @@ -29,10 +29,10 @@ envoy_extension_cc_test( extension_name = "envoy.http.original_ip_detection.xff", deps = [ "//include/envoy/registry", - "//source/extensions/original_ip_detection/xff:config", - "//source/extensions/original_ip_detection/xff:xff_lib", + "//source/extensions/http/original_ip_detection/xff:config", + "//source/extensions/http/original_ip_detection/xff:xff_lib", "//test/mocks/server:factory_context_mocks", "//test/test_common:utility_lib", - "@envoy_api//envoy/extensions/original_ip_detection/xff/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/http/original_ip_detection/xff/v3:pkg_cc_proto", ], ) diff --git a/test/extensions/original_ip_detection/xff/config_test.cc b/test/extensions/http/original_ip_detection/xff/config_test.cc similarity index 78% rename from test/extensions/original_ip_detection/xff/config_test.cc rename to test/extensions/http/original_ip_detection/xff/config_test.cc index 9ea824801e55..0f7f1ace9632 100644 --- a/test/extensions/original_ip_detection/xff/config_test.cc +++ b/test/extensions/http/original_ip_detection/xff/config_test.cc @@ -1,7 +1,7 @@ -#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" +#include "envoy/extensions/http/original_ip_detection/xff/v3/xff.pb.h" #include "envoy/registry/registry.h" -#include "extensions/original_ip_detection/xff/config.h" +#include "extensions/http/original_ip_detection/xff/config.h" #include "test/mocks/server/factory_context.h" #include "test/test_common/utility.h" @@ -10,6 +10,7 @@ namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace Xff { @@ -22,7 +23,7 @@ TEST(CustomHeaderFactoryTest, Basic) { const std::string yaml = R"EOF( name: envoy.formatter.TestFormatter typed_config: - "@type": type.googleapis.com/envoy.extensions.original_ip_detection.xff.v3.XffConfig + "@type": type.googleapis.com/envoy.extensions.http.original_ip_detection.xff.v3.XffConfig xff_num_trusted_hops: 1 )EOF"; TestUtility::loadFromYaml(yaml, typed_config); @@ -33,5 +34,6 @@ TEST(CustomHeaderFactoryTest, Basic) { } // namespace Xff } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/test/extensions/original_ip_detection/xff/xff_test.cc b/test/extensions/http/original_ip_detection/xff/xff_test.cc similarity index 62% rename from test/extensions/original_ip_detection/xff/xff_test.cc rename to test/extensions/http/original_ip_detection/xff/xff_test.cc index 9029f869f8ff..f03ac1a307ca 100644 --- a/test/extensions/original_ip_detection/xff/xff_test.cc +++ b/test/extensions/http/original_ip_detection/xff/xff_test.cc @@ -1,6 +1,6 @@ -#include "envoy/extensions/original_ip_detection/xff/v3/xff.pb.h" +#include "envoy/extensions/http/original_ip_detection/xff/v3/xff.pb.h" -#include "extensions/original_ip_detection/xff/xff.h" +#include "extensions/http/original_ip_detection/xff/xff.h" #include "test/test_common/utility.h" @@ -8,13 +8,14 @@ namespace Envoy { namespace Extensions { +namespace Http { namespace OriginalIPDetection { namespace Xff { class XffTest : public testing::Test { protected: XffTest() { - envoy::extensions::original_ip_detection::xff::v3::XffConfig config; + envoy::extensions::http::original_ip_detection::xff::v3::XffConfig config; config.set_xff_num_trusted_hops(1); xff_extension_ = std::make_shared(config); } @@ -25,8 +26,8 @@ class XffTest : public testing::Test { TEST_F(XffTest, Detection) { // Header missing. { - Http::TestRequestHeaderMapImpl headers{{"x-other", "abc"}}; - Http::OriginalIPDetectionParams params = {headers, nullptr}; + Envoy::Http::TestRequestHeaderMapImpl headers{{"x-other", "abc"}}; + Envoy::Http::OriginalIPDetectionParams params = {headers, nullptr}; auto result = xff_extension_->detect(params); EXPECT_EQ(nullptr, result.detected_remote_address); @@ -35,8 +36,8 @@ TEST_F(XffTest, Detection) { // Good request. { - Http::TestRequestHeaderMapImpl headers{{"x-forwarded-for", "1.2.3.4,2.2.2.2"}}; - Http::OriginalIPDetectionParams params = {headers, nullptr}; + Envoy::Http::TestRequestHeaderMapImpl headers{{"x-forwarded-for", "1.2.3.4,2.2.2.2"}}; + Envoy::Http::OriginalIPDetectionParams params = {headers, nullptr}; auto result = xff_extension_->detect(params); EXPECT_EQ("1.2.3.4:0", result.detected_remote_address->asString()); @@ -46,5 +47,6 @@ TEST_F(XffTest, Detection) { } // namespace Xff } // namespace OriginalIPDetection +} // namespace Http } // namespace Extensions } // namespace Envoy diff --git a/test/integration/BUILD b/test/integration/BUILD index 31acb55c9ca2..a9577298798f 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -299,7 +299,7 @@ envoy_cc_test( ":http_integration_lib", "//source/common/config:api_version_lib", "//source/common/protobuf", - "//source/extensions/original_ip_detection/xff:config", + "//source/extensions/http/original_ip_detection/xff:config", "//test/test_common:utility_lib", "@envoy_api//envoy/api/v2:pkg_cc_proto", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", @@ -1730,8 +1730,8 @@ envoy_cc_test( ], deps = [ ":http_integration_lib", - "//source/extensions/original_ip_detection/custom_header:config", + "//source/extensions/http/original_ip_detection/custom_header:config", "//test/test_common:utility_lib", - "@envoy_api//envoy/extensions/original_ip_detection/custom_header/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/http/original_ip_detection/custom_header/v3:pkg_cc_proto", ], ) diff --git a/test/integration/header_integration_test.cc b/test/integration/header_integration_test.cc index 280bedd73e48..636f1d47c612 100644 --- a/test/integration/header_integration_test.cc +++ b/test/integration/header_integration_test.cc @@ -45,7 +45,7 @@ use_remote_address: false original_ip_detection_extensions: - name: envoy.http.original_ip_detection.xff typed_config: - "@type": type.googleapis.com/envoy.extensions.original_ip_detection.xff.v3.XffConfig + "@type": type.googleapis.com/envoy.extensions.http.original_ip_detection.xff.v3.XffConfig xff_num_trusted_hops: 1 stat_prefix: header_test route_config: diff --git a/test/integration/original_ip_detection_integration_test.cc b/test/integration/original_ip_detection_integration_test.cc index 3ef732388df6..0dd85bb7c391 100644 --- a/test/integration/original_ip_detection_integration_test.cc +++ b/test/integration/original_ip_detection_integration_test.cc @@ -1,4 +1,4 @@ -#include "envoy/extensions/original_ip_detection/custom_header/v3/custom_header.pb.h" +#include "envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.pb.h" #include "test/integration/http_integration.h" #include "test/test_common/registry.h" @@ -22,7 +22,8 @@ TEST_F(OriginalIPDetectionIntegrationTest, HeaderBasedDetection) { config_helper_.addConfigModifier( [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm) -> void { - envoy::extensions::original_ip_detection::custom_header::v3::CustomHeaderConfig config; + envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig + config; config.set_header_name("x-cdn-detected-ip"); auto* extension = hcm.add_original_ip_detection_extensions(); From 29af4d35bc2cacd7f362ef6988176b99135dae26 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 8 Apr 2021 17:37:40 -0400 Subject: [PATCH 067/100] Reduce (or hide) the dynamic_cast calls Signed-off-by: Raul Gutierrez Segales --- .../custom_header/config.cc | 14 +++++--------- .../http/original_ip_detection/xff/config.cc | 16 ++++++---------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/source/extensions/http/original_ip_detection/custom_header/config.cc b/source/extensions/http/original_ip_detection/custom_header/config.cc index 1922ea04c02e..65defdccb738 100644 --- a/source/extensions/http/original_ip_detection/custom_header/config.cc +++ b/source/extensions/http/original_ip_detection/custom_header/config.cc @@ -18,16 +18,12 @@ namespace CustomHeader { Envoy::Http::OriginalIPDetectionSharedPtr CustomHeaderIPDetectionFactory::createExtension(const Protobuf::Message& message, Server::Configuration::FactoryContext& context) { - // TODO(rgs1): change message's type to TypedExtensionConfig and use translateAnyToFactoryConfig() - // here along with downcastAndValidate(). - auto config = createEmptyConfigProto(); - Envoy::Config::Utility::translateOpaqueConfig(dynamic_cast(message), - ProtobufWkt::Struct::default_instance(), - context.messageValidationVisitor(), *config); - const auto& custom_header_config = dynamic_cast< + auto mptr = Envoy::Config::Utility::translateAnyToFactoryConfig( + dynamic_cast(message), context.messageValidationVisitor(), *this); + const auto& proto_config = MessageUtil::downcastAndValidate< const envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig&>( - *config); - return std::make_shared(custom_header_config); + *mptr, context.messageValidationVisitor()); + return std::make_shared(proto_config); } REGISTER_FACTORY(CustomHeaderIPDetectionFactory, Envoy::Http::OriginalIPDetectionFactory); diff --git a/source/extensions/http/original_ip_detection/xff/config.cc b/source/extensions/http/original_ip_detection/xff/config.cc index 39f72a7b4e9c..57179a6a077f 100644 --- a/source/extensions/http/original_ip_detection/xff/config.cc +++ b/source/extensions/http/original_ip_detection/xff/config.cc @@ -18,16 +18,12 @@ namespace Xff { Envoy::Http::OriginalIPDetectionSharedPtr XffIPDetectionFactory::createExtension(const Protobuf::Message& message, Server::Configuration::FactoryContext& context) { - // TODO(rgs1): change message's type to TypedExtensionConfig and use translateAnyToFactoryConfig() - // here along with downcastAndValidate(). - auto config = createEmptyConfigProto(); - Envoy::Config::Utility::translateOpaqueConfig(dynamic_cast(message), - ProtobufWkt::Struct::default_instance(), - context.messageValidationVisitor(), *config); - const auto& xff_config = - dynamic_cast( - *config); - return std::make_shared(xff_config); + auto mptr = Envoy::Config::Utility::translateAnyToFactoryConfig( + dynamic_cast(message), context.messageValidationVisitor(), *this); + const auto& proto_config = MessageUtil::downcastAndValidate< + const envoy::extensions::http::original_ip_detection::xff::v3::XffConfig&>( + *mptr, context.messageValidationVisitor()); + return std::make_shared(proto_config); } REGISTER_FACTORY(XffIPDetectionFactory, Envoy::Http::OriginalIPDetectionFactory); From 720d541971b09a3251e97f96ff6d2c43653ed1eb Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 8 Apr 2021 18:05:44 -0400 Subject: [PATCH 068/100] Fix visibility comments Signed-off-by: Raul Gutierrez Segales --- .../extensions/http/original_ip_detection/custom_header/BUILD | 2 +- source/extensions/http/original_ip_detection/xff/BUILD | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/extensions/http/original_ip_detection/custom_header/BUILD b/source/extensions/http/original_ip_detection/custom_header/BUILD index f9c141d12ad5..e62f29c3e46d 100644 --- a/source/extensions/http/original_ip_detection/custom_header/BUILD +++ b/source/extensions/http/original_ip_detection/custom_header/BUILD @@ -28,7 +28,7 @@ envoy_cc_extension( hdrs = ["config.h"], category = "envoy.http.original_ip_detection", security_posture = "robust_to_untrusted_downstream", - # This extensions is core code. + # This extension is used from core tests. visibility = ["//visibility:public"], deps = [ ":custom_header_lib", diff --git a/source/extensions/http/original_ip_detection/xff/BUILD b/source/extensions/http/original_ip_detection/xff/BUILD index 1065cbe6a9a9..95a98aaaf329 100644 --- a/source/extensions/http/original_ip_detection/xff/BUILD +++ b/source/extensions/http/original_ip_detection/xff/BUILD @@ -28,7 +28,7 @@ envoy_cc_extension( hdrs = ["config.h"], category = "envoy.http.original_ip_detection", security_posture = "robust_to_untrusted_downstream", - # This extensions is core code. + # This extension is core code. visibility = ["//visibility:public"], deps = [ ":xff_lib", From de30bd9d2ad0659d25d1da786708e108d2f63e2f Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 8 Apr 2021 18:08:38 -0400 Subject: [PATCH 069/100] More comment fixes Signed-off-by: Raul Gutierrez Segales --- .../extensions/http/original_ip_detection/custom_header/BUILD | 2 +- source/extensions/http/original_ip_detection/xff/BUILD | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/extensions/http/original_ip_detection/custom_header/BUILD b/source/extensions/http/original_ip_detection/custom_header/BUILD index e62f29c3e46d..687e801b279e 100644 --- a/source/extensions/http/original_ip_detection/custom_header/BUILD +++ b/source/extensions/http/original_ip_detection/custom_header/BUILD @@ -13,7 +13,7 @@ envoy_cc_library( name = "custom_header_lib", srcs = ["custom_header.cc"], hdrs = ["custom_header.h"], - # This extensions is core code. + # This extension is used from core tests. visibility = ["//visibility:public"], deps = [ "//include/envoy/http:original_ip_detection_interface", diff --git a/source/extensions/http/original_ip_detection/xff/BUILD b/source/extensions/http/original_ip_detection/xff/BUILD index 95a98aaaf329..a247f485a1f5 100644 --- a/source/extensions/http/original_ip_detection/xff/BUILD +++ b/source/extensions/http/original_ip_detection/xff/BUILD @@ -13,7 +13,7 @@ envoy_cc_library( name = "xff_lib", srcs = ["xff.cc"], hdrs = ["xff.h"], - # This extensions is core code. + # This extension is core code. visibility = ["//visibility:public"], deps = [ "//include/envoy/http:original_ip_detection_interface", From ab852ff8aa066520194bf64e80a19b24c0eaed4a Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 8 Apr 2021 19:03:31 -0400 Subject: [PATCH 070/100] Validate header name Signed-off-by: Raul Gutierrez Segales --- .../original_ip_detection/custom_header/v3/custom_header.proto | 3 ++- .../original_ip_detection/custom_header/v3/custom_header.proto | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 7b1d060e378c..3c54a7e93059 100644 --- a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -38,7 +38,8 @@ message CustomHeaderConfig { // The header name containing the original downstream remote address, if present. // // Note: in the case of a multi-valued header, only the first value is tried and the rest are ignored. - string header_name = 1 [(validate.rules).string = {min_len: 1}]; + string header_name = 1 + [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: false}]; // If set to true, the extension is allowed to decide if the detected address should be treated as // trusted. If a detected address is considered trusted, it might be used as input to determine diff --git a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 7b1d060e378c..3c54a7e93059 100644 --- a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -38,7 +38,8 @@ message CustomHeaderConfig { // The header name containing the original downstream remote address, if present. // // Note: in the case of a multi-valued header, only the first value is tried and the rest are ignored. - string header_name = 1 [(validate.rules).string = {min_len: 1}]; + string header_name = 1 + [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: false}]; // If set to true, the extension is allowed to decide if the detected address should be treated as // trusted. If a detected address is considered trusted, it might be used as input to determine From 4582469ebc16fc9e62ec62063e85137dd4c20954 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 8 Apr 2021 19:38:54 -0400 Subject: [PATCH 071/100] More fixes * improve test * fix namespacing issue now that we have Extensions::Http confuses things referencing Envoy::Http Signed-off-by: Raul Gutierrez Segales --- source/extensions/request_id/uuid/config.h | 20 ++++++++++--------- test/common/http/conn_manager_utility_test.cc | 11 +++++++++- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/source/extensions/request_id/uuid/config.h b/source/extensions/request_id/uuid/config.h index bd21f9eaa6bc..92d5e68d617d 100644 --- a/source/extensions/request_id/uuid/config.h +++ b/source/extensions/request_id/uuid/config.h @@ -11,14 +11,14 @@ namespace RequestId { // UUIDRequestIDExtension is the default implementation if no other extension is explicitly // configured. -class UUIDRequestIDExtension : public Http::RequestIDExtension { +class UUIDRequestIDExtension : public Envoy::Http::RequestIDExtension { public: UUIDRequestIDExtension(const envoy::extensions::request_id::uuid::v3::UuidRequestIdConfig& config, Random::RandomGenerator& random) : random_(random), pack_trace_reason_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, pack_trace_reason, true)) {} - static Http::RequestIDExtensionSharedPtr defaultInstance(Random::RandomGenerator& random) { + static Envoy::Http::RequestIDExtensionSharedPtr defaultInstance(Random::RandomGenerator& random) { return std::make_shared( envoy::extensions::request_id::uuid::v3::UuidRequestIdConfig(), random); } @@ -26,12 +26,14 @@ class UUIDRequestIDExtension : public Http::RequestIDExtension { bool packTraceReason() { return pack_trace_reason_; } // Http::RequestIDExtension - void set(Http::RequestHeaderMap& request_headers, bool force) override; - void setInResponse(Http::ResponseHeaderMap& response_headers, - const Http::RequestHeaderMap& request_headers) override; - absl::optional toInteger(const Http::RequestHeaderMap& request_headers) const override; - Tracing::Reason getTraceReason(const Http::RequestHeaderMap& request_headers) override; - void setTraceReason(Http::RequestHeaderMap& request_headers, Tracing::Reason status) override; + void set(Envoy::Http::RequestHeaderMap& request_headers, bool force) override; + void setInResponse(Envoy::Http::ResponseHeaderMap& response_headers, + const Envoy::Http::RequestHeaderMap& request_headers) override; + absl::optional + toInteger(const Envoy::Http::RequestHeaderMap& request_headers) const override; + Tracing::Reason getTraceReason(const Envoy::Http::RequestHeaderMap& request_headers) override; + void setTraceReason(Envoy::Http::RequestHeaderMap& request_headers, + Tracing::Reason status) override; private: Envoy::Random::RandomGenerator& random_; @@ -63,7 +65,7 @@ class UUIDRequestIDExtensionFactory : public Server::Configuration::RequestIDExt ProtobufTypes::MessagePtr createEmptyConfigProto() override { return std::make_unique(); } - Http::RequestIDExtensionSharedPtr + Envoy::Http::RequestIDExtensionSharedPtr createExtensionInstance(const Protobuf::Message& config, Server::Configuration::FactoryContext& context) override { return std::make_shared( diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index b166681c4c4f..e772e633ffbe 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -115,6 +115,11 @@ class ConnectionManagerUtilityTest : public testing::Test { } struct MutateRequestRet { + MutateRequestRet() = default; + MutateRequestRet(const std::string& downstream_address, bool internal, + Tracing::Reason trace_reason) + : downstream_address_(downstream_address), internal_(internal), + trace_reason_(trace_reason) {} bool operator==(const MutateRequestRet& rhs) const { return downstream_address_ == rhs.downstream_address_ && internal_ == rhs.internal_ && trace_reason_ == rhs.trace_reason_; @@ -123,6 +128,7 @@ class ConnectionManagerUtilityTest : public testing::Test { std::string downstream_address_; bool internal_; Tracing::Reason trace_reason_; + absl::optional reject_request_{absl::nullopt}; }; // This is a convenience method used to call mutateRequestHeaders(). It is done in this @@ -133,6 +139,7 @@ class ConnectionManagerUtilityTest : public testing::Test { const auto result = ConnectionManagerUtility::mutateRequestHeaders( headers, connection_, config_, route_config_, local_info_); ret.downstream_address_ = result.final_remote_address->asString(); + ret.reject_request_ = result.reject_request; ret.trace_reason_ = ConnectionManagerUtility::mutateTracingRequestHeader(headers, runtime_, config_, &route_); ret.internal_ = HeaderUtility::isEnvoyInternalRequest(headers); @@ -1598,7 +1605,7 @@ TEST_F(ConnectionManagerUtilityTest, NoPreserveExternalRequestIdNoEdgeRequest) { } } -// Test an extension to detect the original IP for the request. +// Test detecting the original IP via a header (no rejection if it fails). TEST_F(ConnectionManagerUtilityTest, OriginalIPDetectionExtension) { const std::string header_name = "x-cdn-detected-ip"; auto detection_extension = std::make_shared< @@ -1613,6 +1620,7 @@ TEST_F(ConnectionManagerUtilityTest, OriginalIPDetectionExtension) { TestRequestHeaderMapImpl headers{{header_name, "2.1.3.4"}}; auto ret = callMutateRequestHeaders(headers, Protocol::Http11); EXPECT_EQ(ret.downstream_address_, "2.1.3.4:0"); + EXPECT_EQ(ret.reject_request_, absl::nullopt); } // Header missing -- fallbacks to default behavior. @@ -1620,6 +1628,7 @@ TEST_F(ConnectionManagerUtilityTest, OriginalIPDetectionExtension) { TestRequestHeaderMapImpl headers; auto ret = callMutateRequestHeaders(headers, Protocol::Http11); EXPECT_EQ(ret.downstream_address_, "10.0.0.3:50000"); + EXPECT_EQ(ret.reject_request_, absl::nullopt); } } From 8ec2a835e5e5c9f7f2d2256f0251e4a45ef32b23 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 8 Apr 2021 20:34:50 -0400 Subject: [PATCH 072/100] More namespaces fixes Signed-off-by: Raul Gutierrez Segales --- .../network/http_connection_manager/config.cc | 135 +++++++++--------- .../http_connection_manager/config_test.cc | 37 ++--- .../config_test_base.h | 2 +- 3 files changed, 91 insertions(+), 83 deletions(-) diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 1bee5418afe7..0c6e8067762e 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -49,7 +49,7 @@ namespace NetworkFilters { namespace HttpConnectionManager { namespace { -using FilterFactoriesList = std::list; +using FilterFactoriesList = std::list; using FilterFactoryMap = std::map; HttpConnectionManagerConfig::UpgradeMap::const_iterator @@ -73,23 +73,23 @@ FilterFactoryMap::const_iterator findUpgradeCaseInsensitive(const FilterFactoryM return upgrade_map.end(); } -std::unique_ptr createInternalAddressConfig( +std::unique_ptr createInternalAddressConfig( const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& config) { if (config.has_internal_address_config()) { return std::make_unique(config.internal_address_config()); } - return std::make_unique(); + return std::make_unique(); } -class MissingConfigFilter : public Http::PassThroughDecoderFilter { +class MissingConfigFilter : public Envoy::Http::PassThroughDecoderFilter { public: - Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool) override { + Envoy::Http::FilterHeadersStatus decodeHeaders(Envoy::Http::RequestHeaderMap&, bool) override { decoder_callbacks_->streamInfo().setResponseFlag(StreamInfo::ResponseFlag::NoFilterConfigFound); - decoder_callbacks_->sendLocalReply(Http::Code::InternalServerError, EMPTY_STRING, nullptr, - absl::nullopt, EMPTY_STRING); - return Http::FilterHeadersStatus::StopIteration; + decoder_callbacks_->sendLocalReply(Envoy::Http::Code::InternalServerError, EMPTY_STRING, + nullptr, absl::nullopt, EMPTY_STRING); + return Envoy::Http::FilterHeadersStatus::StopIteration; } }; @@ -103,11 +103,11 @@ SINGLETON_MANAGER_REGISTRATION(http_tracer_manager); SINGLETON_MANAGER_REGISTRATION(filter_config_provider_manager); Utility::Singletons Utility::createSingletons(Server::Configuration::FactoryContext& context) { - std::shared_ptr date_provider = - context.singletonManager().getTyped( + std::shared_ptr date_provider = + context.singletonManager().getTyped( SINGLETON_MANAGER_REGISTERED_NAME(date_provider), [&context] { - return std::make_shared(context.dispatcher(), - context.threadLocal()); + return std::make_shared(context.dispatcher(), + context.threadLocal()); }); Router::RouteConfigProviderManagerSharedPtr route_config_provider_manager = @@ -143,7 +143,7 @@ Utility::Singletons Utility::createSingletons(Server::Configuration::FactoryCont std::shared_ptr Utility::createConfig( const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& proto_config, - Server::Configuration::FactoryContext& context, Http::DateProvider& date_provider, + Server::Configuration::FactoryContext& context, Envoy::Http::DateProvider& date_provider, Router::RouteConfigProviderManager& route_config_provider_manager, Config::ConfigProviderManager& scoped_routes_config_provider_manager, Tracing::HttpTracerManager& http_tracer_manager, @@ -170,10 +170,11 @@ HttpConnectionManagerFilterConfigFactory::createFilterFactoryFromProtoTyped( // Keep in mind the lambda capture list **doesn't** determine the destruction order, but it's fine // as these captured objects are also global singletons. return [singletons, filter_config, &context](Network::FilterManager& filter_manager) -> void { - filter_manager.addReadFilter(Network::ReadFilterSharedPtr{new Http::ConnectionManagerImpl( - *filter_config, context.drainDecision(), context.api().randomGenerator(), - context.httpContext(), context.runtime(), context.localInfo(), context.clusterManager(), - context.overloadManager(), context.dispatcher().timeSource())}); + filter_manager.addReadFilter( + Network::ReadFilterSharedPtr{new Envoy::Http::ConnectionManagerImpl( + *filter_config, context.drainDecision(), context.api().randomGenerator(), + context.httpContext(), context.runtime(), context.localInfo(), context.clusterManager(), + context.overloadManager(), context.dispatcher().timeSource())}); }; } @@ -192,15 +193,15 @@ InternalAddressConfig::InternalAddressConfig( HttpConnectionManagerConfig::HttpConnectionManagerConfig( const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& config, - Server::Configuration::FactoryContext& context, Http::DateProvider& date_provider, + Server::Configuration::FactoryContext& context, Envoy::Http::DateProvider& date_provider, Router::RouteConfigProviderManager& route_config_provider_manager, Config::ConfigProviderManager& scoped_routes_config_provider_manager, Tracing::HttpTracerManager& http_tracer_manager, Filter::Http::FilterConfigProviderManager& filter_config_provider_manager) : context_(context), stats_prefix_(fmt::format("http.{}.", config.stat_prefix())), - stats_(Http::ConnectionManagerImpl::generateStats(stats_prefix_, context_.scope())), - tracing_stats_( - Http::ConnectionManagerImpl::generateTracingStats(stats_prefix_, context_.scope())), + stats_(Envoy::Http::ConnectionManagerImpl::generateStats(stats_prefix_, context_.scope())), + tracing_stats_(Envoy::Http::ConnectionManagerImpl::generateTracingStats(stats_prefix_, + context_.scope())), use_remote_address_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, use_remote_address, false)), internal_address_config_(createInternalAddressConfig(config)), xff_num_trusted_hops_(config.xff_num_trusted_hops()), @@ -214,16 +215,16 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( http2_options_(Http2::Utility::initializeAndValidateOptions( config.http2_protocol_options(), config.has_stream_error_on_invalid_http_message(), config.stream_error_on_invalid_http_message())), - http1_settings_(Http::Http1::parseHttp1Settings( + http1_settings_(Envoy::Http::Http1::parseHttp1Settings( config.http_protocol_options(), context.messageValidationVisitor(), config.stream_error_on_invalid_http_message(), xff_num_trusted_hops_ == 0 && use_remote_address_)), max_request_headers_kb_(PROTOBUF_GET_WRAPPED_OR_DEFAULT( - config, max_request_headers_kb, Http::DEFAULT_MAX_REQUEST_HEADERS_KB)), + config, max_request_headers_kb, Envoy::Http::DEFAULT_MAX_REQUEST_HEADERS_KB)), max_request_headers_count_(PROTOBUF_GET_WRAPPED_OR_DEFAULT( config.common_http_protocol_options(), max_headers_count, - context.runtime().snapshot().getInteger(Http::MaxRequestHeadersCountOverrideKey, - Http::DEFAULT_MAX_HEADERS_COUNT))), + context.runtime().snapshot().getInteger(Envoy::Http::MaxRequestHeadersCountOverrideKey, + Envoy::Http::DEFAULT_MAX_HEADERS_COUNT))), idle_timeout_(PROTOBUF_GET_OPTIONAL_MS(config.common_http_protocol_options(), idle_timeout)), max_connection_duration_( PROTOBUF_GET_OPTIONAL_MS(config.common_http_protocol_options(), max_connection_duration)), @@ -239,8 +240,8 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( preserve_external_request_id_(config.preserve_external_request_id()), always_set_request_id_in_response_(config.always_set_request_id_in_response()), date_provider_(date_provider), - listener_stats_(Http::ConnectionManagerImpl::generateListenerStats(stats_prefix_, - context_.listenerScope())), + listener_stats_(Envoy::Http::ConnectionManagerImpl::generateListenerStats( + stats_prefix_, context_.listenerScope())), proxy_100_continue_(config.proxy_100_continue()), stream_error_on_invalid_http_messaging_( PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, stream_error_on_invalid_http_message, false)), @@ -280,11 +281,11 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( } if (config.strip_any_host_port()) { - strip_port_type_ = Http::StripPortType::Any; + strip_port_type_ = Envoy::Http::StripPortType::Any; } else if (config.strip_matching_host_port()) { - strip_port_type_ = Http::StripPortType::MatchingHost; + strip_port_type_ = Envoy::Http::StripPortType::MatchingHost; } else { - strip_port_type_ = Http::StripPortType::None; + strip_port_type_ = Envoy::Http::StripPortType::None; } // If we are provided a different request_id_extension implementation to use try and create a @@ -297,15 +298,16 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( final_rid_config.mutable_typed_config()->PackFrom( envoy::extensions::request_id::uuid::v3::UuidRequestIdConfig()); } - request_id_extension_ = Http::RequestIDExtensionFactory::fromProto(final_rid_config, context_); + request_id_extension_ = + Envoy::Http::RequestIDExtensionFactory::fromProto(final_rid_config, context_); // Check if IP detection extensions were configured. const auto& ip_detection_extensions = config.original_ip_detection_extensions(); if (!ip_detection_extensions.empty()) { original_ip_detection_extensions_.reserve(ip_detection_extensions.size()); for (const auto& extension_config : ip_detection_extensions) { - auto* factory = - Envoy::Config::Utility::getFactory(extension_config); + auto* factory = Envoy::Config::Utility::getFactory( + extension_config); if (!factory) { throw EnvoyException(fmt::format("Original IP detection extension not found: '{}'", extension_config.name())); @@ -320,7 +322,8 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( } } else { original_ip_detection_extensions_.push_back( - std::make_shared(xff_num_trusted_hops_)); + std::make_shared( + xff_num_trusted_hops_)); } // If scoped RDS is enabled, avoid creating a route config provider. Route config providers will @@ -347,23 +350,23 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( switch (config.forward_client_cert_details()) { case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: SANITIZE: - forward_client_cert_ = Http::ForwardClientCertType::Sanitize; + forward_client_cert_ = Envoy::Http::ForwardClientCertType::Sanitize; break; case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: FORWARD_ONLY: - forward_client_cert_ = Http::ForwardClientCertType::ForwardOnly; + forward_client_cert_ = Envoy::Http::ForwardClientCertType::ForwardOnly; break; case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: APPEND_FORWARD: - forward_client_cert_ = Http::ForwardClientCertType::AppendForward; + forward_client_cert_ = Envoy::Http::ForwardClientCertType::AppendForward; break; case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: SANITIZE_SET: - forward_client_cert_ = Http::ForwardClientCertType::SanitizeSet; + forward_client_cert_ = Envoy::Http::ForwardClientCertType::SanitizeSet; break; case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: ALWAYS_FORWARD_ONLY: - forward_client_cert_ = Http::ForwardClientCertType::AlwaysForwardOnly; + forward_client_cert_ = Envoy::Http::ForwardClientCertType::AlwaysForwardOnly; break; default: NOT_REACHED_GCOVR_EXCL_LINE; @@ -371,19 +374,19 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( const auto& set_current_client_cert_details = config.set_current_client_cert_details(); if (set_current_client_cert_details.cert()) { - set_current_client_cert_details_.push_back(Http::ClientCertDetailsType::Cert); + set_current_client_cert_details_.push_back(Envoy::Http::ClientCertDetailsType::Cert); } if (set_current_client_cert_details.chain()) { - set_current_client_cert_details_.push_back(Http::ClientCertDetailsType::Chain); + set_current_client_cert_details_.push_back(Envoy::Http::ClientCertDetailsType::Chain); } if (PROTOBUF_GET_WRAPPED_OR_DEFAULT(set_current_client_cert_details, subject, false)) { - set_current_client_cert_details_.push_back(Http::ClientCertDetailsType::Subject); + set_current_client_cert_details_.push_back(Envoy::Http::ClientCertDetailsType::Subject); } if (set_current_client_cert_details.uri()) { - set_current_client_cert_details_.push_back(Http::ClientCertDetailsType::URI); + set_current_client_cert_details_.push_back(Envoy::Http::ClientCertDetailsType::URI); } if (set_current_client_cert_details.dns()) { - set_current_client_cert_details_.push_back(Http::ClientCertDetailsType::DNS); + set_current_client_cert_details_.push_back(Envoy::Http::ClientCertDetailsType::DNS); } if (config.has_add_user_agent() && config.add_user_agent().value()) { @@ -453,8 +456,8 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( const uint32_t max_path_tag_length = PROTOBUF_GET_WRAPPED_OR_DEFAULT( tracing_config, max_path_tag_length, Tracing::DefaultMaxPathTagLength); - tracing_config_ = - std::make_unique(Http::TracingConnectionManagerConfig{ + tracing_config_ = std::make_unique( + Envoy::Http::TracingConnectionManagerConfig{ tracing_operation_name, custom_tags, client_sampling, random_sampling, overall_sampling, tracing_config.verbose(), max_path_tag_length}); } @@ -470,7 +473,7 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( if (!config.server_name().empty()) { server_name_ = config.server_name(); } else { - server_name_ = Http::DefaultServerString::get(); + server_name_ = Envoy::Http::DefaultServerString::get(); } switch (config.codec_type()) { @@ -547,7 +550,7 @@ void HttpConnectionManagerConfig::processFilter( proto_config); ProtobufTypes::MessagePtr message = Config::Utility::translateToFactoryConfig( proto_config, context_.messageValidationVisitor(), factory); - Http::FilterFactoryCb callback = + Envoy::Http::FilterFactoryCb callback = factory.createFilterFactoryFromProto(*message, stats_prefix_, context_); bool is_terminal = factory.isTerminalFilter(); Config::Utility::validateTerminalFilters(proto_config.name(), factory.name(), filter_chain_type, @@ -593,21 +596,21 @@ void HttpConnectionManagerConfig::processDynamicFilterConfig( filter_factories.push_back(std::move(filter_config_provider)); } -Http::ServerConnectionPtr +Envoy::Http::ServerConnectionPtr HttpConnectionManagerConfig::createCodec(Network::Connection& connection, const Buffer::Instance& data, - Http::ServerConnectionCallbacks& callbacks) { + Envoy::Http::ServerConnectionCallbacks& callbacks) { switch (codec_type_) { case CodecType::HTTP1: { - return std::make_unique( - connection, Http::Http1::CodecStats::atomicGet(http1_codec_stats_, context_.scope()), + return std::make_unique( + connection, Envoy::Http::Http1::CodecStats::atomicGet(http1_codec_stats_, context_.scope()), callbacks, http1_settings_, maxRequestHeadersKb(), maxRequestHeadersCount(), headersWithUnderscoresAction()); } case CodecType::HTTP2: { - return std::make_unique( + return std::make_unique( connection, callbacks, - Http::Http2::CodecStats::atomicGet(http2_codec_stats_, context_.scope()), + Envoy::Http::Http2::CodecStats::atomicGet(http2_codec_stats_, context_.scope()), context_.api().randomGenerator(), http2_options_, maxRequestHeadersKb(), maxRequestHeadersCount(), headersWithUnderscoresAction()); } @@ -615,14 +618,14 @@ HttpConnectionManagerConfig::createCodec(Network::Connection& connection, #ifdef ENVOY_ENABLE_QUIC return std::make_unique( dynamic_cast(connection), callbacks, - Http::Http3::CodecStats::atomicGet(http3_codec_stats_, context_.scope()), http3_options_, - maxRequestHeadersKb(), headersWithUnderscoresAction()); + Envoy::Http::Http3::CodecStats::atomicGet(http3_codec_stats_, context_.scope()), + http3_options_, maxRequestHeadersKb(), headersWithUnderscoresAction()); #else // Should be blocked by configuration checking at an earlier point. NOT_REACHED_GCOVR_EXCL_LINE; #endif case CodecType::AUTO: - return Http::ConnectionManagerUtility::autoCreateCodec( + return Envoy::Http::ConnectionManagerUtility::autoCreateCodec( connection, data, callbacks, context_.scope(), context_.api().randomGenerator(), http1_codec_stats_, http2_codec_stats_, http1_settings_, http2_options_, maxRequestHeadersKb(), maxRequestHeadersCount(), headersWithUnderscoresAction()); @@ -631,7 +634,8 @@ HttpConnectionManagerConfig::createCodec(Network::Connection& connection, } void HttpConnectionManagerConfig::createFilterChainForFactories( - Http::FilterChainFactoryCallbacks& callbacks, const FilterFactoriesList& filter_factories) { + Envoy::Http::FilterChainFactoryCallbacks& callbacks, + const FilterFactoriesList& filter_factories) { bool added_missing_config_filter = false; for (const auto& filter_config_provider : filter_factories) { auto config = filter_config_provider->config(); @@ -644,7 +648,7 @@ void HttpConnectionManagerConfig::createFilterChainForFactories( if (!added_missing_config_filter) { ENVOY_LOG(trace, "Missing filter config for a provider {}", filter_config_provider->name()); callbacks.addStreamDecoderFilter( - Http::StreamDecoderFilterSharedPtr{std::make_shared()}); + Envoy::Http::StreamDecoderFilterSharedPtr{std::make_shared()}); added_missing_config_filter = true; } else { ENVOY_LOG(trace, "Provider {} missing a filter config", filter_config_provider->name()); @@ -652,14 +656,15 @@ void HttpConnectionManagerConfig::createFilterChainForFactories( } } -void HttpConnectionManagerConfig::createFilterChain(Http::FilterChainFactoryCallbacks& callbacks) { +void HttpConnectionManagerConfig::createFilterChain( + Envoy::Http::FilterChainFactoryCallbacks& callbacks) { createFilterChainForFactories(callbacks, filter_factories_); } bool HttpConnectionManagerConfig::createUpgradeFilterChain( absl::string_view upgrade_type, - const Http::FilterChainFactory::UpgradeMap* per_route_upgrade_map, - Http::FilterChainFactoryCallbacks& callbacks) { + const Envoy::Http::FilterChainFactory::UpgradeMap* per_route_upgrade_map, + Envoy::Http::FilterChainFactoryCallbacks& callbacks) { bool route_enabled = false; if (per_route_upgrade_map) { auto route_it = findUpgradeBoolCaseInsensitive(*per_route_upgrade_map, upgrade_type); @@ -712,7 +717,7 @@ const envoy::config::trace::v3::Tracing_Http* HttpConnectionManagerConfig::getPe return nullptr; } -std::function +std::function HttpConnectionManagerFactory::createHttpConnectionManagerFactoryFromProto( const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& proto_config, @@ -729,8 +734,8 @@ HttpConnectionManagerFactory::createHttpConnectionManagerFactoryFromProto( // reference count. // Keep in mind the lambda capture list **doesn't** determine the destruction order, but it's fine // as these captured objects are also global singletons. - return [singletons, filter_config, &context, &read_callbacks]() -> Http::ApiListenerPtr { - auto conn_manager = std::make_unique( + return [singletons, filter_config, &context, &read_callbacks]() -> Envoy::Http::ApiListenerPtr { + auto conn_manager = std::make_unique( *filter_config, context.drainDecision(), context.api().randomGenerator(), context.httpContext(), context.runtime(), context.localInfo(), context.clusterManager(), context.overloadManager(), context.dispatcher().timeSource()); diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 4b440704b668..37f1b664a9a4 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -1047,7 +1047,7 @@ TEST_F(HttpConnectionManagerConfigTest, RemovePortDefault) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - EXPECT_EQ(Http::StripPortType::None, config.stripPortType()); + EXPECT_EQ(Envoy::Http::StripPortType::None, config.stripPortType()); } // Validated that when configured, we remove port. @@ -1065,7 +1065,7 @@ TEST_F(HttpConnectionManagerConfigTest, RemovePortTrue) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - EXPECT_EQ(Http::StripPortType::MatchingHost, config.stripPortType()); + EXPECT_EQ(Envoy::Http::StripPortType::MatchingHost, config.stripPortType()); } // Validated that when both strip options are configured, we throw exception. @@ -1104,7 +1104,7 @@ TEST_F(HttpConnectionManagerConfigTest, RemovePortFalse) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - EXPECT_EQ(Http::StripPortType::None, config.stripPortType()); + EXPECT_EQ(Envoy::Http::StripPortType::None, config.stripPortType()); } // Validated that when configured, we remove any port. @@ -1122,7 +1122,7 @@ TEST_F(HttpConnectionManagerConfigTest, RemoveAnyPortTrue) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - EXPECT_EQ(Http::StripPortType::Any, config.stripPortType()); + EXPECT_EQ(Envoy::Http::StripPortType::Any, config.stripPortType()); } // Validated that when explicitly set false, we don't remove any port. @@ -1140,7 +1140,7 @@ TEST_F(HttpConnectionManagerConfigTest, RemoveAnyPortFalse) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - EXPECT_EQ(Http::StripPortType::None, config.stripPortType()); + EXPECT_EQ(Envoy::Http::StripPortType::None, config.stripPortType()); } // Validated that by default we allow requests with header names containing underscores. @@ -1646,20 +1646,21 @@ TEST_F(HttpConnectionManagerConfigTest, AlwaysSetRequestIdInResponseConfigured) namespace { -class TestRequestIDExtension : public Http::RequestIDExtension { +class TestRequestIDExtension : public Envoy::Http::RequestIDExtension { public: TestRequestIDExtension(const test::http_connection_manager::CustomRequestIDExtension& config) : config_(config) {} - void set(Http::RequestHeaderMap&, bool) override {} - void setInResponse(Http::ResponseHeaderMap&, const Http::RequestHeaderMap&) override {} - absl::optional toInteger(const Http::RequestHeaderMap&) const override { + void set(Envoy::Http::RequestHeaderMap&, bool) override {} + void setInResponse(Envoy::Http::ResponseHeaderMap&, + const Envoy::Http::RequestHeaderMap&) override {} + absl::optional toInteger(const Envoy::Http::RequestHeaderMap&) const override { return absl::nullopt; } - Tracing::Reason getTraceReason(const Http::RequestHeaderMap&) override { + Tracing::Reason getTraceReason(const Envoy::Http::RequestHeaderMap&) override { return Tracing::Reason::Sampling; } - void setTraceReason(Http::RequestHeaderMap&, Tracing::Reason) override {} + void setTraceReason(Envoy::Http::RequestHeaderMap&, Tracing::Reason) override {} std::string testField() { return config_.test_field(); } @@ -1677,7 +1678,7 @@ class TestRequestIDExtensionFactory : public Server::Configuration::RequestIDExt return std::make_unique(); } - Http::RequestIDExtensionSharedPtr + Envoy::Http::RequestIDExtensionSharedPtr createExtensionInstance(const Protobuf::Message& config, Server::Configuration::FactoryContext& context) override { const auto& custom_config = MessageUtil::downcastAndValidate< @@ -1793,9 +1794,10 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { namespace { -class OriginalIPDetectionExtensionNotCreatedFactory : public Http::OriginalIPDetectionFactory { +class OriginalIPDetectionExtensionNotCreatedFactory + : public Envoy::Http::OriginalIPDetectionFactory { public: - Http::OriginalIPDetectionSharedPtr + Envoy::Http::OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message&, Server::Configuration::FactoryContext&) override { return nullptr; } @@ -1813,7 +1815,7 @@ class OriginalIPDetectionExtensionNotCreatedFactory : public Http::OriginalIPDet TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtensionNotCreated) { OriginalIPDetectionExtensionNotCreatedFactory factory; - Registry::InjectFactory registration(factory); + Registry::InjectFactory registration(factory); const std::string yaml_string = R"EOF( stat_prefix: ingress_http @@ -1855,8 +1857,9 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { auto original_ip_detection_extensions = config.originalIpDetectionExtensions(); EXPECT_EQ(1, original_ip_detection_extensions.size()); - auto* extension = dynamic_cast( - original_ip_detection_extensions[0].get()); + auto* extension = + dynamic_cast( + original_ip_detection_extensions[0].get()); EXPECT_NE(nullptr, extension); } diff --git a/test/extensions/filters/network/http_connection_manager/config_test_base.h b/test/extensions/filters/network/http_connection_manager/config_test_base.h index a0ce9792af31..35cd5084f197 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test_base.h +++ b/test/extensions/filters/network/http_connection_manager/config_test_base.h @@ -31,7 +31,7 @@ parseHttpConnectionManagerFromYaml(const std::string& yaml, bool avoid_boosting class HttpConnectionManagerConfigTest : public testing::Test { public: NiceMock context_; - Http::SlowDateProviderImpl date_provider_{context_.dispatcher().timeSource()}; + Envoy::Http::SlowDateProviderImpl date_provider_{context_.dispatcher().timeSource()}; NiceMock route_config_provider_manager_; NiceMock scoped_routes_config_provider_manager_; NiceMock http_tracer_manager_; From 129b0bfe890c4b0e4969c1715a4810af49fc7dfb Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 9 Apr 2021 09:16:46 -0400 Subject: [PATCH 073/100] Expand integration test Signed-off-by: Raul Gutierrez Segales --- .../original_ip_detection_integration_test.cc | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/test/integration/original_ip_detection_integration_test.cc b/test/integration/original_ip_detection_integration_test.cc index 0dd85bb7c391..9fa25edce17e 100644 --- a/test/integration/original_ip_detection_integration_test.cc +++ b/test/integration/original_ip_detection_integration_test.cc @@ -11,35 +11,45 @@ using testing::HasSubstr; namespace Envoy { namespace Formatter { -class OriginalIPDetectionIntegrationTest : public testing::Test, public HttpIntegrationTest { +class OriginalIPDetectionIntegrationTest + : public testing::TestWithParam, + public HttpIntegrationTest { public: OriginalIPDetectionIntegrationTest() - : HttpIntegrationTest(Http::CodecClient::Type::HTTP1, Network::Address::IpVersion::v4) {} + : HttpIntegrationTest(Http::CodecClient::Type::HTTP1, GetParam()) {} + + void runTest(const std::string& ip) { + useAccessLog("%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%"); + config_helper_.addConfigModifier( + [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& + hcm) -> void { + envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig + config; + config.set_header_name("x-cdn-detected-ip"); + + auto* extension = hcm.add_original_ip_detection_extensions(); + extension->set_name("envoy.http.original_ip_detection.custom_header"); + extension->mutable_typed_config()->PackFrom(config); + + hcm.mutable_use_remote_address()->set_value(false); + }); + initialize(); + auto raw_http = + fmt::format("GET / HTTP/1.1\r\nHost: host\r\nx-cdn-detected-ip: {}\r\n\r\n", ip); + std::string response; + sendRawHttpAndWaitForResponse(lookupPort("http"), raw_http.c_str(), &response, true); + std::string log = waitForAccessLog(access_log_name_); + EXPECT_THAT(log, HasSubstr(ip)); + } }; -TEST_F(OriginalIPDetectionIntegrationTest, HeaderBasedDetection) { - useAccessLog("%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%"); - config_helper_.addConfigModifier( - [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& - hcm) -> void { - envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig - config; - config.set_header_name("x-cdn-detected-ip"); - - auto* extension = hcm.add_original_ip_detection_extensions(); - extension->set_name("envoy.http.original_ip_detection.custom_header"); - extension->mutable_typed_config()->PackFrom(config); - - hcm.mutable_use_remote_address()->set_value(false); - }); - initialize(); - std::string response; - sendRawHttpAndWaitForResponse( - lookupPort("http"), "GET / HTTP/1.1\r\nHost: host\r\nx-cdn-detected-ip: 9.9.9.9\r\n\r\n", - &response, true); - std::string log = waitForAccessLog(access_log_name_); - EXPECT_THAT(log, HasSubstr("9.9.9.9")); -} +INSTANTIATE_TEST_SUITE_P(IpVersions, OriginalIPDetectionIntegrationTest, + testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), + TestUtility::ipTestParamsToString); + +TEST_P(OriginalIPDetectionIntegrationTest, HeaderBasedDetectionIPv4) { runTest("9.9.9.9"); } + +TEST_P(OriginalIPDetectionIntegrationTest, HeaderBasedDetectionIPv6) { runTest("fc00::1"); } } // namespace Formatter } // namespace Envoy From c338b652bd5af197618394834c728376f1e1fb1f Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 9 Apr 2021 10:56:10 -0400 Subject: [PATCH 074/100] Validate header name I am unsure what the right approach for enforcing validation is: 1) setting `strict: true` in the proto file (most likely not) 2) using ProtobufMessage::getStrictValidationVisitor() instead of the context validator 3) forcing the test to do strict validation I went with 1) for now, otherwise regex validation isn't happening in the added test. Signed-off-by: Raul Gutierrez Segales --- .../custom_header/v3/custom_header.proto | 2 +- .../custom_header/v3/custom_header.proto | 2 +- .../custom_header/config_test.cc | 20 +++++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 3c54a7e93059..4571cc0c2cba 100644 --- a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -39,7 +39,7 @@ message CustomHeaderConfig { // // Note: in the case of a multi-valued header, only the first value is tried and the rest are ignored. string header_name = 1 - [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: false}]; + [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: true}]; // If set to true, the extension is allowed to decide if the detected address should be treated as // trusted. If a detected address is considered trusted, it might be used as input to determine diff --git a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 3c54a7e93059..4571cc0c2cba 100644 --- a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -39,7 +39,7 @@ message CustomHeaderConfig { // // Note: in the case of a multi-valued header, only the first value is tried and the rest are ignored. string header_name = 1 - [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: false}]; + [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: true}]; // If set to true, the extension is allowed to decide if the detected address should be treated as // trusted. If a detected address is considered trusted, it might be used as input to determine diff --git a/test/extensions/http/original_ip_detection/custom_header/config_test.cc b/test/extensions/http/original_ip_detection/custom_header/config_test.cc index e617c465948a..54e42644c053 100644 --- a/test/extensions/http/original_ip_detection/custom_header/config_test.cc +++ b/test/extensions/http/original_ip_detection/custom_header/config_test.cc @@ -32,6 +32,26 @@ TEST(CustomHeaderFactoryTest, Basic) { EXPECT_NE(factory->createExtension(typed_config.typed_config(), context), nullptr); } +TEST(CustomHeaderFactoryTest, InvalidHeaderName) { + auto* factory = Registry::FactoryRegistry::getFactory( + "envoy.http.original_ip_detection.custom_header"); + ASSERT_NE(factory, nullptr); + + envoy::config::core::v3::TypedExtensionConfig typed_config; + const std::string yaml = R"EOF( + name: envoy.formatter.TestFormatter + typed_config: + "@type": type.googleapis.com/envoy.extensions.http.original_ip_detection.custom_header.v3.CustomHeaderConfig + header_name: " " +)EOF"; + TestUtility::loadFromYaml(yaml, typed_config); + + NiceMock context; + EXPECT_THROW_WITH_REGEX(factory->createExtension(typed_config.typed_config(), context), + EnvoyException, + "Proto constraint validation failed.*does not match regex pattern.*"); +} + } // namespace CustomHeader } // namespace OriginalIPDetection } // namespace Http From 91806ca5081362325478131f5e355ea3e91562dd Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 15 Apr 2021 17:50:15 -0400 Subject: [PATCH 075/100] Matt's feedback * rename single_address_ * disable docs for custom key * avoid namespace pollution * document proto restrictions for status_code Signed-off-by: Raul Gutierrez Segales --- .../custom_header/v3/custom_header.proto | 4 + .../custom_header/v3/custom_header.proto | 4 + source/common/http/utility.h | 2 +- source/extensions/all_extensions.bzl | 1 + .../network/http_connection_manager/BUILD | 2 +- .../network/http_connection_manager/config.cc | 177 +++++++++--------- .../http/original_ip_detection/xff/xff.cc | 2 +- source/extensions/request_id/uuid/config.h | 20 +- test/common/http/utility_test.cc | 30 +-- .../network/http_connection_manager/BUILD | 2 - .../http_connection_manager/config_test.cc | 38 ++-- .../config_test_base.h | 2 +- 12 files changed, 140 insertions(+), 144 deletions(-) diff --git a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 4571cc0c2cba..2dd2346a4280 100644 --- a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -14,6 +14,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Custom header original IP detection extension] +// [#not-implemented-hide:] // This extension allows for the original downstream remote IP to be detected // by reading the value from a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such @@ -28,6 +29,9 @@ message CustomHeaderConfig { message RejectOptions { // If reject_request_if_detection_fails is set, this sets the HTTP status that is sent downstream // when detection fails. The default status is HTTP 403 Forbidden. + // + // .. note:: + // If this is set to < 400, the default status 403 will be used instead. type.v3.HttpStatus status_on_error = 1; // If reject_request_if_detection_fails is set, this sets the HTTP body in the response diff --git a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 4571cc0c2cba..2dd2346a4280 100644 --- a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -14,6 +14,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Custom header original IP detection extension] +// [#not-implemented-hide:] // This extension allows for the original downstream remote IP to be detected // by reading the value from a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such @@ -28,6 +29,9 @@ message CustomHeaderConfig { message RejectOptions { // If reject_request_if_detection_fails is set, this sets the HTTP status that is sent downstream // when detection fails. The default status is HTTP 403 Forbidden. + // + // .. note:: + // If this is set to < 400, the default status 403 will be used instead. type.v3.HttpStatus status_on_error = 1; // If reject_request_if_detection_fails is set, this sets the HTTP body in the response diff --git a/source/common/http/utility.h b/source/common/http/utility.h index 64d85613ee1a..1263691949b1 100644 --- a/source/common/http/utility.h +++ b/source/common/http/utility.h @@ -342,7 +342,7 @@ struct GetLastAddressFromXffInfo { // Last valid address pulled from the XFF header. Network::Address::InstanceConstSharedPtr address_; // Whether this is the only address in the XFF header. - bool single_address_; + bool allow_trusted_address_checks_; }; /** diff --git a/source/extensions/all_extensions.bzl b/source/extensions/all_extensions.bzl index f1f2f9901850..761c3c75e0bc 100644 --- a/source/extensions/all_extensions.bzl +++ b/source/extensions/all_extensions.bzl @@ -5,6 +5,7 @@ load("@envoy_build_config//:extensions_build_config.bzl", "EXTENSIONS") # The map may be overridden by extensions specified in envoy_build_config. _required_extensions = { "envoy.common.crypto.utility_lib": "//source/extensions/common/crypto:utility_lib", + "envoy.http.original_ip_detection.xff": "//source/extensions/http/original_ip_detection/xff:config", "envoy.request_id.uuid": "//source/extensions/request_id/uuid:config", "envoy.transport_sockets.tls": "//source/extensions/transport_sockets/tls:config", } diff --git a/source/extensions/filters/network/http_connection_manager/BUILD b/source/extensions/filters/network/http_connection_manager/BUILD index 8f791c20d3fb..31a0a7d642a7 100644 --- a/source/extensions/filters/network/http_connection_manager/BUILD +++ b/source/extensions/filters/network/http_connection_manager/BUILD @@ -58,10 +58,10 @@ envoy_cc_extension( "//source/extensions/filters/http/common:pass_through_filter_lib", "//source/extensions/filters/network:well_known_names", "//source/extensions/filters/network/common:factory_base_lib", - "//source/extensions/http/original_ip_detection/xff:xff_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/request_id/uuid/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/http/original_ip_detection/xff/v3:pkg_cc_proto", "@envoy_api//envoy/type/tracing/v3:pkg_cc_proto", "@envoy_api//envoy/type/v3:pkg_cc_proto", ] + envoy_select_enable_http3([ diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 0c6e8067762e..d1986a36ffe1 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -9,6 +9,7 @@ #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h" #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.validate.h" #include "envoy/extensions/request_id/uuid/v3/uuid.pb.h" +#include "envoy/extensions/http/original_ip_detection/xff/v3/xff.pb.h" #include "envoy/filesystem/filesystem.h" #include "envoy/registry/registry.h" #include "envoy/server/admin.h" @@ -41,7 +42,6 @@ #endif #include "extensions/filters/http/common/pass_through_filter.h" -#include "extensions/http/original_ip_detection/xff/xff.h" namespace Envoy { namespace Extensions { @@ -49,7 +49,7 @@ namespace NetworkFilters { namespace HttpConnectionManager { namespace { -using FilterFactoriesList = std::list; +using FilterFactoriesList = std::list; using FilterFactoryMap = std::map; HttpConnectionManagerConfig::UpgradeMap::const_iterator @@ -73,23 +73,23 @@ FilterFactoryMap::const_iterator findUpgradeCaseInsensitive(const FilterFactoryM return upgrade_map.end(); } -std::unique_ptr createInternalAddressConfig( +std::unique_ptr createInternalAddressConfig( const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& config) { if (config.has_internal_address_config()) { return std::make_unique(config.internal_address_config()); } - return std::make_unique(); + return std::make_unique(); } -class MissingConfigFilter : public Envoy::Http::PassThroughDecoderFilter { +class MissingConfigFilter : public Http::PassThroughDecoderFilter { public: - Envoy::Http::FilterHeadersStatus decodeHeaders(Envoy::Http::RequestHeaderMap&, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool) override { decoder_callbacks_->streamInfo().setResponseFlag(StreamInfo::ResponseFlag::NoFilterConfigFound); - decoder_callbacks_->sendLocalReply(Envoy::Http::Code::InternalServerError, EMPTY_STRING, - nullptr, absl::nullopt, EMPTY_STRING); - return Envoy::Http::FilterHeadersStatus::StopIteration; + decoder_callbacks_->sendLocalReply(Http::Code::InternalServerError, EMPTY_STRING, nullptr, + absl::nullopt, EMPTY_STRING); + return Http::FilterHeadersStatus::StopIteration; } }; @@ -103,11 +103,11 @@ SINGLETON_MANAGER_REGISTRATION(http_tracer_manager); SINGLETON_MANAGER_REGISTRATION(filter_config_provider_manager); Utility::Singletons Utility::createSingletons(Server::Configuration::FactoryContext& context) { - std::shared_ptr date_provider = - context.singletonManager().getTyped( + std::shared_ptr date_provider = + context.singletonManager().getTyped( SINGLETON_MANAGER_REGISTERED_NAME(date_provider), [&context] { - return std::make_shared(context.dispatcher(), - context.threadLocal()); + return std::make_shared(context.dispatcher(), + context.threadLocal()); }); Router::RouteConfigProviderManagerSharedPtr route_config_provider_manager = @@ -143,7 +143,7 @@ Utility::Singletons Utility::createSingletons(Server::Configuration::FactoryCont std::shared_ptr Utility::createConfig( const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& proto_config, - Server::Configuration::FactoryContext& context, Envoy::Http::DateProvider& date_provider, + Server::Configuration::FactoryContext& context, Http::DateProvider& date_provider, Router::RouteConfigProviderManager& route_config_provider_manager, Config::ConfigProviderManager& scoped_routes_config_provider_manager, Tracing::HttpTracerManager& http_tracer_manager, @@ -170,11 +170,10 @@ HttpConnectionManagerFilterConfigFactory::createFilterFactoryFromProtoTyped( // Keep in mind the lambda capture list **doesn't** determine the destruction order, but it's fine // as these captured objects are also global singletons. return [singletons, filter_config, &context](Network::FilterManager& filter_manager) -> void { - filter_manager.addReadFilter( - Network::ReadFilterSharedPtr{new Envoy::Http::ConnectionManagerImpl( - *filter_config, context.drainDecision(), context.api().randomGenerator(), - context.httpContext(), context.runtime(), context.localInfo(), context.clusterManager(), - context.overloadManager(), context.dispatcher().timeSource())}); + filter_manager.addReadFilter(Network::ReadFilterSharedPtr{new Http::ConnectionManagerImpl( + *filter_config, context.drainDecision(), context.api().randomGenerator(), + context.httpContext(), context.runtime(), context.localInfo(), context.clusterManager(), + context.overloadManager(), context.dispatcher().timeSource())}); }; } @@ -193,15 +192,15 @@ InternalAddressConfig::InternalAddressConfig( HttpConnectionManagerConfig::HttpConnectionManagerConfig( const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& config, - Server::Configuration::FactoryContext& context, Envoy::Http::DateProvider& date_provider, + Server::Configuration::FactoryContext& context, Http::DateProvider& date_provider, Router::RouteConfigProviderManager& route_config_provider_manager, Config::ConfigProviderManager& scoped_routes_config_provider_manager, Tracing::HttpTracerManager& http_tracer_manager, Filter::Http::FilterConfigProviderManager& filter_config_provider_manager) : context_(context), stats_prefix_(fmt::format("http.{}.", config.stat_prefix())), - stats_(Envoy::Http::ConnectionManagerImpl::generateStats(stats_prefix_, context_.scope())), - tracing_stats_(Envoy::Http::ConnectionManagerImpl::generateTracingStats(stats_prefix_, - context_.scope())), + stats_(Http::ConnectionManagerImpl::generateStats(stats_prefix_, context_.scope())), + tracing_stats_( + Http::ConnectionManagerImpl::generateTracingStats(stats_prefix_, context_.scope())), use_remote_address_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, use_remote_address, false)), internal_address_config_(createInternalAddressConfig(config)), xff_num_trusted_hops_(config.xff_num_trusted_hops()), @@ -215,16 +214,16 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( http2_options_(Http2::Utility::initializeAndValidateOptions( config.http2_protocol_options(), config.has_stream_error_on_invalid_http_message(), config.stream_error_on_invalid_http_message())), - http1_settings_(Envoy::Http::Http1::parseHttp1Settings( + http1_settings_(Http::Http1::parseHttp1Settings( config.http_protocol_options(), context.messageValidationVisitor(), config.stream_error_on_invalid_http_message(), xff_num_trusted_hops_ == 0 && use_remote_address_)), max_request_headers_kb_(PROTOBUF_GET_WRAPPED_OR_DEFAULT( - config, max_request_headers_kb, Envoy::Http::DEFAULT_MAX_REQUEST_HEADERS_KB)), + config, max_request_headers_kb, Http::DEFAULT_MAX_REQUEST_HEADERS_KB)), max_request_headers_count_(PROTOBUF_GET_WRAPPED_OR_DEFAULT( config.common_http_protocol_options(), max_headers_count, - context.runtime().snapshot().getInteger(Envoy::Http::MaxRequestHeadersCountOverrideKey, - Envoy::Http::DEFAULT_MAX_HEADERS_COUNT))), + context.runtime().snapshot().getInteger(Http::MaxRequestHeadersCountOverrideKey, + Http::DEFAULT_MAX_HEADERS_COUNT))), idle_timeout_(PROTOBUF_GET_OPTIONAL_MS(config.common_http_protocol_options(), idle_timeout)), max_connection_duration_( PROTOBUF_GET_OPTIONAL_MS(config.common_http_protocol_options(), max_connection_duration)), @@ -240,8 +239,8 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( preserve_external_request_id_(config.preserve_external_request_id()), always_set_request_id_in_response_(config.always_set_request_id_in_response()), date_provider_(date_provider), - listener_stats_(Envoy::Http::ConnectionManagerImpl::generateListenerStats( - stats_prefix_, context_.listenerScope())), + listener_stats_(Http::ConnectionManagerImpl::generateListenerStats(stats_prefix_, + context_.listenerScope())), proxy_100_continue_(config.proxy_100_continue()), stream_error_on_invalid_http_messaging_( PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, stream_error_on_invalid_http_message, false)), @@ -281,11 +280,11 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( } if (config.strip_any_host_port()) { - strip_port_type_ = Envoy::Http::StripPortType::Any; + strip_port_type_ = Http::StripPortType::Any; } else if (config.strip_matching_host_port()) { - strip_port_type_ = Envoy::Http::StripPortType::MatchingHost; + strip_port_type_ = Http::StripPortType::MatchingHost; } else { - strip_port_type_ = Envoy::Http::StripPortType::None; + strip_port_type_ = Http::StripPortType::None; } // If we are provided a different request_id_extension implementation to use try and create a @@ -298,32 +297,34 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( final_rid_config.mutable_typed_config()->PackFrom( envoy::extensions::request_id::uuid::v3::UuidRequestIdConfig()); } - request_id_extension_ = - Envoy::Http::RequestIDExtensionFactory::fromProto(final_rid_config, context_); - - // Check if IP detection extensions were configured. - const auto& ip_detection_extensions = config.original_ip_detection_extensions(); - if (!ip_detection_extensions.empty()) { - original_ip_detection_extensions_.reserve(ip_detection_extensions.size()); - for (const auto& extension_config : ip_detection_extensions) { - auto* factory = Envoy::Config::Utility::getFactory( - extension_config); - if (!factory) { - throw EnvoyException(fmt::format("Original IP detection extension not found: '{}'", - extension_config.name())); - } + request_id_extension_ = Http::RequestIDExtensionFactory::fromProto(final_rid_config, context_); - auto extension = factory->createExtension(extension_config.typed_config(), context_); - if (!extension) { - throw EnvoyException(fmt::format( - "Original IP detection extension could not be created: '{}'", extension_config.name())); - } - original_ip_detection_extensions_.push_back(extension); + // Check if IP detection extensions were configured, otherwise fallback to XFF. + auto ip_detection_extensions = config.original_ip_detection_extensions(); + if (ip_detection_extensions.empty()) { + envoy::extensions::http::original_ip_detection::xff::v3::XffConfig xff_config; + xff_config.set_xff_num_trusted_hops(xff_num_trusted_hops_); + + auto* extension = ip_detection_extensions.Add(); + extension->set_name("envoy.http.original_ip_detection.xff"); + extension->mutable_typed_config()->PackFrom(xff_config); + } + + original_ip_detection_extensions_.reserve(ip_detection_extensions.size()); + for (const auto& extension_config : ip_detection_extensions) { + auto* factory = + Envoy::Config::Utility::getFactory(extension_config); + if (!factory) { + throw EnvoyException( + fmt::format("Original IP detection extension not found: '{}'", extension_config.name())); } - } else { - original_ip_detection_extensions_.push_back( - std::make_shared( - xff_num_trusted_hops_)); + + auto extension = factory->createExtension(extension_config.typed_config(), context_); + if (!extension) { + throw EnvoyException(fmt::format("Original IP detection extension could not be created: '{}'", + extension_config.name())); + } + original_ip_detection_extensions_.push_back(extension); } // If scoped RDS is enabled, avoid creating a route config provider. Route config providers will @@ -350,23 +351,23 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( switch (config.forward_client_cert_details()) { case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: SANITIZE: - forward_client_cert_ = Envoy::Http::ForwardClientCertType::Sanitize; + forward_client_cert_ = Http::ForwardClientCertType::Sanitize; break; case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: FORWARD_ONLY: - forward_client_cert_ = Envoy::Http::ForwardClientCertType::ForwardOnly; + forward_client_cert_ = Http::ForwardClientCertType::ForwardOnly; break; case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: APPEND_FORWARD: - forward_client_cert_ = Envoy::Http::ForwardClientCertType::AppendForward; + forward_client_cert_ = Http::ForwardClientCertType::AppendForward; break; case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: SANITIZE_SET: - forward_client_cert_ = Envoy::Http::ForwardClientCertType::SanitizeSet; + forward_client_cert_ = Http::ForwardClientCertType::SanitizeSet; break; case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: ALWAYS_FORWARD_ONLY: - forward_client_cert_ = Envoy::Http::ForwardClientCertType::AlwaysForwardOnly; + forward_client_cert_ = Http::ForwardClientCertType::AlwaysForwardOnly; break; default: NOT_REACHED_GCOVR_EXCL_LINE; @@ -374,19 +375,19 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( const auto& set_current_client_cert_details = config.set_current_client_cert_details(); if (set_current_client_cert_details.cert()) { - set_current_client_cert_details_.push_back(Envoy::Http::ClientCertDetailsType::Cert); + set_current_client_cert_details_.push_back(Http::ClientCertDetailsType::Cert); } if (set_current_client_cert_details.chain()) { - set_current_client_cert_details_.push_back(Envoy::Http::ClientCertDetailsType::Chain); + set_current_client_cert_details_.push_back(Http::ClientCertDetailsType::Chain); } if (PROTOBUF_GET_WRAPPED_OR_DEFAULT(set_current_client_cert_details, subject, false)) { - set_current_client_cert_details_.push_back(Envoy::Http::ClientCertDetailsType::Subject); + set_current_client_cert_details_.push_back(Http::ClientCertDetailsType::Subject); } if (set_current_client_cert_details.uri()) { - set_current_client_cert_details_.push_back(Envoy::Http::ClientCertDetailsType::URI); + set_current_client_cert_details_.push_back(Http::ClientCertDetailsType::URI); } if (set_current_client_cert_details.dns()) { - set_current_client_cert_details_.push_back(Envoy::Http::ClientCertDetailsType::DNS); + set_current_client_cert_details_.push_back(Http::ClientCertDetailsType::DNS); } if (config.has_add_user_agent() && config.add_user_agent().value()) { @@ -456,8 +457,8 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( const uint32_t max_path_tag_length = PROTOBUF_GET_WRAPPED_OR_DEFAULT( tracing_config, max_path_tag_length, Tracing::DefaultMaxPathTagLength); - tracing_config_ = std::make_unique( - Envoy::Http::TracingConnectionManagerConfig{ + tracing_config_ = + std::make_unique(Http::TracingConnectionManagerConfig{ tracing_operation_name, custom_tags, client_sampling, random_sampling, overall_sampling, tracing_config.verbose(), max_path_tag_length}); } @@ -473,7 +474,7 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( if (!config.server_name().empty()) { server_name_ = config.server_name(); } else { - server_name_ = Envoy::Http::DefaultServerString::get(); + server_name_ = Http::DefaultServerString::get(); } switch (config.codec_type()) { @@ -550,7 +551,7 @@ void HttpConnectionManagerConfig::processFilter( proto_config); ProtobufTypes::MessagePtr message = Config::Utility::translateToFactoryConfig( proto_config, context_.messageValidationVisitor(), factory); - Envoy::Http::FilterFactoryCb callback = + Http::FilterFactoryCb callback = factory.createFilterFactoryFromProto(*message, stats_prefix_, context_); bool is_terminal = factory.isTerminalFilter(); Config::Utility::validateTerminalFilters(proto_config.name(), factory.name(), filter_chain_type, @@ -596,21 +597,21 @@ void HttpConnectionManagerConfig::processDynamicFilterConfig( filter_factories.push_back(std::move(filter_config_provider)); } -Envoy::Http::ServerConnectionPtr +Http::ServerConnectionPtr HttpConnectionManagerConfig::createCodec(Network::Connection& connection, const Buffer::Instance& data, - Envoy::Http::ServerConnectionCallbacks& callbacks) { + Http::ServerConnectionCallbacks& callbacks) { switch (codec_type_) { case CodecType::HTTP1: { - return std::make_unique( - connection, Envoy::Http::Http1::CodecStats::atomicGet(http1_codec_stats_, context_.scope()), + return std::make_unique( + connection, Http::Http1::CodecStats::atomicGet(http1_codec_stats_, context_.scope()), callbacks, http1_settings_, maxRequestHeadersKb(), maxRequestHeadersCount(), headersWithUnderscoresAction()); } case CodecType::HTTP2: { - return std::make_unique( + return std::make_unique( connection, callbacks, - Envoy::Http::Http2::CodecStats::atomicGet(http2_codec_stats_, context_.scope()), + Http::Http2::CodecStats::atomicGet(http2_codec_stats_, context_.scope()), context_.api().randomGenerator(), http2_options_, maxRequestHeadersKb(), maxRequestHeadersCount(), headersWithUnderscoresAction()); } @@ -618,14 +619,14 @@ HttpConnectionManagerConfig::createCodec(Network::Connection& connection, #ifdef ENVOY_ENABLE_QUIC return std::make_unique( dynamic_cast(connection), callbacks, - Envoy::Http::Http3::CodecStats::atomicGet(http3_codec_stats_, context_.scope()), - http3_options_, maxRequestHeadersKb(), headersWithUnderscoresAction()); + Http::Http3::CodecStats::atomicGet(http3_codec_stats_, context_.scope()), http3_options_, + maxRequestHeadersKb(), headersWithUnderscoresAction()); #else // Should be blocked by configuration checking at an earlier point. NOT_REACHED_GCOVR_EXCL_LINE; #endif case CodecType::AUTO: - return Envoy::Http::ConnectionManagerUtility::autoCreateCodec( + return Http::ConnectionManagerUtility::autoCreateCodec( connection, data, callbacks, context_.scope(), context_.api().randomGenerator(), http1_codec_stats_, http2_codec_stats_, http1_settings_, http2_options_, maxRequestHeadersKb(), maxRequestHeadersCount(), headersWithUnderscoresAction()); @@ -634,8 +635,7 @@ HttpConnectionManagerConfig::createCodec(Network::Connection& connection, } void HttpConnectionManagerConfig::createFilterChainForFactories( - Envoy::Http::FilterChainFactoryCallbacks& callbacks, - const FilterFactoriesList& filter_factories) { + Http::FilterChainFactoryCallbacks& callbacks, const FilterFactoriesList& filter_factories) { bool added_missing_config_filter = false; for (const auto& filter_config_provider : filter_factories) { auto config = filter_config_provider->config(); @@ -648,7 +648,7 @@ void HttpConnectionManagerConfig::createFilterChainForFactories( if (!added_missing_config_filter) { ENVOY_LOG(trace, "Missing filter config for a provider {}", filter_config_provider->name()); callbacks.addStreamDecoderFilter( - Envoy::Http::StreamDecoderFilterSharedPtr{std::make_shared()}); + Http::StreamDecoderFilterSharedPtr{std::make_shared()}); added_missing_config_filter = true; } else { ENVOY_LOG(trace, "Provider {} missing a filter config", filter_config_provider->name()); @@ -656,15 +656,14 @@ void HttpConnectionManagerConfig::createFilterChainForFactories( } } -void HttpConnectionManagerConfig::createFilterChain( - Envoy::Http::FilterChainFactoryCallbacks& callbacks) { +void HttpConnectionManagerConfig::createFilterChain(Http::FilterChainFactoryCallbacks& callbacks) { createFilterChainForFactories(callbacks, filter_factories_); } bool HttpConnectionManagerConfig::createUpgradeFilterChain( absl::string_view upgrade_type, - const Envoy::Http::FilterChainFactory::UpgradeMap* per_route_upgrade_map, - Envoy::Http::FilterChainFactoryCallbacks& callbacks) { + const Http::FilterChainFactory::UpgradeMap* per_route_upgrade_map, + Http::FilterChainFactoryCallbacks& callbacks) { bool route_enabled = false; if (per_route_upgrade_map) { auto route_it = findUpgradeBoolCaseInsensitive(*per_route_upgrade_map, upgrade_type); @@ -717,7 +716,7 @@ const envoy::config::trace::v3::Tracing_Http* HttpConnectionManagerConfig::getPe return nullptr; } -std::function +std::function HttpConnectionManagerFactory::createHttpConnectionManagerFactoryFromProto( const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& proto_config, @@ -734,8 +733,8 @@ HttpConnectionManagerFactory::createHttpConnectionManagerFactoryFromProto( // reference count. // Keep in mind the lambda capture list **doesn't** determine the destruction order, but it's fine // as these captured objects are also global singletons. - return [singletons, filter_config, &context, &read_callbacks]() -> Envoy::Http::ApiListenerPtr { - auto conn_manager = std::make_unique( + return [singletons, filter_config, &context, &read_callbacks]() -> Http::ApiListenerPtr { + auto conn_manager = std::make_unique( *filter_config, context.drainDecision(), context.api().randomGenerator(), context.httpContext(), context.runtime(), context.localInfo(), context.clusterManager(), context.overloadManager(), context.dispatcher().timeSource()); diff --git a/source/extensions/http/original_ip_detection/xff/xff.cc b/source/extensions/http/original_ip_detection/xff/xff.cc index 4600fb6774e7..70f142bb52df 100644 --- a/source/extensions/http/original_ip_detection/xff/xff.cc +++ b/source/extensions/http/original_ip_detection/xff/xff.cc @@ -19,7 +19,7 @@ Envoy::Http::OriginalIPDetectionResult XffIPDetection::detect(Envoy::Http::OriginalIPDetectionParams& params) { auto ret = Envoy::Http::Utility::getLastAddressFromXFF(params.request_headers, xff_num_trusted_hops_); - return {ret.address_, ret.single_address_, absl::nullopt}; + return {ret.address_, ret.allow_trusted_address_checks_, absl::nullopt}; } } // namespace Xff diff --git a/source/extensions/request_id/uuid/config.h b/source/extensions/request_id/uuid/config.h index 92d5e68d617d..bd21f9eaa6bc 100644 --- a/source/extensions/request_id/uuid/config.h +++ b/source/extensions/request_id/uuid/config.h @@ -11,14 +11,14 @@ namespace RequestId { // UUIDRequestIDExtension is the default implementation if no other extension is explicitly // configured. -class UUIDRequestIDExtension : public Envoy::Http::RequestIDExtension { +class UUIDRequestIDExtension : public Http::RequestIDExtension { public: UUIDRequestIDExtension(const envoy::extensions::request_id::uuid::v3::UuidRequestIdConfig& config, Random::RandomGenerator& random) : random_(random), pack_trace_reason_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, pack_trace_reason, true)) {} - static Envoy::Http::RequestIDExtensionSharedPtr defaultInstance(Random::RandomGenerator& random) { + static Http::RequestIDExtensionSharedPtr defaultInstance(Random::RandomGenerator& random) { return std::make_shared( envoy::extensions::request_id::uuid::v3::UuidRequestIdConfig(), random); } @@ -26,14 +26,12 @@ class UUIDRequestIDExtension : public Envoy::Http::RequestIDExtension { bool packTraceReason() { return pack_trace_reason_; } // Http::RequestIDExtension - void set(Envoy::Http::RequestHeaderMap& request_headers, bool force) override; - void setInResponse(Envoy::Http::ResponseHeaderMap& response_headers, - const Envoy::Http::RequestHeaderMap& request_headers) override; - absl::optional - toInteger(const Envoy::Http::RequestHeaderMap& request_headers) const override; - Tracing::Reason getTraceReason(const Envoy::Http::RequestHeaderMap& request_headers) override; - void setTraceReason(Envoy::Http::RequestHeaderMap& request_headers, - Tracing::Reason status) override; + void set(Http::RequestHeaderMap& request_headers, bool force) override; + void setInResponse(Http::ResponseHeaderMap& response_headers, + const Http::RequestHeaderMap& request_headers) override; + absl::optional toInteger(const Http::RequestHeaderMap& request_headers) const override; + Tracing::Reason getTraceReason(const Http::RequestHeaderMap& request_headers) override; + void setTraceReason(Http::RequestHeaderMap& request_headers, Tracing::Reason status) override; private: Envoy::Random::RandomGenerator& random_; @@ -65,7 +63,7 @@ class UUIDRequestIDExtensionFactory : public Server::Configuration::RequestIDExt ProtobufTypes::MessagePtr createEmptyConfigProto() override { return std::make_unique(); } - Envoy::Http::RequestIDExtensionSharedPtr + Http::RequestIDExtensionSharedPtr createExtensionInstance(const Protobuf::Message& config, Server::Configuration::FactoryContext& context) override { return std::make_shared( diff --git a/test/common/http/utility_test.cc b/test/common/http/utility_test.cc index 49cf81f341e2..99736e5097fb 100644 --- a/test/common/http/utility_test.cc +++ b/test/common/http/utility_test.cc @@ -464,16 +464,16 @@ TEST(HttpUtility, getLastAddressFromXFF) { {"x-forwarded-for", "192.0.2.10, 192.0.2.1, 10.0.0.1"}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(third_address, ret.address_->ip()->addressAsString()); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); ret = Utility::getLastAddressFromXFF(request_headers, 1); EXPECT_EQ(second_address, ret.address_->ip()->addressAsString()); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); ret = Utility::getLastAddressFromXFF(request_headers, 2); EXPECT_EQ(first_address, ret.address_->ip()->addressAsString()); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); ret = Utility::getLastAddressFromXFF(request_headers, 3); EXPECT_EQ(nullptr, ret.address_); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); } { const std::string first_address = "192.0.2.10"; @@ -486,64 +486,64 @@ TEST(HttpUtility, getLastAddressFromXFF) { // No space on the left. auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(fourth_address, ret.address_->ip()->addressAsString()); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); // No space on either side. ret = Utility::getLastAddressFromXFF(request_headers, 1); EXPECT_EQ(third_address, ret.address_->ip()->addressAsString()); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); // Exercise rtrim() and ltrim(). ret = Utility::getLastAddressFromXFF(request_headers, 2); EXPECT_EQ(second_address, ret.address_->ip()->addressAsString()); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); // No space trimming. ret = Utility::getLastAddressFromXFF(request_headers, 3); EXPECT_EQ(first_address, ret.address_->ip()->addressAsString()); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); // No address found. ret = Utility::getLastAddressFromXFF(request_headers, 4); EXPECT_EQ(nullptr, ret.address_); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); } { TestRequestHeaderMapImpl request_headers{{"x-forwarded-for", ""}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(nullptr, ret.address_); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); } { TestRequestHeaderMapImpl request_headers{{"x-forwarded-for", ","}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(nullptr, ret.address_); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); } { TestRequestHeaderMapImpl request_headers{{"x-forwarded-for", ", "}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(nullptr, ret.address_); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); } { TestRequestHeaderMapImpl request_headers{{"x-forwarded-for", ", bad"}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(nullptr, ret.address_); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); } { TestRequestHeaderMapImpl request_headers; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(nullptr, ret.address_); - EXPECT_FALSE(ret.single_address_); + EXPECT_FALSE(ret.allow_trusted_address_checks_); } { const std::string first_address = "34.0.0.1"; TestRequestHeaderMapImpl request_headers{{"x-forwarded-for", first_address}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(first_address, ret.address_->ip()->addressAsString()); - EXPECT_TRUE(ret.single_address_); + EXPECT_TRUE(ret.allow_trusted_address_checks_); } } diff --git a/test/extensions/filters/network/http_connection_manager/BUILD b/test/extensions/filters/network/http_connection_manager/BUILD index eeebd5c27a66..cf1a8ea1827c 100644 --- a/test/extensions/filters/network/http_connection_manager/BUILD +++ b/test/extensions/filters/network/http_connection_manager/BUILD @@ -47,8 +47,6 @@ envoy_extension_cc_test( "//source/common/buffer:buffer_lib", "//source/extensions/access_loggers/file:config", "//source/extensions/filters/network/http_connection_manager:config", - "//source/extensions/http/original_ip_detection/custom_header:config", - "//source/extensions/http/original_ip_detection/custom_header:custom_header_lib", "//test/integration/filters:encoder_decoder_buffer_filter_lib", "//test/mocks/network:network_mocks", "//test/mocks/server:factory_context_mocks", diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 37f1b664a9a4..2c957512fedc 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -10,7 +10,6 @@ #include "common/network/address_impl.h" #include "extensions/filters/network/http_connection_manager/config.h" -#include "extensions/http/original_ip_detection/custom_header/custom_header.h" #include "extensions/request_id/uuid/config.h" #include "test/extensions/filters/network/http_connection_manager/config.pb.h" @@ -1047,7 +1046,7 @@ TEST_F(HttpConnectionManagerConfigTest, RemovePortDefault) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - EXPECT_EQ(Envoy::Http::StripPortType::None, config.stripPortType()); + EXPECT_EQ(Http::StripPortType::None, config.stripPortType()); } // Validated that when configured, we remove port. @@ -1065,7 +1064,7 @@ TEST_F(HttpConnectionManagerConfigTest, RemovePortTrue) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - EXPECT_EQ(Envoy::Http::StripPortType::MatchingHost, config.stripPortType()); + EXPECT_EQ(Http::StripPortType::MatchingHost, config.stripPortType()); } // Validated that when both strip options are configured, we throw exception. @@ -1104,7 +1103,7 @@ TEST_F(HttpConnectionManagerConfigTest, RemovePortFalse) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - EXPECT_EQ(Envoy::Http::StripPortType::None, config.stripPortType()); + EXPECT_EQ(Http::StripPortType::None, config.stripPortType()); } // Validated that when configured, we remove any port. @@ -1122,7 +1121,7 @@ TEST_F(HttpConnectionManagerConfigTest, RemoveAnyPortTrue) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - EXPECT_EQ(Envoy::Http::StripPortType::Any, config.stripPortType()); + EXPECT_EQ(Http::StripPortType::Any, config.stripPortType()); } // Validated that when explicitly set false, we don't remove any port. @@ -1140,7 +1139,7 @@ TEST_F(HttpConnectionManagerConfigTest, RemoveAnyPortFalse) { date_provider_, route_config_provider_manager_, scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - EXPECT_EQ(Envoy::Http::StripPortType::None, config.stripPortType()); + EXPECT_EQ(Http::StripPortType::None, config.stripPortType()); } // Validated that by default we allow requests with header names containing underscores. @@ -1646,21 +1645,20 @@ TEST_F(HttpConnectionManagerConfigTest, AlwaysSetRequestIdInResponseConfigured) namespace { -class TestRequestIDExtension : public Envoy::Http::RequestIDExtension { +class TestRequestIDExtension : public Http::RequestIDExtension { public: TestRequestIDExtension(const test::http_connection_manager::CustomRequestIDExtension& config) : config_(config) {} - void set(Envoy::Http::RequestHeaderMap&, bool) override {} - void setInResponse(Envoy::Http::ResponseHeaderMap&, - const Envoy::Http::RequestHeaderMap&) override {} - absl::optional toInteger(const Envoy::Http::RequestHeaderMap&) const override { + void set(Http::RequestHeaderMap&, bool) override {} + void setInResponse(Http::ResponseHeaderMap&, const Http::RequestHeaderMap&) override {} + absl::optional toInteger(const Http::RequestHeaderMap&) const override { return absl::nullopt; } - Tracing::Reason getTraceReason(const Envoy::Http::RequestHeaderMap&) override { + Tracing::Reason getTraceReason(const Http::RequestHeaderMap&) override { return Tracing::Reason::Sampling; } - void setTraceReason(Envoy::Http::RequestHeaderMap&, Tracing::Reason) override {} + void setTraceReason(Http::RequestHeaderMap&, Tracing::Reason) override {} std::string testField() { return config_.test_field(); } @@ -1678,7 +1676,7 @@ class TestRequestIDExtensionFactory : public Server::Configuration::RequestIDExt return std::make_unique(); } - Envoy::Http::RequestIDExtensionSharedPtr + Http::RequestIDExtensionSharedPtr createExtensionInstance(const Protobuf::Message& config, Server::Configuration::FactoryContext& context) override { const auto& custom_config = MessageUtil::downcastAndValidate< @@ -1794,10 +1792,9 @@ TEST_F(HttpConnectionManagerConfigTest, UnknownOriginalIPDetectionExtension) { namespace { -class OriginalIPDetectionExtensionNotCreatedFactory - : public Envoy::Http::OriginalIPDetectionFactory { +class OriginalIPDetectionExtensionNotCreatedFactory : public Http::OriginalIPDetectionFactory { public: - Envoy::Http::OriginalIPDetectionSharedPtr + Http::OriginalIPDetectionSharedPtr createExtension(const Protobuf::Message&, Server::Configuration::FactoryContext&) override { return nullptr; } @@ -1815,7 +1812,7 @@ class OriginalIPDetectionExtensionNotCreatedFactory TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtensionNotCreated) { OriginalIPDetectionExtensionNotCreatedFactory factory; - Registry::InjectFactory registration(factory); + Registry::InjectFactory registration(factory); const std::string yaml_string = R"EOF( stat_prefix: ingress_http @@ -1856,11 +1853,6 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { auto original_ip_detection_extensions = config.originalIpDetectionExtensions(); EXPECT_EQ(1, original_ip_detection_extensions.size()); - - auto* extension = - dynamic_cast( - original_ip_detection_extensions[0].get()); - EXPECT_NE(nullptr, extension); } TEST_F(HttpConnectionManagerConfigTest, DynamicFilterWarmingNoDefault) { diff --git a/test/extensions/filters/network/http_connection_manager/config_test_base.h b/test/extensions/filters/network/http_connection_manager/config_test_base.h index 35cd5084f197..a0ce9792af31 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test_base.h +++ b/test/extensions/filters/network/http_connection_manager/config_test_base.h @@ -31,7 +31,7 @@ parseHttpConnectionManagerFromYaml(const std::string& yaml, bool avoid_boosting class HttpConnectionManagerConfigTest : public testing::Test { public: NiceMock context_; - Envoy::Http::SlowDateProviderImpl date_provider_{context_.dispatcher().timeSource()}; + Http::SlowDateProviderImpl date_provider_{context_.dispatcher().timeSource()}; NiceMock route_config_provider_manager_; NiceMock scoped_routes_config_provider_manager_; NiceMock http_tracer_manager_; From 014d6d45ba0db54aa842536af3397612afd7c804 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 15 Apr 2021 17:57:56 -0400 Subject: [PATCH 076/100] Update changelog Signed-off-by: Raul Gutierrez Segales --- docs/root/version_history/current.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 6b5e0a79e3ff..04f98ab37de0 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -144,10 +144,10 @@ New Features * ext_authz: added :ref:`allowed_client_headers_on_success ` to support sending response headers to downstream clients on OK external authorization checks via HTTP. * grpc_json_transcoder: added :ref:`request_validation_options ` to reject invalid requests early. * grpc_json_transcoder: filter can now be configured on per-route/per-vhost level as well. Leaving empty list of services in the filter configuration disables transcoding on the specific route. +* http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 and HTTP/2 dispatching. Crashes while inside the dispatching loop should dump debug information. Furthermore, HTTP/1 and HTTP/2 clients now dumps the originating request whose response from the upstream caused Envoy to crash. * http: added support for :ref:`original IP detection extensions`. Two initial extensions were added, the :ref:`custom header ` extension and the :ref:`xff ` extension. -* http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 and HTTP/2 dispatching. Crashes while inside the dispatching loop should dump debug information. Furthermore, HTTP/1 and HTTP/2 clients now dumps the originating request whose response from the upstream caused Envoy to crash. * http: added support for :ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. * http: added support for stream filters to mutate the cached route set by HCM route resolution. Useful for filters in a filter chain that want to override specific methods/properties of a route. See :ref:`http route mutation ` docs for more information. * http: added new runtime config `envoy.reloadable_features.check_unsupported_typed_per_filter_config`, the default value is true. When the value is true, envoy will reject virtual host-specific typed per filter config when the filter doesn't support it. From eaca63db15a8814748179fe51cd6ac115b674ce2 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 15 Apr 2021 19:07:04 -0400 Subject: [PATCH 077/100] Fix changelog Signed-off-by: Raul Gutierrez Segales --- docs/root/version_history/current.rst | 111 +------------------------- 1 file changed, 1 insertion(+), 110 deletions(-) diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 2ff2eeeecc23..aee20806a5f6 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -3,126 +3,17 @@ Bug Fixes --------- -*Changes expected to improve the state of the world and are unlikely to have negative effects* -* active http health checks: properly handles HTTP/2 GOAWAY frames from the upstream. Previously a GOAWAY frame due to a graceful listener drain could cause improper failed health checks due to streams being refused by the upstream on a connection that is going away. To revert to old GOAWAY handling behavior, set the runtime feature `envoy.reloadable_features.health_check.graceful_goaway_handling` to false. -* adaptive concurrency: fixed a bug where concurrent requests on different worker threads could update minRTT back-to-back. -* buffer: tighten network connection read and write buffer high watermarks in preparation to more careful enforcement of read limits. Buffer high-watermark is now set to the exact configured value; previously it was set to value + 1. -* cdn_loop: check that the entirety of the :ref:`cdn_id ` field is a valid CDN identifier. -* cds: fix blocking the update for a warming cluster when the update is the same as the active version. -* ext_authz: emit :ref:`CheckResponse.dynamic_metadata ` when the external authorization response has "Denied" check status. -* fault injection: stop counting as active fault after delay elapsed. Previously fault injection filter continues to count the injected delay as an active fault even after it has elapsed. This produces incorrect output statistics and impacts the max number of consecutive faults allowed (e.g., for long-lived streams). This change decreases the active fault count when the delay fault is the only active and has gone finished. -* filter_chain: fix filter chain matching with the server name as the case-insensitive way. -* grpc-web: fix local reply and non-proto-encoded gRPC response handling for small response bodies. This fix can be temporarily reverted by setting `envoy.reloadable_features.grpc_web_fix_non_proto_encoded_response_handling` to false. -* grpc_http_bridge: the downstream HTTP status is now correctly set for trailers-only responses from the upstream. -* header map: pick the right delimiter to append multiple header values to the same key. Previouly header with multiple values were coalesced with ",", after this fix cookie headers should be coalesced with " ;". This doesn't affect Http1 or Http2 requests because these 2 codecs coalesce cookie headers before adding it to header map. To revert to the old behavior, set the runtime feature `envoy.reloadable_features.header_map_correctly_coalesce_cookies` to false. -* http: avoid grpc-status overwrite on when sending local replies if that field has already been set. -* http: disallowing "host:" in request_headers_to_add for behavioral consistency with rejecting :authority header. This behavior can be temporarily reverted by setting `envoy.reloadable_features.treat_host_like_authority` to false. -* http: fixed an issue where Enovy did not handle peer stream limits correctly, and queued streams in nghttp2 rather than establish new connections. This behavior can be temporarily reverted by setting `envoy.reloadable_features.improved_stream_limit_handling` to false. -* http: fixed a bug where setting :ref:`MaxStreamDuration proto ` did not disable legacy timeout defaults. -* http: fixed a crash upon receiving empty HTTP/2 metadata frames. Received empty metadata frames are now counted in the HTTP/2 codec stat :ref:`metadata_empty_frames `. -* http: fixed a remotely exploitable integer overflow via a very large grpc-timeout value causes undefined behavior. -* http: reverting a behavioral change where upstream connect timeouts were temporarily treated differently from other connection failures. The change back to the original behavior can be temporarily reverted by setting `envoy.reloadable_features.treat_upstream_connect_timeout_as_connect_failure` to false. -* jwt_authn: reject requests with a proper error if JWT has the wrong issuer when allow_missing is used. Before this change, the requests are accepted. -* listener: prevent crashing when an unknown listener config proto is received and debug logging is enabled. -* mysql_filter: improve the codec ability of mysql filter at connection phase, it can now decode MySQL5.7+ connection phase protocol packet. -* overload: fix a bug that can cause use-after-free when one scaled timer disables another one with the same duration. -* sni: as the server name in sni should be case-insensitive, envoy will convert the server name as lower case first before any other process inside envoy. -* tls: fix a crash when peer sends a TLS Alert with an unknown code. -* tls: fix the subject alternative name of the presented certificate matches the specified matchers as the case-insensitive way when it uses DNS name. -* tls: fix issue where OCSP was inadvertently removed from SSL response in multi-context scenarios. -* upstream: fix handling of moving endpoints between priorities when active health checks are enabled. Previously moving to a higher numbered priority was a NOOP, and moving to a lower numbered priority caused an abort. -* upstream: retry budgets will now set default values for xDS configurations. -* zipkin: fix 'verbose' mode to emit annotations for stream events. This was the documented behavior, but wasn't behaving as documented. - -Removed Config or Runtime -------------------------- -*Normally occurs at the end of the* :ref:`deprecation period ` - -* access_logs: removed legacy unbounded access logs and runtime guard `envoy.reloadable_features.disallow_unbounded_access_logs`. -* dns: removed legacy buggy wildcard matching path and runtime guard `envoy.reloadable_features.fix_wildcard_matching`. -* dynamic_forward_proxy: removed `envoy.reloadable_features.enable_dns_cache_circuit_breakers` and legacy code path. -* http: removed legacy connect behavior and runtime guard `envoy.reloadable_features.stop_faking_paths`. -* http: removed legacy connection close behavior and runtime guard `envoy.reloadable_features.fixed_connection_close`. -* http: removed legacy HTTP/1.1 error reporting path and runtime guard `envoy.reloadable_features.early_errors_via_hcm`. -* http: removed legacy sanitization path for upgrade response headers and runtime guard `envoy.reloadable_features.fix_upgrade_response`. -* http: removed legacy date header overwriting logic and runtime guard `envoy.reloadable_features.preserve_upstream_date deprecation`. -* http: removed legacy ALPN handling and runtime guard `envoy.reloadable_features.http_default_alpn`. -* listener: removed legacy runtime guard `envoy.reloadable_features.listener_in_place_filterchain_update`. -* router: removed `envoy.reloadable_features.consume_all_retry_headers` and legacy code path. -* router: removed `envoy.reloadable_features.preserve_query_string_in_path_redirects` and legacy code path. +* code: fixed some whitespace to make fix_format happy. New Features ------------ -* access log: added a new :ref:`OpenTelemetry access logger ` extension, allowing a flexible log structure with native Envoy access log formatting. -* access log: added the new response flag `NC` for upstream cluster not found. The error flag is set when the http or tcp route is found for the request but the cluster is not available. -* access log: added the :ref:`formatters ` extension point for custom formatters (command operators). -* access log: added support for cross platform writing to :ref:`standard output ` and :ref:`standard error `. -* access log: support command operator: %FILTER_CHAIN_NAME% for the downstream tcp and http request. -* access log: support command operator: %REQUEST_HEADERS_BYTES%, %RESPONSE_HEADERS_BYTES%, and %RESPONSE_TRAILERS_BYTES%. -* admin: added support for :ref:`access loggers ` to the admin interface. -* composite filter: added new :ref:`composite filter ` that can be used to instantiate different filter configuratios based on matching incoming data. -* compression: add brotli :ref:`compressor ` and :ref:`decompressor `. -* compression: extended the compression allow compressing when the content length header is not present. This behavior may be temporarily reverted by setting `envoy.reloadable_features.enable_compression_without_content_length_header` to false. -* config: add `envoy.features.fail_on_any_deprecated_feature` runtime key, which matches the behaviour of compile-time flag `ENVOY_DISABLE_DEPRECATED_FEATURES`, i.e. use of deprecated fields will cause a crash. -* config: the ``Node`` :ref:`dynamic context parameters ` are populated in discovery requests when set on the server instance. -* dispatcher: supports a stack of `Envoy::ScopeTrackedObject` instead of a single tracked object. This will allow Envoy to dump more debug information on crash. -* ext_authz: added :ref:`response_headers_to_add ` to support sending response headers to downstream clients on OK authorization checks via gRPC. -* ext_authz: added :ref:`allowed_client_headers_on_success ` to support sending response headers to downstream clients on OK external authorization checks via HTTP. -* grpc_json_transcoder: added :ref:`request_validation_options ` to reject invalid requests early. -* grpc_json_transcoder: filter can now be configured on per-route/per-vhost level as well. Leaving empty list of services in the filter configuration disables transcoding on the specific route. -* http: added support for `Envoy::ScopeTrackedObject` for HTTP/1 and HTTP/2 dispatching. Crashes while inside the dispatching loop should dump debug information. Furthermore, HTTP/1 and HTTP/2 clients now dumps the originating request whose response from the upstream caused Envoy to crash. * http: added support for :ref:`original IP detection extensions`. Two initial extensions were added, the :ref:`custom header ` extension and the :ref:`xff ` extension. -* http: added support for :ref:`preconnecting `. Preconnecting is off by default, but recommended for clusters serving latency-sensitive traffic, especially if using HTTP/1.1. -* http: added support for stream filters to mutate the cached route set by HCM route resolution. Useful for filters in a filter chain that want to override specific methods/properties of a route. See :ref:`http route mutation ` docs for more information. -* http: added new runtime config `envoy.reloadable_features.check_unsupported_typed_per_filter_config`, the default value is true. When the value is true, envoy will reject virtual host-specific typed per filter config when the filter doesn't support it. -* http: added the ability to preserve HTTP/1 header case across the proxy. See the :ref:`header casing ` documentation for more information. -* http: change frame flood and abuse checks to the upstream HTTP/2 codec to ON by default. It can be disabled by setting the `envoy.reloadable_features.upstream_http2_flood_checks` runtime key to false. -* http: hash multiple header values instead of only hash the first header value. It can be disabled by setting the `envoy.reloadable_features.hash_multiple_header_values` runtime key to false. See the :ref:`HashPolicy's Header configuration ` for more information. -* json: introduced new JSON parser (https://github.com/nlohmann/json) to replace RapidJSON. The new parser is disabled by default. To test the new RapidJSON parser, enable the runtime feature `envoy.reloadable_features.remove_legacy_json`. -* kill_request: :ref:`Kill Request ` now supports bidirection killing. -* listener: added an optional :ref:`stat_prefix `. -* loadbalancer: added the ability to specify the hash_key for a host when using a consistent hashing loadbalancer (ringhash, maglev) using the :ref:`LbEndpoint.Metadata ` e.g.: ``"envoy.lb": {"hash_key": "..."}``. -* log: added a new custom flag ``%j`` to the log pattern to print the actual message to log as JSON escaped string. -* oauth filter: added the optional parameter :ref:`resources `. Set this value to add multiple "resource" parameters in the Authorization request sent to the OAuth provider. This acts as an identifier representing the protected resources the client is requesting a token for. -* original_dst: added support for :ref:`Original Destination ` on Windows. This enables the use of Envoy as a sidecar proxy on Windows. -* overload: add support for scaling :ref:`transport connection timeouts`. This can be used to reduce the TLS handshake timeout in response to overload. -* postgres: added ability to :ref:`terminate SSL`. -* rbac: added :ref:`shadow_rules_stat_prefix ` to allow adding custom prefix to the stats emitted by shadow rules. -* route config: added :ref:`allow_post field ` for allowing POST payload as raw TCP. -* route config: added :ref:`max_direct_response_body_size_bytes ` to set maximum :ref:`direct response body ` size in bytes. If not specified the default remains 4096 bytes. -* server: added *fips_mode* to :ref:`server compilation settings ` related statistic. -* server: added :option:`--enable-core-dump` flag to enable core dumps via prctl (Linux-based systems only). -* tcp_proxy: add support for converting raw TCP streams into HTTP/1.1 CONNECT requests. See :ref:`upgrade documentation ` for details. -* tcp_proxy: added a :ref:`use_post field ` for using HTTP POST to proxy TCP streams. -* tcp_proxy: added a :ref:`headers_to_add field ` for setting additional headers to the HTTP requests for TCP proxing. -* thrift_proxy: added a :ref:`max_requests_per_connection field ` for setting maximum requests for per downstream connection. -* thrift_proxy: added per upstream metrics within the :ref:`thrift router ` for messagetype counters in request/response. -* thrift_proxy: added per upstream metrics within the :ref:`thrift router ` for request time histograms. -* tls peer certificate validation: added :ref:`SPIFFE validator ` for supporting isolated multiple trust bundles in a single listener or cluster. -* tracing: added the :ref:`pack_trace_reason ` - field as well as explicit configuration for the built-in :ref:`UuidRequestIdConfig ` - request ID implementation. See the trace context propagation :ref:`architecture overview - ` for more information. -* udp: added :ref:`downstream ` and - :ref:`upstream ` statistics for dropped datagrams. -* udp: added :ref:`downstream_socket_config ` - listener configuration to allow configuration of downstream max UDP datagram size. Also added - :ref:`upstream_socket_config ` - UDP proxy configuration to allow configuration of upstream max UDP datagram size. The defaults for - both remain 1500 bytes. -* udp: added configuration for :ref:`GRO - `. The default is disabled for - :ref:`downstream sockets ` - and enabled for :ref:`upstream sockets `. Deprecated ---------- -* admin: :ref:`access_log_path ` is deprecated in favor for :ref:`access loggers `. * http: :ref:`xff_num_trusted_hops ` is deprecated in favor of :ref:`original IP detection extensions`. - -code: fixed some whitespace to make fix_format happy. From a2418276559aaba1cef42cbbe951c138b6a61218 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 09:04:24 -0400 Subject: [PATCH 078/100] Fix current changelog Signed-off-by: Raul Gutierrez Segales --- docs/root/version_history/current.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index e47c239c1f0d..5936ceb3b093 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -20,11 +20,6 @@ Removed Config or Runtime New Features ------------ -* code: fixed some whitespace to make fix_format happy. - -New Features ------------- - * http: added support for :ref:`original IP detection extensions`. Two initial extensions were added, the :ref:`custom header ` extension and the :ref:`xff ` extension. @@ -33,5 +28,3 @@ Deprecated ---------- * http: :ref:`xff_num_trusted_hops ` is deprecated in favor of :ref:`original IP detection extensions`. -Deprecated ----------- From bffe4d1ca85c9b6ea9fc4970165b21d530196db2 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 09:08:46 -0400 Subject: [PATCH 079/100] Bring back the custom header extension It's more painful to have it excluded since we still want/need to reference it from multiple places because it's a useful example of how this extension point works. So at the cost of forcing deployments to exclude it manually, let's bring it back. Signed-off-by: Raul Gutierrez Segales --- .../original_ip_detection/custom_header/v3/custom_header.proto | 1 - .../original_ip_detection/custom_header/v3/custom_header.proto | 1 - source/extensions/extensions_build_config.bzl | 1 - .../extensions/http/original_ip_detection/custom_header/BUILD | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 2dd2346a4280..eff2eae91dbe 100644 --- a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -14,7 +14,6 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Custom header original IP detection extension] -// [#not-implemented-hide:] // This extension allows for the original downstream remote IP to be detected // by reading the value from a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such diff --git a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 2dd2346a4280..eff2eae91dbe 100644 --- a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -14,7 +14,6 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: Custom header original IP detection extension] -// [#not-implemented-hide:] // This extension allows for the original downstream remote IP to be detected // by reading the value from a configured header name. If the value is successfully parsed // as an IP, it'll be treated as the effective downstream remote address and seen as such diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index 069e6cdf6e20..d4737af782c4 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -275,7 +275,6 @@ EXTENSIONS = { # Original IP detection # - # Disabled by default "envoy.http.original_ip_detection.custom_header": "//source/extensions/http/original_ip_detection/custom_header:config", "envoy.http.original_ip_detection.xff": "//source/extensions/http/original_ip_detection/xff:config", diff --git a/source/extensions/http/original_ip_detection/custom_header/BUILD b/source/extensions/http/original_ip_detection/custom_header/BUILD index 687e801b279e..13f1a2000999 100644 --- a/source/extensions/http/original_ip_detection/custom_header/BUILD +++ b/source/extensions/http/original_ip_detection/custom_header/BUILD @@ -7,7 +7,7 @@ load( licenses(["notice"]) # Apache 2 -envoy_extension_package(enabled_default = False) +envoy_extension_package() envoy_cc_library( name = "custom_header_lib", From 991996b2096fa589f96e3dbb2ed6d07f3e0f885e Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 11:42:21 -0400 Subject: [PATCH 080/100] Fix format Signed-off-by: Raul Gutierrez Segales --- .../filters/network/http_connection_manager/config.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index d1986a36ffe1..bd2e906f73a9 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -8,8 +8,8 @@ #include "envoy/config/core/v3/base.pb.h" #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h" #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.validate.h" -#include "envoy/extensions/request_id/uuid/v3/uuid.pb.h" #include "envoy/extensions/http/original_ip_detection/xff/v3/xff.pb.h" +#include "envoy/extensions/request_id/uuid/v3/uuid.pb.h" #include "envoy/filesystem/filesystem.h" #include "envoy/registry/registry.h" #include "envoy/server/admin.h" From 73aad95811af9cc919d453c97ebe627c70003ed9 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 13:47:09 -0400 Subject: [PATCH 081/100] Avoid namespace pollution issues Signed-off-by: Raul Gutierrez Segales --- test/common/http/BUILD | 13 +++++++++++-- test/common/http/conn_manager_utility_test.cc | 12 ++++-------- test/common/http/ip_detection_extensions.cc | 17 +++++++++++++++++ test/common/http/ip_detection_extensions.h | 11 +++++++++++ 4 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 test/common/http/ip_detection_extensions.cc create mode 100644 test/common/http/ip_detection_extensions.h diff --git a/test/common/http/BUILD b/test/common/http/BUILD index 673fe2ecd33a..d80b75ec6254 100644 --- a/test/common/http/BUILD +++ b/test/common/http/BUILD @@ -240,6 +240,7 @@ envoy_cc_test( name = "conn_manager_utility_test", srcs = ["conn_manager_utility_test.cc"], deps = [ + ":ip_detection_extensions_lib", "//source/common/common:random_generator_lib", "//source/common/event:dispatcher_lib", "//source/common/http:conn_manager_lib", @@ -247,8 +248,6 @@ envoy_cc_test( "//source/common/network:address_lib", "//source/common/network:utility_lib", "//source/common/runtime:runtime_lib", - "//source/extensions/http/original_ip_detection/custom_header:custom_header_lib", - "//source/extensions/http/original_ip_detection/xff:xff_lib", "//source/extensions/request_id/uuid:config", "//test/mocks/http:http_mocks", "//test/mocks/local_info:local_info_mocks", @@ -463,3 +462,13 @@ envoy_cc_fuzz_test( "//test/fuzz:utility_lib", ], ) + +envoy_cc_test_library( + name = "ip_detection_extensions_lib", + srcs = ["ip_detection_extensions.cc"], + hdrs = ["ip_detection_extensions.h"], + deps = [ + "//source/extensions/http/original_ip_detection/custom_header:custom_header_lib", + "//source/extensions/http/original_ip_detection/xff:xff_lib", + ], +) diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index e772e633ffbe..9f04130bed42 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -12,10 +12,9 @@ #include "common/network/utility.h" #include "common/runtime/runtime_impl.h" -#include "extensions/http/original_ip_detection/custom_header/custom_header.h" -#include "extensions/http/original_ip_detection/xff/xff.h" #include "extensions/request_id/uuid/config.h" +#include "test/common/http/ip_detection_extensions.h" #include "test/mocks/http/mocks.h" #include "test/mocks/local_info/mocks.h" #include "test/mocks/network/mocks.h" @@ -108,8 +107,7 @@ class ConnectionManagerUtilityTest : public testing::Test { ON_CALL(config_, requestIDExtension()) .WillByDefault(ReturnRef(request_id_extension_to_return_)); - detection_extensions_.push_back( - std::make_shared(0)); + detection_extensions_.push_back(getXFFExtension(0)); ON_CALL(config_, originalIpDetectionExtensions()) .WillByDefault(ReturnRef(detection_extensions_)); } @@ -381,8 +379,7 @@ TEST_F(ConnectionManagerUtilityTest, UseRemoteAddressWithXFFTrustedHops) { TEST_F(ConnectionManagerUtilityTest, UseXFFTrustedHopsWithoutRemoteAddress) { // Reconfigure XFF detection. detection_extensions_.clear(); - detection_extensions_.push_back( - std::make_shared(1)); + detection_extensions_.push_back(getXFFExtension(1)); ON_CALL(config_, originalIpDetectionExtensions()).WillByDefault(ReturnRef(detection_extensions_)); connection_.stream_info_.downstream_address_provider_->setRemoteAddress( @@ -1608,8 +1605,7 @@ TEST_F(ConnectionManagerUtilityTest, NoPreserveExternalRequestIdNoEdgeRequest) { // Test detecting the original IP via a header (no rejection if it fails). TEST_F(ConnectionManagerUtilityTest, OriginalIPDetectionExtension) { const std::string header_name = "x-cdn-detected-ip"; - auto detection_extension = std::make_shared< - Extensions::Http::OriginalIPDetection::CustomHeader::CustomHeaderIPDetection>(header_name); + auto detection_extension = getCustomHeaderExtension(header_name); const std::vector extensions = {detection_extension}; ON_CALL(config_, originalIpDetectionExtensions()).WillByDefault(ReturnRef(extensions)); diff --git a/test/common/http/ip_detection_extensions.cc b/test/common/http/ip_detection_extensions.cc new file mode 100644 index 000000000000..1ea67435c295 --- /dev/null +++ b/test/common/http/ip_detection_extensions.cc @@ -0,0 +1,17 @@ +#include "ip_detection_extensions.h" + +#include "extensions/http/original_ip_detection/custom_header/custom_header.h" +#include "extensions/http/original_ip_detection/xff/xff.h" + +namespace Envoy { + +Http::OriginalIPDetectionSharedPtr getXFFExtension(uint32_t hops) { + return std::make_shared(hops); +} + +Http::OriginalIPDetectionSharedPtr getCustomHeaderExtension(const std::string& header_name) { + return std::make_shared< + Extensions::Http::OriginalIPDetection::CustomHeader::CustomHeaderIPDetection>(header_name); +} + +} // namespace Envoy diff --git a/test/common/http/ip_detection_extensions.h b/test/common/http/ip_detection_extensions.h new file mode 100644 index 000000000000..c601197b0f74 --- /dev/null +++ b/test/common/http/ip_detection_extensions.h @@ -0,0 +1,11 @@ +#pragma once + +#include "envoy/http/original_ip_detection.h" + +// This helper is used to escape namespace pollution issues. +namespace Envoy { + +Http::OriginalIPDetectionSharedPtr getXFFExtension(uint32_t hops); +Http::OriginalIPDetectionSharedPtr getCustomHeaderExtension(const std::string& header_name); + +} // namespace Envoy From 6cd3d43ff36bf421df689bb7667d934c5ce5f6d5 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 14:12:04 -0400 Subject: [PATCH 082/100] Another test fix Signed-off-by: Raul Gutierrez Segales --- test/common/http/BUILD | 3 +-- test/common/http/conn_manager_impl_test_base.cc | 4 ++-- test/common/http/conn_manager_impl_test_base.h | 2 -- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/test/common/http/BUILD b/test/common/http/BUILD index d80b75ec6254..741d5a2e3066 100644 --- a/test/common/http/BUILD +++ b/test/common/http/BUILD @@ -214,11 +214,10 @@ envoy_cc_test( ], shard_count = 3, deps = [ + ":ip_detection_extensions_lib", "//source/common/http:conn_manager_lib", "//source/common/http:context_lib", "//source/extensions/access_loggers/common:file_access_log_lib", - "//source/extensions/http/original_ip_detection/custom_header:custom_header_lib", - "//source/extensions/http/original_ip_detection/xff:xff_lib", "//source/extensions/request_id/uuid:config", "//test/mocks/access_log:access_log_mocks", "//test/mocks/event:event_mocks", diff --git a/test/common/http/conn_manager_impl_test_base.cc b/test/common/http/conn_manager_impl_test_base.cc index c2d02d6e6ab1..fe59f5356d9b 100644 --- a/test/common/http/conn_manager_impl_test_base.cc +++ b/test/common/http/conn_manager_impl_test_base.cc @@ -1,4 +1,5 @@ #include "test/common/http/conn_manager_impl_test_base.h" +#include "test/common/http/ip_detection_extensions.h" #include "extensions/request_id/uuid/config.h" @@ -34,8 +35,7 @@ HttpConnectionManagerImplTest::HttpConnectionManagerImplTest() // method only. EXPECT_CALL(response_encoder_, getStream()).Times(AtLeast(0)); - ip_detection_extensions_.push_back( - std::make_shared(0)); + ip_detection_extensions_.push_back(getXFFExtension(0)); } HttpConnectionManagerImplTest::~HttpConnectionManagerImplTest() { diff --git a/test/common/http/conn_manager_impl_test_base.h b/test/common/http/conn_manager_impl_test_base.h index 905b645b12b4..818d918e39c2 100644 --- a/test/common/http/conn_manager_impl_test_base.h +++ b/test/common/http/conn_manager_impl_test_base.h @@ -6,8 +6,6 @@ #include "common/network/address_impl.h" #include "extensions/access_loggers/common/file_access_log_impl.h" -#include "extensions/http/original_ip_detection/custom_header/custom_header.h" -#include "extensions/http/original_ip_detection/xff/xff.h" #include "test/mocks/access_log/mocks.h" #include "test/mocks/event/mocks.h" From 42776e955816898c675c7b91f446aba2ce887252 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 14:17:12 -0400 Subject: [PATCH 083/100] Another test fix Signed-off-by: Raul Gutierrez Segales --- test/common/http/conn_manager_impl_test_2.cc | 5 ++--- test/common/http/ip_detection_extensions.cc | 8 ++++++++ test/common/http/ip_detection_extensions.h | 3 +++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/test/common/http/conn_manager_impl_test_2.cc b/test/common/http/conn_manager_impl_test_2.cc index dafffd6f1bf4..cc96a4999eac 100644 --- a/test/common/http/conn_manager_impl_test_2.cc +++ b/test/common/http/conn_manager_impl_test_2.cc @@ -1,4 +1,5 @@ #include "test/common/http/conn_manager_impl_test_base.h" +#include "test/common/http/ip_detection_extensions.h" #include "test/test_common/logging.h" #include "test/test_common/test_runtime.h" @@ -3037,9 +3038,7 @@ TEST_F(HttpConnectionManagerImplDeathTest, InvalidConnectionManagerConfig) { TEST_F(HttpConnectionManagerImplTest, RequestRejectedViaIPDetection) { OriginalIPRejectRequestOptions reject_options = {Http::Code::Forbidden, "ip detection failed"}; - auto extension = std::make_shared< - Extensions::Http::OriginalIPDetection::CustomHeader::CustomHeaderIPDetection>("x-ip", - reject_options); + auto extension = getCustomHeaderExtension("x-ip", reject_options); ip_detection_extensions_.push_back(extension); use_remote_address_ = false; diff --git a/test/common/http/ip_detection_extensions.cc b/test/common/http/ip_detection_extensions.cc index 1ea67435c295..b315e8ffa146 100644 --- a/test/common/http/ip_detection_extensions.cc +++ b/test/common/http/ip_detection_extensions.cc @@ -14,4 +14,12 @@ Http::OriginalIPDetectionSharedPtr getCustomHeaderExtension(const std::string& h Extensions::Http::OriginalIPDetection::CustomHeader::CustomHeaderIPDetection>(header_name); } +Http::OriginalIPDetectionSharedPtr +getCustomHeaderExtension(const std::string& header_name, + OriginalIPRejectRequestOptions reject_options) { + return std::make_shared< + Extensions::Http::OriginalIPDetection::CustomHeader::CustomHeaderIPDetection>(header_name, + reject_options); +} + } // namespace Envoy diff --git a/test/common/http/ip_detection_extensions.h b/test/common/http/ip_detection_extensions.h index c601197b0f74..a46d04f375c2 100644 --- a/test/common/http/ip_detection_extensions.h +++ b/test/common/http/ip_detection_extensions.h @@ -7,5 +7,8 @@ namespace Envoy { Http::OriginalIPDetectionSharedPtr getXFFExtension(uint32_t hops); Http::OriginalIPDetectionSharedPtr getCustomHeaderExtension(const std::string& header_name); +Http::OriginalIPDetectionSharedPtr +getCustomHeaderExtension(const std::string& header_name, + OriginalIPRejectRequestOptions reject_options); } // namespace Envoy From 7e6da84d634c8a8e9e67771f69369f7205f798f3 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 14:20:47 -0400 Subject: [PATCH 084/100] Fix Signed-off-by: Raul Gutierrez Segales --- test/common/http/ip_detection_extensions.cc | 2 +- test/common/http/ip_detection_extensions.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/common/http/ip_detection_extensions.cc b/test/common/http/ip_detection_extensions.cc index b315e8ffa146..95c2abec8488 100644 --- a/test/common/http/ip_detection_extensions.cc +++ b/test/common/http/ip_detection_extensions.cc @@ -16,7 +16,7 @@ Http::OriginalIPDetectionSharedPtr getCustomHeaderExtension(const std::string& h Http::OriginalIPDetectionSharedPtr getCustomHeaderExtension(const std::string& header_name, - OriginalIPRejectRequestOptions reject_options) { + Http::OriginalIPRejectRequestOptions reject_options) { return std::make_shared< Extensions::Http::OriginalIPDetection::CustomHeader::CustomHeaderIPDetection>(header_name, reject_options); diff --git a/test/common/http/ip_detection_extensions.h b/test/common/http/ip_detection_extensions.h index a46d04f375c2..32863f20a1a1 100644 --- a/test/common/http/ip_detection_extensions.h +++ b/test/common/http/ip_detection_extensions.h @@ -9,6 +9,6 @@ Http::OriginalIPDetectionSharedPtr getXFFExtension(uint32_t hops); Http::OriginalIPDetectionSharedPtr getCustomHeaderExtension(const std::string& header_name); Http::OriginalIPDetectionSharedPtr getCustomHeaderExtension(const std::string& header_name, - OriginalIPRejectRequestOptions reject_options); + Http::OriginalIPRejectRequestOptions reject_options); } // namespace Envoy From ef56193220902575f20fa398dab69ce989df56bf Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 15:10:14 -0400 Subject: [PATCH 085/100] Format Signed-off-by: Raul Gutierrez Segales --- test/common/http/conn_manager_impl_test_base.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/common/http/conn_manager_impl_test_base.cc b/test/common/http/conn_manager_impl_test_base.cc index fe59f5356d9b..cd0bbd88408e 100644 --- a/test/common/http/conn_manager_impl_test_base.cc +++ b/test/common/http/conn_manager_impl_test_base.cc @@ -1,8 +1,9 @@ #include "test/common/http/conn_manager_impl_test_base.h" -#include "test/common/http/ip_detection_extensions.h" #include "extensions/request_id/uuid/config.h" +#include "test/common/http/ip_detection_extensions.h" + using testing::AtLeast; using testing::InSequence; using testing::InvokeWithoutArgs; From 66f2296f4faf4f667f41831c7377925e6404c351 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 17:52:21 -0400 Subject: [PATCH 086/100] Fix integration tests Registering XFF with _required_extensions isn't enough, needs to be part of _core_extensions too. Signed-off-by: Raul Gutierrez Segales --- source/extensions/all_extensions.bzl | 1 + 1 file changed, 1 insertion(+) diff --git a/source/extensions/all_extensions.bzl b/source/extensions/all_extensions.bzl index 761c3c75e0bc..2cbf958b7497 100644 --- a/source/extensions/all_extensions.bzl +++ b/source/extensions/all_extensions.bzl @@ -28,6 +28,7 @@ _core_extensions = [ "envoy.filters.http.router", "envoy.filters.http.health_check", "envoy.filters.network.http_connection_manager", + "envoy.http.original_ip_detection.xff", "envoy.stat_sinks.statsd", "envoy.transport_sockets.raw_buffer", ] From b78ba36723f97779ca79a25dbd1d483c6a808180 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 18:00:15 -0400 Subject: [PATCH 087/100] extensions/common/aws needs xff to run Signed-off-by: Raul Gutierrez Segales --- test/extensions/common/aws/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/test/extensions/common/aws/BUILD b/test/extensions/common/aws/BUILD index 2a177200f6e7..215ab5070f0f 100644 --- a/test/extensions/common/aws/BUILD +++ b/test/extensions/common/aws/BUILD @@ -84,6 +84,7 @@ envoy_cc_test( "//source/extensions/filters/http/router:config", "//source/extensions/filters/network/echo:config", "//source/extensions/filters/network/http_connection_manager:config", + "//source/extensions/http/original_ip_detection/xff:config", "//test/integration:integration_lib", "//test/server:utility_lib", "//test/test_common:utility_lib", From 16a736ef6500ed6916e12cfe54a8184ed2958e2a Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 16 Apr 2021 19:58:14 -0400 Subject: [PATCH 088/100] xff:config should have been a dep of hcm:config in the prev commit Signed-off-by: Raul Gutierrez Segales --- source/extensions/all_extensions.bzl | 1 - source/extensions/filters/network/http_connection_manager/BUILD | 1 + test/extensions/common/aws/BUILD | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/source/extensions/all_extensions.bzl b/source/extensions/all_extensions.bzl index 2cbf958b7497..761c3c75e0bc 100644 --- a/source/extensions/all_extensions.bzl +++ b/source/extensions/all_extensions.bzl @@ -28,7 +28,6 @@ _core_extensions = [ "envoy.filters.http.router", "envoy.filters.http.health_check", "envoy.filters.network.http_connection_manager", - "envoy.http.original_ip_detection.xff", "envoy.stat_sinks.statsd", "envoy.transport_sockets.raw_buffer", ] diff --git a/source/extensions/filters/network/http_connection_manager/BUILD b/source/extensions/filters/network/http_connection_manager/BUILD index 31a0a7d642a7..0d0616ad4d4a 100644 --- a/source/extensions/filters/network/http_connection_manager/BUILD +++ b/source/extensions/filters/network/http_connection_manager/BUILD @@ -58,6 +58,7 @@ envoy_cc_extension( "//source/extensions/filters/http/common:pass_through_filter_lib", "//source/extensions/filters/network:well_known_names", "//source/extensions/filters/network/common:factory_base_lib", + "//source/extensions/http/original_ip_detection/xff:config", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/request_id/uuid/v3:pkg_cc_proto", diff --git a/test/extensions/common/aws/BUILD b/test/extensions/common/aws/BUILD index 215ab5070f0f..2a177200f6e7 100644 --- a/test/extensions/common/aws/BUILD +++ b/test/extensions/common/aws/BUILD @@ -84,7 +84,6 @@ envoy_cc_test( "//source/extensions/filters/http/router:config", "//source/extensions/filters/network/echo:config", "//source/extensions/filters/network/http_connection_manager:config", - "//source/extensions/http/original_ip_detection/xff:config", "//test/integration:integration_lib", "//test/server:utility_lib", "//test/test_common:utility_lib", From fcf7945ae88b03079202d013c68bf8b0e4ebfcdd Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Sun, 18 Apr 2021 10:55:12 -0400 Subject: [PATCH 089/100] HCM's test needs the custom header extension Signed-off-by: Raul Gutierrez Segales --- test/extensions/filters/network/http_connection_manager/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/test/extensions/filters/network/http_connection_manager/BUILD b/test/extensions/filters/network/http_connection_manager/BUILD index cf1a8ea1827c..3fdc9824d31f 100644 --- a/test/extensions/filters/network/http_connection_manager/BUILD +++ b/test/extensions/filters/network/http_connection_manager/BUILD @@ -47,6 +47,7 @@ envoy_extension_cc_test( "//source/common/buffer:buffer_lib", "//source/extensions/access_loggers/file:config", "//source/extensions/filters/network/http_connection_manager:config", + "//source/extensions/http/original_ip_detection/custom_header:config", "//test/integration/filters:encoder_decoder_buffer_filter_lib", "//test/mocks/network:network_mocks", "//test/mocks/server:factory_context_mocks", From 098ecd5ac17cec8c5e24d922f2376f2f80cdca8c Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Sun, 18 Apr 2021 16:43:00 -0400 Subject: [PATCH 090/100] clang-tidy Signed-off-by: Raul Gutierrez Segales --- .../filters/network/http_connection_manager/config_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 2c957512fedc..000953689614 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -1851,7 +1851,7 @@ TEST_F(HttpConnectionManagerConfigTest, OriginalIPDetectionExtension) { scoped_routes_config_provider_manager_, http_tracer_manager_, filter_config_provider_manager_); - auto original_ip_detection_extensions = config.originalIpDetectionExtensions(); + const auto& original_ip_detection_extensions = config.originalIpDetectionExtensions(); EXPECT_EQ(1, original_ip_detection_extensions.size()); } From ff6b944eaccd939add5613f3ccee1b909c9b2f34 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Tue, 20 Apr 2021 13:00:32 -0400 Subject: [PATCH 091/100] Undo jwt proto formatting Not sure what triggered this, probs something in my env. Signed-off-by: Raul Gutierrez Segales --- api/envoy/config/filter/http/jwt_authn/v2alpha/config.proto | 3 +-- api/envoy/extensions/filters/http/jwt_authn/v3/config.proto | 3 +-- .../extensions/filters/http/jwt_authn/v4alpha/config.proto | 3 +-- .../envoy/config/filter/http/jwt_authn/v2alpha/config.proto | 3 +-- .../envoy/extensions/filters/http/jwt_authn/v3/config.proto | 3 +-- .../extensions/filters/http/jwt_authn/v4alpha/config.proto | 3 +-- 6 files changed, 6 insertions(+), 12 deletions(-) diff --git a/api/envoy/config/filter/http/jwt_authn/v2alpha/config.proto b/api/envoy/config/filter/http/jwt_authn/v2alpha/config.proto index 847e36f163ba..07044f92201e 100644 --- a/api/envoy/config/filter/http/jwt_authn/v2alpha/config.proto +++ b/api/envoy/config/filter/http/jwt_authn/v2alpha/config.proto @@ -390,8 +390,7 @@ message FilterStateRule { // A map of string keys to requirements. The string key is the string value // in the FilterState with the name specified in the *name* field above. - map - requires = 3; + map requires = 3; } // This is the Envoy HTTP filter config for JWT authentication. diff --git a/api/envoy/extensions/filters/http/jwt_authn/v3/config.proto b/api/envoy/extensions/filters/http/jwt_authn/v3/config.proto index c1d8326cec3b..08ef7a09feb2 100644 --- a/api/envoy/extensions/filters/http/jwt_authn/v3/config.proto +++ b/api/envoy/extensions/filters/http/jwt_authn/v3/config.proto @@ -449,8 +449,7 @@ message FilterStateRule { // A map of string keys to requirements. The string key is the string value // in the FilterState with the name specified in the *name* field above. - map - requires = 3; + map requires = 3; } // This is the Envoy HTTP filter config for JWT authentication. diff --git a/api/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto b/api/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto index 48ceb05906f0..7656f09912e9 100644 --- a/api/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto +++ b/api/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto @@ -449,8 +449,7 @@ message FilterStateRule { // A map of string keys to requirements. The string key is the string value // in the FilterState with the name specified in the *name* field above. - map - requires = 3; + map requires = 3; } // This is the Envoy HTTP filter config for JWT authentication. diff --git a/generated_api_shadow/envoy/config/filter/http/jwt_authn/v2alpha/config.proto b/generated_api_shadow/envoy/config/filter/http/jwt_authn/v2alpha/config.proto index 847e36f163ba..07044f92201e 100644 --- a/generated_api_shadow/envoy/config/filter/http/jwt_authn/v2alpha/config.proto +++ b/generated_api_shadow/envoy/config/filter/http/jwt_authn/v2alpha/config.proto @@ -390,8 +390,7 @@ message FilterStateRule { // A map of string keys to requirements. The string key is the string value // in the FilterState with the name specified in the *name* field above. - map - requires = 3; + map requires = 3; } // This is the Envoy HTTP filter config for JWT authentication. diff --git a/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v3/config.proto b/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v3/config.proto index c1d8326cec3b..08ef7a09feb2 100644 --- a/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v3/config.proto +++ b/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v3/config.proto @@ -449,8 +449,7 @@ message FilterStateRule { // A map of string keys to requirements. The string key is the string value // in the FilterState with the name specified in the *name* field above. - map - requires = 3; + map requires = 3; } // This is the Envoy HTTP filter config for JWT authentication. diff --git a/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto b/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto index 48ceb05906f0..7656f09912e9 100644 --- a/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto +++ b/generated_api_shadow/envoy/extensions/filters/http/jwt_authn/v4alpha/config.proto @@ -449,8 +449,7 @@ message FilterStateRule { // A map of string keys to requirements. The string key is the string value // in the FilterState with the name specified in the *name* field above. - map - requires = 3; + map requires = 3; } // This is the Envoy HTTP filter config for JWT authentication. From 0eac9804dc3cd29ec086cedc586bffc598bbee67 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 28 Apr 2021 11:27:34 -0400 Subject: [PATCH 092/100] Fallback -> fall back Signed-off-by: Raul Gutierrez Segales --- .../filters/network/http_connection_manager/config.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index 9d8612109fb5..3b8573ebdb36 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -299,7 +299,7 @@ HttpConnectionManagerConfig::HttpConnectionManagerConfig( } request_id_extension_ = Http::RequestIDExtensionFactory::fromProto(final_rid_config, context_); - // Check if IP detection extensions were configured, otherwise fallback to XFF. + // Check if IP detection extensions were configured, otherwise fall back to XFF. auto ip_detection_extensions = config.original_ip_detection_extensions(); if (ip_detection_extensions.empty()) { envoy::extensions::http::original_ip_detection::xff::v3::XffConfig xff_config; @@ -706,7 +706,7 @@ const envoy::config::trace::v3::Tracing_Http* HttpConnectionManagerConfig::getPe if (config.tracing().has_provider()) { return &config.tracing().provider(); } - // Otherwise, for the sake of backwards compatibility, fallback to using tracing provider + // Otherwise, for the sake of backwards compatibility, fall back to using tracing provider // configuration defined in the bootstrap config. if (context_.httpContext().defaultTracingConfig().has_http()) { return &context_.httpContext().defaultTracingConfig().http(); From c751398e19cd5facaf249d7a83f5308a3f507ef7 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 28 Apr 2021 11:30:09 -0400 Subject: [PATCH 093/100] Comment on allow trusted check Signed-off-by: Raul Gutierrez Segales --- source/common/http/utility.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/common/http/utility.h b/source/common/http/utility.h index 1263691949b1..147175029bfd 100644 --- a/source/common/http/utility.h +++ b/source/common/http/utility.h @@ -341,7 +341,7 @@ void sendLocalReply(const bool& is_reset, const EncodeFunctions& encode_function struct GetLastAddressFromXffInfo { // Last valid address pulled from the XFF header. Network::Address::InstanceConstSharedPtr address_; - // Whether this is the only address in the XFF header. + // Whether this address can be used to determine if it's an internal request. bool allow_trusted_address_checks_; }; From bafa351b73e65189931f388769f37b6cbbb87469 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Wed, 28 Apr 2021 11:31:32 -0400 Subject: [PATCH 094/100] Status code comment Signed-off-by: Raul Gutierrez Segales --- .../original_ip_detection/custom_header/v3/custom_header.proto | 2 +- .../original_ip_detection/custom_header/v3/custom_header.proto | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index eff2eae91dbe..f671eb28860b 100644 --- a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -30,7 +30,7 @@ message CustomHeaderConfig { // when detection fails. The default status is HTTP 403 Forbidden. // // .. note:: - // If this is set to < 400, the default status 403 will be used instead. + // If this is set to < 400 or > 511, the default status 403 will be used instead. type.v3.HttpStatus status_on_error = 1; // If reject_request_if_detection_fails is set, this sets the HTTP body in the response diff --git a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index eff2eae91dbe..f671eb28860b 100644 --- a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -30,7 +30,7 @@ message CustomHeaderConfig { // when detection fails. The default status is HTTP 403 Forbidden. // // .. note:: - // If this is set to < 400, the default status 403 will be used instead. + // If this is set to < 400 or > 511, the default status 403 will be used instead. type.v3.HttpStatus status_on_error = 1; // If reject_request_if_detection_fails is set, this sets the HTTP body in the response From 892a4a842779d063d52b1b9fbfe834ead8be15c8 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 13 May 2021 14:46:28 -0400 Subject: [PATCH 095/100] Fix merge Signed-off-by: Raul Gutierrez Segales --- .../v4alpha/http_connection_manager.proto | 2 +- source/common/http/conn_manager_config.h | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index e1eed21edbfe..8fb1a785bf72 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -304,7 +304,7 @@ message HttpConnectionManager { type.http.v3.PathTransformation http_filter_transformation = 2; } - reserved 27, 11, 45, 19; + reserved 27, 11, 19; reserved "idle_timeout", "xff_num_trusted_hops"; diff --git a/source/common/http/conn_manager_config.h b/source/common/http/conn_manager_config.h index a8106dec54a5..8b05b4bbff49 100644 --- a/source/common/http/conn_manager_config.h +++ b/source/common/http/conn_manager_config.h @@ -472,19 +472,18 @@ class ConnectionManagerConfig { virtual const LocalReply::LocalReply& localReply() const PURE; /** -<<<<<<< HEAD - * @return vector of OriginalIPDetectionSharedPtr original IP detection extensions. - */ - virtual const std::vector& - originalIpDetectionExtensions() const PURE; -======= * @return the action HttpConnectionManager should take when receiving client request * with URI path containing %2F, %2f, %5c or %5C sequences. */ virtual envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: PathWithEscapedSlashesAction pathWithEscapedSlashesAction() const PURE; ->>>>>>> upstream/main + + /** + * @return vector of OriginalIPDetectionSharedPtr original IP detection extensions. + */ + virtual const std::vector& + originalIpDetectionExtensions() const PURE; }; } // namespace Http } // namespace Envoy From fd10840b1323664718f6b56aa31d4ccca626dc69 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 13 May 2021 15:35:38 -0400 Subject: [PATCH 096/100] Trim down comment for original_ip_detection_extensions Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 28 ++++--------------- .../v4alpha/http_connection_manager.proto | 28 ++++--------------- .../v3/http_connection_manager.proto | 28 ++++--------------- .../v4alpha/http_connection_manager.proto | 28 ++++--------------- 4 files changed, 20 insertions(+), 92 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index b5bc44ffebd0..37cf30d94adb 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -516,31 +516,13 @@ message HttpConnectionManager { // The configuration for the original-IP detection extensions. // - // By default, when the :ref:`use_remote_address - // ` - // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the deprecated :ref:`xff_num_trusted_hops - // ` - // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops - // ` - // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to - // configure xff_num_trusted_hops when using extensions. - // - // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` - // header doesn't necessarily work for all network configurations. For instance, - // if the number of trusted hops isn't consistent for requests flowing into - // Envoy this mechanism cannot be used reliably. For such cases, the following - // option allows for a list of custom extensions to be provided. - // // When configured the extensions will be called along with the request headers - // and information about the downstream connection, such as direct connected address, - // when the HCM needs to populate the final remote address. Each extension will then rely - // on these parameters to decide the value of the request's final remote address. + // and information about the downstream connection, such as the directly connected address. + // Each extension will then use these parameters to decide the request's effective remote address. // If an extension fails to detect the original IP address and isn't configured to reject - // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. If the request isn't rejected nor any extension - // succeeds, the HCM will fallback to using the remote address. + // the request, the HCM will try the remaining extensions until one succeeds or rejects + // the request. If the request isn't rejected nor any extension succeeds, the HCM will + // fallback to using the remote address. // // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 46; diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 8fb1a785bf72..06f737c58f22 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -495,31 +495,13 @@ message HttpConnectionManager { // The configuration for the original-IP detection extensions. // - // By default, when the :ref:`use_remote_address - // ` - // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the deprecated :ref:`xff_num_trusted_hops - // ` - // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops - // ` - // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to - // configure xff_num_trusted_hops when using extensions. - // - // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` - // header doesn't necessarily work for all network configurations. For instance, - // if the number of trusted hops isn't consistent for requests flowing into - // Envoy this mechanism cannot be used reliably. For such cases, the following - // option allows for a list of custom extensions to be provided. - // // When configured the extensions will be called along with the request headers - // and information about the downstream connection, such as direct connected address, - // when the HCM needs to populate the final remote address. Each extension will then rely - // on these parameters to decide the value of the request's final remote address. + // and information about the downstream connection, such as the directly connected address. + // Each extension will then use these parameters to decide the request's effective remote address. // If an extension fails to detect the original IP address and isn't configured to reject - // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. If the request isn't rejected nor any extension - // succeeds, the HCM will fallback to using the remote address. + // the request, the HCM will try the remaining extensions until one succeeds or rejects + // the request. If the request isn't rejected nor any extension succeeds, the HCM will + // fallback to using the remote address. // // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 46; diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index c6e8f2a6a82e..3329d559f1fd 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -521,31 +521,13 @@ message HttpConnectionManager { // The configuration for the original-IP detection extensions. // - // By default, when the :ref:`use_remote_address - // ` - // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the deprecated :ref:`xff_num_trusted_hops - // ` - // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops - // ` - // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to - // configure xff_num_trusted_hops when using extensions. - // - // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` - // header doesn't necessarily work for all network configurations. For instance, - // if the number of trusted hops isn't consistent for requests flowing into - // Envoy this mechanism cannot be used reliably. For such cases, the following - // option allows for a list of custom extensions to be provided. - // // When configured the extensions will be called along with the request headers - // and information about the downstream connection, such as direct connected address, - // when the HCM needs to populate the final remote address. Each extension will then rely - // on these parameters to decide the value of the request's final remote address. + // and information about the downstream connection, such as the directly connected address. + // Each extension will then use these parameters to decide the request's effective remote address. // If an extension fails to detect the original IP address and isn't configured to reject - // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. If the request isn't rejected nor any extension - // succeeds, the HCM will fallback to using the remote address. + // the request, the HCM will try the remaining extensions until one succeeds or rejects + // the request. If the request isn't rejected nor any extension succeeds, the HCM will + // fallback to using the remote address. // // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v3.TypedExtensionConfig original_ip_detection_extensions = 46; diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index b1a749493741..548067e65127 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -519,31 +519,13 @@ message HttpConnectionManager { // The configuration for the original-IP detection extensions. // - // By default, when the :ref:`use_remote_address - // ` - // option is not used, Envoy will rely on the :ref:`config_http_conn_man_headers_x-forwarded-for` header - // and the deprecated :ref:`xff_num_trusted_hops - // ` - // configuration option to detect the remote address. Once :ref:`xff_num_trusted_hops - // ` - // is removed, leaving this field empty will retain the default behavior when that field is unset. See - // the :ref:`xff extension ` for how to - // configure xff_num_trusted_hops when using extensions. - // - // Furthermore, relying on the :ref:`config_http_conn_man_headers_x-forwarded-for` - // header doesn't necessarily work for all network configurations. For instance, - // if the number of trusted hops isn't consistent for requests flowing into - // Envoy this mechanism cannot be used reliably. For such cases, the following - // option allows for a list of custom extensions to be provided. - // // When configured the extensions will be called along with the request headers - // and information about the downstream connection, such as direct connected address, - // when the HCM needs to populate the final remote address. Each extension will then rely - // on these parameters to decide the value of the request's final remote address. + // and information about the downstream connection, such as the directly connected address. + // Each extension will then use these parameters to decide the request's effective remote address. // If an extension fails to detect the original IP address and isn't configured to reject - // the request when this happens, the HCM will then try the remaining configured extensions - // until one succeeds or the request is rejected. If the request isn't rejected nor any extension - // succeeds, the HCM will fallback to using the remote address. + // the request, the HCM will try the remaining extensions until one succeeds or rejects + // the request. If the request isn't rejected nor any extension succeeds, the HCM will + // fallback to using the remote address. // // [#extension-category: envoy.http.original_ip_detection] repeated config.core.v4alpha.TypedExtensionConfig original_ip_detection_extensions = 46; From 3ef96b1d627d16206d8b385c735ebc961489e5ec Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 13 May 2021 16:54:55 -0400 Subject: [PATCH 097/100] More fixes Signed-off-by: Raul Gutierrez Segales --- .../v3/http_connection_manager.proto | 2 +- .../custom_header/v3/custom_header.proto | 26 +++++-------------- .../v3/http_connection_manager.proto | 2 +- .../v4alpha/http_connection_manager.proto | 2 +- .../custom_header/v3/custom_header.proto | 26 +++++-------------- .../custom_header/custom_header.cc | 6 ++--- source/server/admin/admin.h | 2 +- .../http/conn_manager_impl_fuzz_test.cc | 2 +- .../custom_header/custom_header_test.cc | 13 +++------- 9 files changed, 26 insertions(+), 55 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 37cf30d94adb..31e036d5f978 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -500,7 +500,7 @@ message HttpConnectionManager { // .. note:: // This field is deprecated and instead :ref:`original_ip_detection_extensions // ` - // should be used to configure the :ref:`xff extension ` + // should be used to configure the :ref:`xff extension ` // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. To replace // this field use a config like the following: // diff --git a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index f671eb28860b..3f5aca789903 100644 --- a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -24,32 +24,20 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // // [#extension: envoy.http.original_ip_detection.custom_header] message CustomHeaderConfig { - // Configuration options for rejecting requests when detection fails. - message RejectOptions { - // If reject_request_if_detection_fails is set, this sets the HTTP status that is sent downstream - // when detection fails. The default status is HTTP 403 Forbidden. - // - // .. note:: - // If this is set to < 400 or > 511, the default status 403 will be used instead. - type.v3.HttpStatus status_on_error = 1; - - // If reject_request_if_detection_fails is set, this sets the HTTP body in the response - // when detection fails. If not set, an empty body is used. - string body_on_error = 2; - } - // The header name containing the original downstream remote address, if present. // // Note: in the case of a multi-valued header, only the first value is tried and the rest are ignored. string header_name = 1 [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: true}]; - // If set to true, the extension is allowed to decide if the detected address should be treated as - // trusted. If a detected address is considered trusted, it might be used as input to determine + // If set to true, the extension could decide that the detected address should be treated as + // trusted by the HCM. If the address is considered trusted, it might be used as input to determine // if the request is internal (among other things). bool allow_extension_to_set_address_as_trusted = 2; - // If set, requests for which either the configured header is missing or parsing an IP from its - // value fails will be rejected with these options. - RejectOptions reject_options = 3; + // If this is set, the request will be rejected when detection fails using it as the HTTP response status. + // + // .. note:: + // If this is set to < 400 or > 511, the default status 403 will be used instead. + type.v3.HttpStatus reject_with_status = 3; } diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 3329d559f1fd..69f392513c2c 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -505,7 +505,7 @@ message HttpConnectionManager { // .. note:: // This field is deprecated and instead :ref:`original_ip_detection_extensions // ` - // should be used to configure the :ref:`xff extension ` + // should be used to configure the :ref:`xff extension ` // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. To replace // this field use a config like the following: // diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 548067e65127..f0e13180d595 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -503,7 +503,7 @@ message HttpConnectionManager { // .. note:: // This field is deprecated and instead :ref:`original_ip_detection_extensions // ` - // should be used to configure the :ref:`xff extension ` + // should be used to configure the :ref:`xff extension ` // to configure IP detection using the :ref:`config_http_conn_man_headers_x-forwarded-for` header. To replace // this field use a config like the following: // diff --git a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index f671eb28860b..3f5aca789903 100644 --- a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -24,32 +24,20 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // // [#extension: envoy.http.original_ip_detection.custom_header] message CustomHeaderConfig { - // Configuration options for rejecting requests when detection fails. - message RejectOptions { - // If reject_request_if_detection_fails is set, this sets the HTTP status that is sent downstream - // when detection fails. The default status is HTTP 403 Forbidden. - // - // .. note:: - // If this is set to < 400 or > 511, the default status 403 will be used instead. - type.v3.HttpStatus status_on_error = 1; - - // If reject_request_if_detection_fails is set, this sets the HTTP body in the response - // when detection fails. If not set, an empty body is used. - string body_on_error = 2; - } - // The header name containing the original downstream remote address, if present. // // Note: in the case of a multi-valued header, only the first value is tried and the rest are ignored. string header_name = 1 [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: true}]; - // If set to true, the extension is allowed to decide if the detected address should be treated as - // trusted. If a detected address is considered trusted, it might be used as input to determine + // If set to true, the extension could decide that the detected address should be treated as + // trusted by the HCM. If the address is considered trusted, it might be used as input to determine // if the request is internal (among other things). bool allow_extension_to_set_address_as_trusted = 2; - // If set, requests for which either the configured header is missing or parsing an IP from its - // value fails will be rejected with these options. - RejectOptions reject_options = 3; + // If this is set, the request will be rejected when detection fails using it as the HTTP response status. + // + // .. note:: + // If this is set to < 400 or > 511, the default status 403 will be used instead. + type.v3.HttpStatus reject_with_status = 3; } diff --git a/source/extensions/http/original_ip_detection/custom_header/custom_header.cc b/source/extensions/http/original_ip_detection/custom_header/custom_header.cc index 8ff33b99bb75..86c31236b726 100644 --- a/source/extensions/http/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/http/original_ip_detection/custom_header/custom_header.cc @@ -13,9 +13,9 @@ CustomHeaderIPDetection::CustomHeaderIPDetection( config) : header_name_(config.header_name()), allow_trusted_address_checks_(config.allow_extension_to_set_address_as_trusted()) { - if (config.has_reject_options()) { - const auto reject_code = toErrorCode(config.reject_options().status_on_error().code()); - reject_options_ = {reject_code, config.reject_options().body_on_error()}; + if (config.has_status_on_error()) { + const auto reject_code = toErrorCode(config.status_on_error().code()); + reject_options_ = {reject_code, ""}; } } diff --git a/source/server/admin/admin.h b/source/server/admin/admin.h index 9fcf83ecdf54..84d5236e212b 100644 --- a/source/server/admin/admin.h +++ b/source/server/admin/admin.h @@ -192,7 +192,7 @@ class AdminImpl : public Admin, const std::vector& originalIpDetectionExtensions() const override { return detection_extensions_; - }; + } Http::Code request(absl::string_view path_and_query, absl::string_view method, Http::ResponseHeaderMap& response_headers, std::string& body) override; void closeSocket(); diff --git a/test/common/http/conn_manager_impl_fuzz_test.cc b/test/common/http/conn_manager_impl_fuzz_test.cc index 8d8ca4a8c004..a62a208315ae 100644 --- a/test/common/http/conn_manager_impl_fuzz_test.cc +++ b/test/common/http/conn_manager_impl_fuzz_test.cc @@ -204,13 +204,13 @@ class FuzzConfig : public ConnectionManagerConfig { return envoy::config::core::v3::HttpProtocolOptions::ALLOW; } const LocalReply::LocalReply& localReply() const override { return *local_reply_; } - const std::vector& envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: PathWithEscapedSlashesAction pathWithEscapedSlashesAction() const override { return envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: KEEP_UNCHANGED; } + const std::vector& originalIpDetectionExtensions() const override { return ip_detection_extensions_; } diff --git a/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc index 05c84233d79b..7417e38a72af 100644 --- a/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc @@ -22,12 +22,7 @@ class CustomHeaderTest : public testing::Test { envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig config; config.set_header_name("x-real-ip"); config.set_allow_extension_to_set_address_as_trusted(true); - - auto* reject_options = config.mutable_reject_options(); - reject_options->set_body_on_error("detection failed"); - auto* status_on_error = reject_options->mutable_status_on_error(); - status_on_error->set_code(code); - + config.set_status_on_error(code); custom_header_extension_ = std::make_shared(config); } @@ -47,7 +42,7 @@ TEST_F(CustomHeaderTest, Detection) { const auto& reject_options = result.reject_options.value(); EXPECT_EQ(reject_options.response_code, Envoy::Http::Code::Unauthorized); - EXPECT_EQ(reject_options.body, "detection failed"); + EXPECT_EQ(reject_options.body, ""); } // Bad IP in the header. @@ -62,7 +57,7 @@ TEST_F(CustomHeaderTest, Detection) { const auto& reject_options = result.reject_options.value(); EXPECT_EQ(reject_options.response_code, Envoy::Http::Code::Unauthorized); - EXPECT_EQ(reject_options.body, "detection failed"); + EXPECT_EQ(reject_options.body, ""); } // Good IPv4. @@ -101,7 +96,7 @@ TEST_F(CustomHeaderTest, FallbacksToDefaultResponseCode) { const auto& reject_options = result.reject_options.value(); EXPECT_EQ(reject_options.response_code, Envoy::Http::Code::Forbidden); - EXPECT_EQ(reject_options.body, "detection failed"); + EXPECT_EQ(reject_options.body, ""); } } // namespace CustomHeader From f841b5fced4dbddd06367cd88042a8f0626493a1 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 13 May 2021 17:50:24 -0400 Subject: [PATCH 098/100] Field name update Signed-off-by: Raul Gutierrez Segales --- .../http/original_ip_detection/custom_header/custom_header.cc | 4 ++-- .../original_ip_detection/custom_header/custom_header_test.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/extensions/http/original_ip_detection/custom_header/custom_header.cc b/source/extensions/http/original_ip_detection/custom_header/custom_header.cc index 86c31236b726..9e7d9d7e8bcb 100644 --- a/source/extensions/http/original_ip_detection/custom_header/custom_header.cc +++ b/source/extensions/http/original_ip_detection/custom_header/custom_header.cc @@ -13,8 +13,8 @@ CustomHeaderIPDetection::CustomHeaderIPDetection( config) : header_name_(config.header_name()), allow_trusted_address_checks_(config.allow_extension_to_set_address_as_trusted()) { - if (config.has_status_on_error()) { - const auto reject_code = toErrorCode(config.status_on_error().code()); + if (config.has_reject_with_status()) { + const auto reject_code = toErrorCode(config.reject_with_status().code()); reject_options_ = {reject_code, ""}; } } diff --git a/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc index 7417e38a72af..1d3f4a3bfb56 100644 --- a/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc @@ -22,7 +22,7 @@ class CustomHeaderTest : public testing::Test { envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig config; config.set_header_name("x-real-ip"); config.set_allow_extension_to_set_address_as_trusted(true); - config.set_status_on_error(code); + config.set_reject_with_status(code); custom_header_extension_ = std::make_shared(config); } From c4a21e79e6627adb9574261098175f5896a236d4 Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Thu, 13 May 2021 20:42:09 -0400 Subject: [PATCH 099/100] Fix Signed-off-by: Raul Gutierrez Segales --- .../original_ip_detection/custom_header/custom_header_test.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc b/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc index 1d3f4a3bfb56..e1a14c133d73 100644 --- a/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc +++ b/test/extensions/http/original_ip_detection/custom_header/custom_header_test.cc @@ -22,7 +22,8 @@ class CustomHeaderTest : public testing::Test { envoy::extensions::http::original_ip_detection::custom_header::v3::CustomHeaderConfig config; config.set_header_name("x-real-ip"); config.set_allow_extension_to_set_address_as_trusted(true); - config.set_reject_with_status(code); + auto* reject_with_status = config.mutable_reject_with_status(); + reject_with_status->set_code(code); custom_header_extension_ = std::make_shared(config); } From 166eddbebda2498250635b4bd6b1697537d0575f Mon Sep 17 00:00:00 2001 From: Raul Gutierrez Segales Date: Fri, 14 May 2021 10:07:50 -0400 Subject: [PATCH 100/100] htuch's review Signed-off-by: Raul Gutierrez Segales --- .../http_connection_manager/v3/http_connection_manager.proto | 2 +- .../v4alpha/http_connection_manager.proto | 2 +- .../custom_header/v3/custom_header.proto | 4 ++-- .../http_connection_manager/v3/http_connection_manager.proto | 2 +- .../v4alpha/http_connection_manager.proto | 2 +- .../custom_header/v3/custom_header.proto | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 31e036d5f978..90f4b276dc3c 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -514,7 +514,7 @@ message HttpConnectionManager { uint32 xff_num_trusted_hops = 19 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // The configuration for the original-IP detection extensions. + // The configuration for the original IP detection extensions. // // When configured the extensions will be called along with the request headers // and information about the downstream connection, such as the directly connected address. diff --git a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 06f737c58f22..4f61ffb8ccca 100644 --- a/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/api/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -493,7 +493,7 @@ message HttpConnectionManager { google.protobuf.BoolValue use_remote_address = 14 [(udpa.annotations.security).configure_for_untrusted_downstream = true]; - // The configuration for the original-IP detection extensions. + // The configuration for the original IP detection extensions. // // When configured the extensions will be called along with the request headers // and information about the downstream connection, such as the directly connected address. diff --git a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 3f5aca789903..5ea93d754843 100644 --- a/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/api/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -31,8 +31,8 @@ message CustomHeaderConfig { [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: true}]; // If set to true, the extension could decide that the detected address should be treated as - // trusted by the HCM. If the address is considered trusted, it might be used as input to determine - // if the request is internal (among other things). + // trusted by the HCM. If the address is considered :ref:`trusted`, + // it might be used as input to determine if the request is internal (among other things). bool allow_extension_to_set_address_as_trusted = 2; // If this is set, the request will be rejected when detection fails using it as the HTTP response status. diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 69f392513c2c..1ac96a5a292c 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -519,7 +519,7 @@ message HttpConnectionManager { uint32 xff_num_trusted_hops = 19 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // The configuration for the original-IP detection extensions. + // The configuration for the original IP detection extensions. // // When configured the extensions will be called along with the request headers // and information about the downstream connection, such as the directly connected address. diff --git a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index f0e13180d595..7582fc2611ee 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -517,7 +517,7 @@ message HttpConnectionManager { uint32 hidden_envoy_deprecated_xff_num_trusted_hops = 19 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; - // The configuration for the original-IP detection extensions. + // The configuration for the original IP detection extensions. // // When configured the extensions will be called along with the request headers // and information about the downstream connection, such as the directly connected address. diff --git a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto index 3f5aca789903..5ea93d754843 100644 --- a/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto +++ b/generated_api_shadow/envoy/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto @@ -31,8 +31,8 @@ message CustomHeaderConfig { [(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: true}]; // If set to true, the extension could decide that the detected address should be treated as - // trusted by the HCM. If the address is considered trusted, it might be used as input to determine - // if the request is internal (among other things). + // trusted by the HCM. If the address is considered :ref:`trusted`, + // it might be used as input to determine if the request is internal (among other things). bool allow_extension_to_set_address_as_trusted = 2; // If this is set, the request will be rejected when detection fails using it as the HTTP response status.