diff --git a/docs/root/configuration/http_filters/dynamic_forward_proxy_filter.rst b/docs/root/configuration/http_filters/dynamic_forward_proxy_filter.rst index 80c569ae5a3e3..a627ce3d21202 100644 --- a/docs/root/configuration/http_filters/dynamic_forward_proxy_filter.rst +++ b/docs/root/configuration/http_filters/dynamic_forward_proxy_filter.rst @@ -25,14 +25,12 @@ HTTP dynamic forward proxy. ` parameter has been set to true to allow Envoy to proxy absolute HTTP URLs. -.. attention:: +.. note:: - While configuring a :ref:`tls_context ` on the cluster with + Configuring a :ref:`tls_context ` on the cluster with *trusted_ca* certificates instructs Envoy to use TLS when connecting to upstream hosts and verify - the certificate chain, currently it is not possible to configure per-host TLS configuration - parameters including SNI, subject alt name verification, etc. This will be added in a future - change. **This means that the following configuration will not fully validate TLS certificates**. - Use with care until full support for per-host validation is implemented. + the certificate chain. Additionally, Envoy will automatically perform SAN verification for the + resolved host name as well as specify the host name via SNI. .. code-block:: yaml diff --git a/docs/root/intro/arch_overview/http/http_proxy.rst b/docs/root/intro/arch_overview/http/http_proxy.rst index 496feab8c5709..2ed691203abb4 100644 --- a/docs/root/intro/arch_overview/http/http_proxy.rst +++ b/docs/root/intro/arch_overview/http/http_proxy.rst @@ -27,6 +27,8 @@ follows: * A special load balancer will select the right host to use based on the HTTP host/authority header during forwarding. * Hosts that have not been used for a period of time are subject to a TTL that will purge them. +* When the upstream cluster has been configured with a TLS context, Envoy will automatically perform + SAN verification for the resolved host name as well as specify the host name via SNI. The above implementation details mean that at steady state Envoy can forward a large volume of HTTP proxy traffic while all DNS resolution happens asynchronously in the background. Additionally, diff --git a/include/envoy/network/transport_socket.h b/include/envoy/network/transport_socket.h index dab4a2054c314..1167f46e19d3f 100644 --- a/include/envoy/network/transport_socket.h +++ b/include/envoy/network/transport_socket.h @@ -165,6 +165,12 @@ class TransportSocketOptions { */ virtual const absl::optional& serverNameOverride() const PURE; + /** + * @return the optional overridden SAN names to verify, if the transport socket supports SAN + * verification. + */ + virtual const std::vector& verifySubjectAltNameListOverride() const PURE; + /** * @param vector of bytes to which the option should append hash key data that will be used * to separate connections based on the option. Any data already in the key vector must @@ -173,7 +179,8 @@ class TransportSocketOptions { virtual void hashKey(std::vector& key) const PURE; }; -using TransportSocketOptionsSharedPtr = std::shared_ptr; +// TODO(mattklein123): Rename to TransportSocketOptionsConstSharedPtr in a dedicated follow up. +using TransportSocketOptionsSharedPtr = std::shared_ptr; /** * A factory for creating transport socket. It will be associated to filter chains and clusters. diff --git a/source/common/config/tls_context_json.cc b/source/common/config/tls_context_json.cc index 6072c55b2a772..fece59b47676c 100644 --- a/source/common/config/tls_context_json.cc +++ b/source/common/config/tls_context_json.cc @@ -9,20 +9,6 @@ namespace Envoy { namespace Config { -void TlsContextJson::translateDownstreamTlsContext( - const Json::Object& json_tls_context, - envoy::api::v2::auth::DownstreamTlsContext& downstream_tls_context) { - translateCommonTlsContext(json_tls_context, *downstream_tls_context.mutable_common_tls_context()); - JSON_UTIL_SET_BOOL(json_tls_context, downstream_tls_context, require_client_certificate); - - const std::vector paths = - json_tls_context.getStringArray("session_ticket_key_paths", true); - for (const std::string& path : paths) { - downstream_tls_context.mutable_session_ticket_keys()->mutable_keys()->Add()->set_filename(path); - } - MessageUtil::validate(downstream_tls_context); -} - void TlsContextJson::translateUpstreamTlsContext( const Json::Object& json_tls_context, envoy::api::v2::auth::UpstreamTlsContext& upstream_tls_context) { diff --git a/source/common/config/tls_context_json.h b/source/common/config/tls_context_json.h index 53a1a14afe75d..1eb9cbc1139d3 100644 --- a/source/common/config/tls_context_json.h +++ b/source/common/config/tls_context_json.h @@ -8,15 +8,6 @@ namespace Config { class TlsContextJson { public: - /** - * Translate a v1 JSON TLS context to v2 envoy::api::v2::auth::DownstreamTlsContext. - * @param json_tls_context source v1 JSON TLS context object. - * @param downstream_tls_context destination v2 envoy::api::v2::Cluster. - */ - static void - translateDownstreamTlsContext(const Json::Object& json_tls_context, - envoy::api::v2::auth::DownstreamTlsContext& downstream_tls_context); - /** * Translate a v1 JSON TLS context to v2 envoy::api::v2::auth::UpstreamTlsContext. * @param json_tls_context source v1 JSON TLS context object. diff --git a/source/common/network/transport_socket_options_impl.h b/source/common/network/transport_socket_options_impl.h index ba544a67d7656..0010a46d763a8 100644 --- a/source/common/network/transport_socket_options_impl.h +++ b/source/common/network/transport_socket_options_impl.h @@ -7,19 +7,25 @@ namespace Network { class TransportSocketOptionsImpl : public TransportSocketOptions { public: - TransportSocketOptionsImpl(absl::string_view override_server_name = "") + TransportSocketOptionsImpl(absl::string_view override_server_name = "", + std::vector&& override_verify_san_list = {}) : override_server_name_(override_server_name.empty() ? absl::nullopt - : absl::optional(override_server_name)) {} + : absl::optional(override_server_name)), + override_verify_san_list_{std::move(override_verify_san_list)} {} // Network::TransportSocketOptions const absl::optional& serverNameOverride() const override { return override_server_name_; } + const std::vector& verifySubjectAltNameListOverride() const override { + return override_verify_san_list_; + } void hashKey(std::vector& key) const override; private: const absl::optional override_server_name_; + const std::vector override_verify_san_list_; }; } // namespace Network diff --git a/source/common/upstream/logical_dns_cluster.cc b/source/common/upstream/logical_dns_cluster.cc index 88ce5e02da5bc..06c1e415b845c 100644 --- a/source/common/upstream/logical_dns_cluster.cc +++ b/source/common/upstream/logical_dns_cluster.cc @@ -89,8 +89,8 @@ void LogicalDnsCluster::startResolve() { } if (!logical_host_) { - logical_host_.reset( - new LogicalHost(info_, hostname_, new_address, localityLbEndpoint(), lbEndpoint())); + logical_host_.reset(new LogicalHost(info_, hostname_, new_address, localityLbEndpoint(), + lbEndpoint(), nullptr)); const auto& locality_lb_endpoint = localityLbEndpoint(); PriorityStateManager priority_state_manager(*this, local_info_, nullptr); diff --git a/source/common/upstream/logical_host.cc b/source/common/upstream/logical_host.cc index a6c9c20ede4ce..a196e8fbd2344 100644 --- a/source/common/upstream/logical_host.cc +++ b/source/common/upstream/logical_host.cc @@ -8,7 +8,9 @@ Upstream::Host::CreateConnectionData LogicalHost::createConnection( Network::TransportSocketOptionsSharedPtr transport_socket_options) const { const auto current_address = address(); return {HostImpl::createConnection(dispatcher, cluster(), current_address, options, - transport_socket_options), + override_transport_socket_options_ != nullptr + ? override_transport_socket_options_ + : transport_socket_options), std::make_shared(current_address, shared_from_this())}; } diff --git a/source/common/upstream/logical_host.h b/source/common/upstream/logical_host.h index d22a415a2fcf4..a1ed7eee2f9e4 100644 --- a/source/common/upstream/logical_host.h +++ b/source/common/upstream/logical_host.h @@ -14,11 +14,13 @@ class LogicalHost : public HostImpl { LogicalHost(const ClusterInfoConstSharedPtr& cluster, const std::string& hostname, const Network::Address::InstanceConstSharedPtr& address, const envoy::api::v2::endpoint::LocalityLbEndpoints& locality_lb_endpoint, - const envoy::api::v2::endpoint::LbEndpoint& lb_endpoint) + const envoy::api::v2::endpoint::LbEndpoint& lb_endpoint, + const Network::TransportSocketOptionsSharedPtr& override_transport_socket_options) : HostImpl(cluster, hostname, address, lb_endpoint.metadata(), lb_endpoint.load_balancing_weight().value(), locality_lb_endpoint.locality(), lb_endpoint.endpoint().health_check_config(), locality_lb_endpoint.priority(), - lb_endpoint.health_status()) {} + lb_endpoint.health_status()), + override_transport_socket_options_(override_transport_socket_options) {} // Set the new address. Updates are typically rare so a R/W lock is used for address updates. // Note that the health check address update requires no lock to be held since it is only @@ -51,6 +53,7 @@ class LogicalHost : public HostImpl { } private: + const Network::TransportSocketOptionsSharedPtr override_transport_socket_options_; mutable absl::Mutex address_lock_; }; diff --git a/source/extensions/clusters/dynamic_forward_proxy/BUILD b/source/extensions/clusters/dynamic_forward_proxy/BUILD index 861a2da0a10b4..51ba531f70b74 100644 --- a/source/extensions/clusters/dynamic_forward_proxy/BUILD +++ b/source/extensions/clusters/dynamic_forward_proxy/BUILD @@ -13,6 +13,7 @@ envoy_cc_library( srcs = ["cluster.cc"], hdrs = ["cluster.h"], deps = [ + "//source/common/network:transport_socket_options_lib", "//source/common/upstream:cluster_factory_lib", "//source/common/upstream:logical_host_lib", "//source/extensions/clusters:well_known_names", diff --git a/source/extensions/clusters/dynamic_forward_proxy/cluster.cc b/source/extensions/clusters/dynamic_forward_proxy/cluster.cc index e67066f9a4447..37bfa8f6f5b5f 100644 --- a/source/extensions/clusters/dynamic_forward_proxy/cluster.cc +++ b/source/extensions/clusters/dynamic_forward_proxy/cluster.cc @@ -1,5 +1,7 @@ #include "extensions/clusters/dynamic_forward_proxy/cluster.h" +#include "common/network/transport_socket_options_impl.h" + #include "extensions/common/dynamic_forward_proxy/dns_cache_manager_impl.h" namespace Envoy { @@ -7,10 +9,6 @@ namespace Extensions { namespace Clusters { namespace DynamicForwardProxy { -// TODO(mattklein123): Make sure that the cluster's hosts display their host name in admin output. -// TODO(mattklein123): Allow customizing TLS on a per-host basis. For example, setting SNI and -// doing certificate validation. - Cluster::Cluster( const envoy::api::v2::Cluster& cluster, const envoy::config::cluster::dynamic_forward_proxy::v2alpha::ClusterConfig& config, @@ -58,14 +56,15 @@ void Cluster::onDnsHostAddOrUpdate( HostInfoMapSharedPtr current_map = getCurrentHostMap(); const auto host_map_it = current_map->find(host); if (host_map_it != current_map->end()) { - // If we only have an address change, we can do that swap inline without any other updates. The - // appropriate R/W locking is in place to allow this. The details of this locking are: + // If we only have an address change, we can do that swap inline without any other updates. + // The appropriate R/W locking is in place to allow this. The details of this locking are: // - Hosts are not thread local, they are global. // - We take a read lock when reading the address and a write lock when changing it. // - Address updates are very rare. - // - Address reads are only done when a connection is being made and a "real" host description - // is created or the host is queries via the admin endpoint. Both of these operations are - // relatively rare and the read lock is held for a short period of time. + // - Address reads are only done when a connection is being made and a "real" host + // description is created or the host is queried via the admin endpoint. Both of + // these operations are relatively rare and the read lock is held for a short period + // of time. // // TODO(mattklein123): Right now the dynamic forward proxy / DNS cache works similar to how // logical DNS works, meaning that we only store a single address per @@ -82,11 +81,20 @@ void Cluster::onDnsHostAddOrUpdate( } ENVOY_LOG(debug, "adding new dfproxy cluster host '{}'", host); + + // Create an override transport socket options that automatically provides both SNI as well as + // SAN verification for the resolved host if the cluster has been configured with TLS. + // TODO(mattklein123): If the host is an IP address we should not set SNI. + Network::TransportSocketOptionsSharedPtr transport_socket_options = + std::make_shared( + host_info->resolvedHost(), std::vector{host_info->resolvedHost()}); + const auto new_host_map = std::make_shared(*current_map); - const auto emplaced = new_host_map->try_emplace( - host, host_info, - std::make_shared(info(), host, host_info->address(), - dummy_locality_lb_endpoint_, dummy_lb_endpoint_)); + const auto emplaced = + new_host_map->try_emplace(host, host_info, + std::make_shared( + info(), host, host_info->address(), dummy_locality_lb_endpoint_, + dummy_lb_endpoint_, transport_socket_options)); Upstream::HostVector hosts_added; hosts_added.emplace_back(emplaced.first->second.logical_host_); diff --git a/source/extensions/common/dynamic_forward_proxy/dns_cache.h b/source/extensions/common/dynamic_forward_proxy/dns_cache.h index 96ee2d5a7473c..3a0fb4580ef30 100644 --- a/source/extensions/common/dynamic_forward_proxy/dns_cache.h +++ b/source/extensions/common/dynamic_forward_proxy/dns_cache.h @@ -23,6 +23,12 @@ class DnsHostInfo { */ virtual Network::Address::InstanceConstSharedPtr address() PURE; + /** + * Returns the host that was actually resolved via DNS. If port was originally specified it will + * be stripped from this return value. + */ + virtual const std::string& resolvedHost() PURE; + /** * Indicates that the host has been used and should not be purged depending on any configured * TTL policy diff --git a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc index b8173e2dfd00c..0e9a978ff40f6 100644 --- a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc +++ b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc @@ -132,12 +132,12 @@ void DnsCacheImpl::onReResolve(const std::string& host) { void DnsCacheImpl::startResolve(const std::string& host, PrimaryHostInfo& host_info) { ENVOY_LOG(debug, "starting main thread resolve for host='{}' dns='{}' port='{}'", host, - host_info.host_to_resolve_, host_info.port_); + host_info.host_info_->resolved_host_, host_info.port_); ASSERT(host_info.active_query_ == nullptr); stats_.dns_query_attempt_.inc(); host_info.active_query_ = - resolver_->resolve(host_info.host_to_resolve_, dns_lookup_family_, + resolver_->resolve(host_info.host_info_->resolved_host_, dns_lookup_family_, [this, host](std::list&& response) { finishResolve(host, std::move(response)); }); @@ -151,11 +151,8 @@ void DnsCacheImpl::finishResolve(const std::string& host, auto& primary_host_info = *primary_host_it->second; primary_host_info.active_query_ = nullptr; - const bool first_resolve = primary_host_info.host_info_ == nullptr; - if (primary_host_info.host_info_ == nullptr) { - primary_host_info.host_info_ = - std::make_shared(main_thread_dispatcher_.timeSource()); - } + const bool first_resolve = !primary_host_info.host_info_->first_resolve_complete_; + primary_host_info.host_info_->first_resolve_complete_ = true; const auto new_address = !response.empty() ? Network::Utility::getAddressWithPort(*(response.front().address_), @@ -211,9 +208,8 @@ void DnsCacheImpl::runRemoveCallbacks(const std::string& host) { void DnsCacheImpl::updateTlsHostsMap() { TlsHostMapSharedPtr new_host_map = std::make_shared(); for (const auto& primary_host : primary_hosts_) { - // Do not include hosts without host info. This only happens before we get the first - // resolution. - if (primary_host.second->host_info_ != nullptr) { + // Do not include hosts that have not resolved at least once. + if (primary_host.second->host_info_->first_resolve_complete_) { new_host_map->emplace(primary_host.first, primary_host.second->host_info_); } } @@ -249,8 +245,10 @@ void DnsCacheImpl::ThreadLocalHostInfo::updateHostMap(const TlsHostMapSharedPtr& DnsCacheImpl::PrimaryHostInfo::PrimaryHostInfo(DnsCacheImpl& parent, absl::string_view host_to_resolve, uint16_t port, const Event::TimerCb& timer_cb) - : parent_(parent), host_to_resolve_(host_to_resolve), port_(port), - refresh_timer_(parent.main_thread_dispatcher_.createTimer(timer_cb)) { + : parent_(parent), port_(port), + refresh_timer_(parent.main_thread_dispatcher_.createTimer(timer_cb)), + host_info_(std::make_shared(parent.main_thread_dispatcher_.timeSource(), + host_to_resolve)) { parent_.stats_.host_added_.inc(); parent_.stats_.num_hosts_.inc(); } diff --git a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.h b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.h index 7ecccdf3a8d27..440617b61c70c 100644 --- a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.h +++ b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.h @@ -71,13 +71,19 @@ class DnsCacheImpl : public DnsCache, Logger::Loggable ContextImpl::parseAlpnProtocols(const std::string& alpn_pro return out; } -bssl::UniquePtr ContextImpl::newSsl(absl::optional) { +bssl::UniquePtr ContextImpl::newSsl(const Network::TransportSocketOptions*) { // We use the first certificate for a new SSL object, later in the // SSL_CTX_set_select_certificate_cb() callback following ClientHello, we replace with the // selected certificate via SSL_set_SSL_CTX(). @@ -419,12 +419,18 @@ int ContextImpl::verifyCallback(X509_STORE_CTX* store_ctx, void* arg) { SSL* ssl = reinterpret_cast( X509_STORE_CTX_get_ex_data(store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx())); bssl::UniquePtr cert(SSL_get_peer_certificate(ssl)); - return impl->verifyCertificate(cert.get()); + + const Network::TransportSocketOptions* transport_socket_options = + static_cast(SSL_get_app_data(ssl)); + return impl->verifyCertificate( + cert.get(), transport_socket_options && + !transport_socket_options->verifySubjectAltNameListOverride().empty() + ? transport_socket_options->verifySubjectAltNameListOverride() + : impl->verify_subject_alt_name_list_); } -int ContextImpl::verifyCertificate(X509* cert) { - if (!verify_subject_alt_name_list_.empty() && - !verifySubjectAltName(cert, verify_subject_alt_name_list_)) { +int ContextImpl::verifyCertificate(X509* cert, const std::vector& verify_san_list) { + if (!verify_san_list.empty() && !verifySubjectAltName(cert, verify_san_list)) { stats_.fail_verify_san_.inc(); return 0; } @@ -664,17 +670,23 @@ ClientContextImpl::ClientContextImpl(Stats::Scope& scope, } } -bssl::UniquePtr ClientContextImpl::newSsl(absl::optional override_server_name) { - bssl::UniquePtr ssl_con(ContextImpl::newSsl(absl::nullopt)); +bssl::UniquePtr ClientContextImpl::newSsl(const Network::TransportSocketOptions* options) { + bssl::UniquePtr ssl_con(ContextImpl::newSsl(options)); - std::string server_name_indication = - override_server_name.has_value() ? override_server_name.value() : server_name_indication_; + const std::string server_name_indication = options && options->serverNameOverride().has_value() + ? options->serverNameOverride().value() + : server_name_indication_; if (!server_name_indication.empty()) { int rc = SSL_set_tlsext_host_name(ssl_con.get(), server_name_indication.c_str()); RELEASE_ASSERT(rc, ""); } + if (options && !options->verifySubjectAltNameListOverride().empty()) { + SSL_set_app_data(ssl_con.get(), options); + SSL_set_verify(ssl_con.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); + } + if (allow_renegotiation_) { SSL_set_renegotiate_mode(ssl_con.get(), ssl_renegotiate_freely); } diff --git a/source/extensions/transport_sockets/tls/context_impl.h b/source/extensions/transport_sockets/tls/context_impl.h index 57c8ffbdec350..c4cf67d6cfa8a 100644 --- a/source/extensions/transport_sockets/tls/context_impl.h +++ b/source/extensions/transport_sockets/tls/context_impl.h @@ -5,6 +5,7 @@ #include #include +#include "envoy/network/transport_socket.h" #include "envoy/ssl/context.h" #include "envoy/ssl/context_config.h" #include "envoy/stats/scope.h" @@ -46,7 +47,7 @@ struct SslStats { class ContextImpl : public virtual Envoy::Ssl::Context { public: - virtual bssl::UniquePtr newSsl(absl::optional override_server_name); + virtual bssl::UniquePtr newSsl(const Network::TransportSocketOptions* options); /** * Logs successful TLS handshake and updates stats. @@ -94,7 +95,7 @@ class ContextImpl : public virtual Envoy::Ssl::Context { // A SSL_CTX_set_cert_verify_callback for custom cert validation. static int verifyCallback(X509_STORE_CTX* store_ctx, void* arg); - int verifyCertificate(X509* cert); + int verifyCertificate(X509* cert, const std::vector& verify_san_list); /** * Verifies certificate hash for pinning. The hash is a hex-encoded SHA-256 of the DER-encoded @@ -168,7 +169,7 @@ class ClientContextImpl : public ContextImpl, public Envoy::Ssl::ClientContext { ClientContextImpl(Stats::Scope& scope, const Envoy::Ssl::ClientContextConfig& config, TimeSource& time_source); - bssl::UniquePtr newSsl(absl::optional override_server_name) override; + bssl::UniquePtr newSsl(const Network::TransportSocketOptions* options) override; private: int newSessionKey(SSL_SESSION* session); diff --git a/source/extensions/transport_sockets/tls/ssl_socket.cc b/source/extensions/transport_sockets/tls/ssl_socket.cc index 519495a1b76b8..d6b63be7d0918 100644 --- a/source/extensions/transport_sockets/tls/ssl_socket.cc +++ b/source/extensions/transport_sockets/tls/ssl_socket.cc @@ -43,11 +43,10 @@ class NotReadySslSocket : public Network::TransportSocket { } // namespace SslSocket::SslSocket(Envoy::Ssl::ContextSharedPtr ctx, InitialState state, - Network::TransportSocketOptionsSharedPtr transport_socket_options) - : ctx_(std::dynamic_pointer_cast(ctx)), - ssl_(ctx_->newSsl(transport_socket_options != nullptr - ? transport_socket_options->serverNameOverride() - : absl::nullopt)) { + const Network::TransportSocketOptionsSharedPtr& transport_socket_options) + : transport_socket_options_(transport_socket_options), + ctx_(std::dynamic_pointer_cast(ctx)), + ssl_(ctx_->newSsl(transport_socket_options_.get())) { if (state == InitialState::Client) { SSL_set_connect_state(ssl_.get()); } else { diff --git a/source/extensions/transport_sockets/tls/ssl_socket.h b/source/extensions/transport_sockets/tls/ssl_socket.h index 7b00ba406387f..549ffbf83696f 100644 --- a/source/extensions/transport_sockets/tls/ssl_socket.h +++ b/source/extensions/transport_sockets/tls/ssl_socket.h @@ -44,7 +44,7 @@ class SslSocket : public Network::TransportSocket, protected Logger::Loggable { public: SslSocket(Envoy::Ssl::ContextSharedPtr ctx, InitialState state, - Network::TransportSocketOptionsSharedPtr transport_socket_options); + const Network::TransportSocketOptionsSharedPtr& transport_socket_options); // Ssl::ConnectionInfo bool peerCertificatePresented() const override; @@ -90,6 +90,7 @@ class SslSocket : public Network::TransportSocket, void drainErrorQueue(); void shutdownSsl(); + const Network::TransportSocketOptionsSharedPtr transport_socket_options_; Network::TransportSocketCallbacks* callbacks_{}; ContextImplSharedPtr ctx_; bssl::UniquePtr ssl_; diff --git a/test/config/integration/certs/README.md b/test/config/integration/certs/README.md index 78eb2a677c2d7..2f6dfabaff116 100644 --- a/test/config/integration/certs/README.md +++ b/test/config/integration/certs/README.md @@ -11,6 +11,10 @@ There are 5 identities: - **Upstream**: It has the certificate *upstreamcert.pem*, which is signed by the **Upstream CA** using the config *upstreamcert.cfg*. *upstreamkey.pem* is its private key. +- **Upstream localhost**: It has the certificate *upstreamlocalhostcert.pem*, which is signed by + the **Upstream CA** using the config *upstreamlocalhostcert.cfg*. *upstreamlocalhostkey.pem* is + its private key. The different between this certificate and **Upstream** is that this certifcate + has a SAN for "localhost". # How to update certificates **certs.sh** has the commands to generate all files. Running certs.sh directly diff --git a/test/config/integration/certs/certs.sh b/test/config/integration/certs/certs.sh index 8798fe9a50130..d67da84352da9 100755 --- a/test/config/integration/certs/certs.sh +++ b/test/config/integration/certs/certs.sh @@ -52,6 +52,8 @@ generate_ca upstreamca # Generate cert for the upstream node. generate_rsa_key upstream upstreamca generate_x509_cert upstream upstreamca +generate_rsa_key upstreamlocalhost upstreamca +generate_x509_cert upstreamlocalhost upstreamca rm *.csr rm *.srl diff --git a/test/config/integration/certs/upstreamcacert.pem b/test/config/integration/certs/upstreamcacert.pem index b812dee4e3a21..c3d5692354bd7 100644 --- a/test/config/integration/certs/upstreamcacert.pem +++ b/test/config/integration/certs/upstreamcacert.pem @@ -1,23 +1,24 @@ -----BEGIN CERTIFICATE----- -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 +4P3c -----END CERTIFICATE----- diff --git a/test/config/integration/certs/upstreamcakey.pem b/test/config/integration/certs/upstreamcakey.pem index c9f1c73c7cb89..2fe99b9c2c105 100644 --- a/test/config/integration/certs/upstreamcakey.pem +++ b/test/config/integration/certs/upstreamcakey.pem @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/test/config/integration/certs/upstreamcert.pem b/test/config/integration/certs/upstreamcert.pem index 19d9ced64a22a..509397d6caa86 100644 --- a/test/config/integration/certs/upstreamcert.pem +++ b/test/config/integration/certs/upstreamcert.pem @@ -1,25 +1,25 @@ -----BEGIN CERTIFICATE----- -MIIEMzCCAxugAwIBAgIJAOOWZZgU2DxcMA0GCSqGSIb3DQEBCwUAMH8xCzAJBgNV -BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp -c2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2luZWVyaW5nMRkw -FwYDVQQDDBBUZXN0IFVwc3RyZWFtIENBMB4XDTE4MTIxNzIwMTgwMFoXDTIwMTIx -NjIwMTgwMFowgYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYw -FAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBM -eWZ0IEVuZ2luZWVyaW5nMR0wGwYDVQQDDBRUZXN0IFVwc3RyZWFtIFNlcnZlcjCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALxFMTgM8XOMFueOZ1SFVuEf -aa/WZs2Tm5OQJBCnQUlSq8QafvT7jg6YqB8ap6AA/LwYn9G6Q/dN+7SlVxEzIZlj -UspSd5iCuhYVVXpR1PrmYIyl5pDY5nX7eRrMhhgxUSnWf9bt4azu2FH+K89wazV9 -4uw1gpxkw3Ocj9HWiseNz+IE1iwMlSr/1n0jRZFKqnnfveuGByIANRj7DpnNJgZm -dMenBr4KeJEl/alvESRb0Zf0vWgDfwwUHs4rR7ZQl48Spjd7xjIoAQZ5DY8UKxB0 -BTTzeSkuvuxVSrAYefIIpq15rU4laKBcRkj9f8tvd53DJHWmvsVkCLlA6BkLqnUC -AwEAAaOBrDCBqTAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAU -BggrBgEFBQcDAgYIKwYBBQUHAwEwLQYDVR0RBCYwJIIKKi5seWZ0LmNvbYcEAAAA -AIcQAAAAAAAAAAAAAAAAAAAAADAdBgNVHQ4EFgQU/HB8QxqmxcgL4WPoyewp4ooz -UhcwHwYDVR0jBBgwFoAUqbsVny7rxHz5IgkTnIe1mx0sWHAwDQYJKoZIhvcNAQEL -BQADggEBAI1JScIpfxjLV5BrgflVKCjeABBuMGFj3qZOCBuiBbFTt+KOpc9dmfzL -bDSg9cLRe9MhFqaLFrzqAOZfqwCxB8jsAEMaki4anwm3fefC8D5H8uBB5KckZExk -/j/y0UYpnH21xvj7Z4M4bOMACTneel2IJ8rTzJD5QbSersbxB7FF/cOEZNt2B94l -6hkPaZzvzxjwizK6XDnpLPAQnytMPAcrPSAS9wmRPfjGgG4xFcc3EoqJKpCuymTt -hSLzAsLBP7NOITlgA0iRCU5Ly//TLnmLcA4iAVYQaog21cJYxEbRJTIm9z73/88D -bf/hoN53Jhgwt+xFK0CKZyahhZGsuXs= +MIIEPjCCAyagAwIBAgIUS0ht/ypqxlVqt86GiCya6cw/jJwwDQYJKoZIhvcNAQEL +BQAwfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsMEEx5ZnQgRW5n +aW5lZXJpbmcxGTAXBgNVBAMMEFRlc3QgVXBzdHJlYW0gQ0EwHhcNMTkwNzA4MjE0 +NTU3WhcNMjEwNzA3MjE0NTU3WjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh +bGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQx +GTAXBgNVBAsMEEx5ZnQgRW5naW5lZXJpbmcxHTAbBgNVBAMMFFRlc3QgVXBzdHJl +YW0gU2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+evHY2ld +y4iKlGEHtenqIK26QeFpU9t2iqiRjUz0+lZ+92haR+I+x1nL41SO71i2SaHp8L2Q +5cWkOS0zuYivsZSz/l9dHinAS+N50QsERo01moWOMyxfqSEbnZHMQS4OI/mf1dja +Rykp7zhCXie2BlUtmiBMW+YnvLmBm1z6icwg7ZBJ8mt2ChpeH6qBggzwQQms9wvK +/mcHR5HYHalLQdjhou3wwa6MB9bbeEoDd8I0tueRgnrq55mVJrm3yg1TSgUwkWCB +J3VUrvdk3olgGwHv4njAB+uNfUn3od7MuipyHL8GJQJHOcus63M/Ax/UVxu0BiDy +LfWW4MVO/5OX5QIDAQABo4GsMIGpMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXg +MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAtBgNVHREEJjAkggoqLmx5 +ZnQuY29thwQAAAAAhxAAAAAAAAAAAAAAAAAAAAAAMB0GA1UdDgQWBBR3BvXiz3zi +p+/5cojIhCEz3nn39jAfBgNVHSMEGDAWgBTi0zC68szQHLsXt3ChIQpZC+yHbjAN +BgkqhkiG9w0BAQsFAAOCAQEAEB9RWuGIcRhZMM2AqXyOr4FOG63yfVg4fi3/WIcu +p7iVPhtdByefx4FQxg7913rdJyeQrI+hab0uPl/CjylwMVwWtBqRx4oKo8im59/4 +N7MRYZKJ44/fBSIGoM0pibSpDzfd7y6Drusp1mqi3CXGPXsVFIDQ66d7yoFt+t7h +nB2A565e/C1eXaS80XTHeJzfS5dJ6ssjgyszTGM5PdN9C335pDGfQV0CqGNAMZqo +tbBI1B0NgQ2KJJ787Wi3pexxi3haliMNrSKEAkLVDZ6R0a1PgpN/hBth3Nf2Oj+O ++pBNtkiA0fnkoKS6ps9Vgj+NB08OLeYNpfGFHa9xxFdPoA== -----END CERTIFICATE----- diff --git a/test/config/integration/certs/upstreamcert_hash.h b/test/config/integration/certs/upstreamcert_hash.h index 9b872dc40cb52..4342078b93804 100644 --- a/test/config/integration/certs/upstreamcert_hash.h +++ b/test/config/integration/certs/upstreamcert_hash.h @@ -1,3 +1,3 @@ // NOLINT(namespace-envoy) -constexpr char TEST_UPSTREAM_CERT_HASH[] = "89:92:C7:6D:B7:92:42:B3:77:77:6F:77:1C:51:04:1B:D7:27:" - "25:A7:7E:75:A9:6A:0A:F7:23:F9:F6:50:A5:34"; +constexpr char TEST_UPSTREAM_CERT_HASH[] = "57:0E:EF:74:60:9C:8E:3D:AA:EA:3F:3E:02:69:89:40:E6:00:" + "AD:CA:86:69:73:BA:9E:0B:01:A2:E2:F3:75:7F"; diff --git a/test/config/integration/certs/upstreamkey.pem b/test/config/integration/certs/upstreamkey.pem index d5e94728c7f5e..58945f2125add 100644 --- a/test/config/integration/certs/upstreamkey.pem +++ b/test/config/integration/certs/upstreamkey.pem @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/test/config/integration/certs/upstreamlocalhostcert.cfg b/test/config/integration/certs/upstreamlocalhostcert.cfg new file mode 100644 index 0000000000000..fbea513733e9b --- /dev/null +++ b/test/config/integration/certs/upstreamlocalhostcert.cfg @@ -0,0 +1,38 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = US +countryName_default = US +stateOrProvinceName = California +stateOrProvinceName_default = California +localityName = San Francisco +localityName_default = San Francisco +organizationName = Lyft +organizationName_default = Lyft +organizationalUnitName = Lyft Engineering +organizationalUnitName_default = Lyft Engineering +commonName = Test Upstream Server +commonName_default = Test Upstream Server +commonName_max = 64 + +[v3_req] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names +subjectKeyIdentifier = hash + +[v3_ca] +basicConstraints = critical, CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always + +[alt_names] +DNS.2 = localhost +IP.1 = 0.0.0.0 +IP.2 = :: diff --git a/test/config/integration/certs/upstreamlocalhostcert.pem b/test/config/integration/certs/upstreamlocalhostcert.pem new file mode 100644 index 0000000000000..e34ab833d86c7 --- /dev/null +++ b/test/config/integration/certs/upstreamlocalhostcert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEPTCCAyWgAwIBAgIUS0ht/ypqxlVqt86GiCya6cw/jJ0wDQYJKoZIhvcNAQEL +BQAwfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsMEEx5ZnQgRW5n +aW5lZXJpbmcxGTAXBgNVBAMMEFRlc3QgVXBzdHJlYW0gQ0EwHhcNMTkwNzA4MjE0 +NTU3WhcNMjEwNzA3MjE0NTU3WjCBgzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh +bGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQx +GTAXBgNVBAsMEEx5ZnQgRW5naW5lZXJpbmcxHTAbBgNVBAMMFFRlc3QgVXBzdHJl +YW0gU2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAujOqV+UB +T8oKxxnIlgKMPn10hIZxOOEzA96CDMQtQ2+180HLfSTErLWzQFNeP6jRDcbXTN0w +tYJlIUmVJtPaj7Dh4VvpORhRwAPZt9bkHcKKFCIaGYj61YCv3YpNyBSfJ0vwgATD +Yn6I2R8nobMKau/hMk4SpPZ6Z3pwSEt0GHd9/cE7t1WvE4BhqIjznexeFO+YrgvF +2ea4j7u4hJxezZhzAqOUyqtlbfkHQwXXzg/93PxBY5Y1mUPszjY+doGhW3DfTI1O +qgU2OfAoFZ6SKtUphUG/gt5DKHvKeARCWMEaUXC9UkyzhSNIl7s8qnRzweZwyOIk +KClryNQCtTjHOwIDAQABo4GrMIGoMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXg +MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAsBgNVHREEJTAjgglsb2Nh +bGhvc3SHBAAAAACHEAAAAAAAAAAAAAAAAAAAAAAwHQYDVR0OBBYEFPlBuX/WSFDb ++nUGMLTu7svrrtolMB8GA1UdIwQYMBaAFOLTMLryzNAcuxe3cKEhClkL7IduMA0G +CSqGSIb3DQEBCwUAA4IBAQCgknWXc/Iz/Av6inDxGOncsNlYehKU+UBoR69HlcUE +AEOW7nFaPey5zLL3dgTJd1nOe0u97yT5Hoy9b7O9z5cBWHkNYqFh2oEZKXeDtS81 +z/N4ZQuPxxAlS4d7krAsQNB2vjMFp81eGude680twbto6LKRg9iJMv+AeEJD9p0j +ubeZA20j8YV8Aijm/kNe82d+TQYULxQeLo5QM6VU0pK2VcCunHywcYFc/t99Ync6 +NaqGrxOu6Jfduzg0TsZsIX7GveYC4dmx3CK1qOSB7SE2SVQjAITZL7gIvbLQPEKu +XJrmpIIhgUw+AgPq7D8JEaLoYERCRQLWt4v/yVus2Tgd +-----END CERTIFICATE----- diff --git a/test/config/integration/certs/upstreamlocalhostcert_hash.h b/test/config/integration/certs/upstreamlocalhostcert_hash.h new file mode 100644 index 0000000000000..409ad0af1cd36 --- /dev/null +++ b/test/config/integration/certs/upstreamlocalhostcert_hash.h @@ -0,0 +1,4 @@ +// NOLINT(namespace-envoy) +constexpr char TEST_UPSTREAMLOCALHOST_CERT_HASH[] = + "5B:5C:02:47:DE:17:B7:1B:98:05:0A:DB:41:2C:F6:8F:65:E3:86:E6:03:B3:9A:EC:67:33:2E:39:1F:05:88:" + "B0"; diff --git a/test/config/integration/certs/upstreamlocalhostkey.pem b/test/config/integration/certs/upstreamlocalhostkey.pem new file mode 100644 index 0000000000000..7bf369f08b6d3 --- /dev/null +++ b/test/config/integration/certs/upstreamlocalhostkey.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAujOqV+UBT8oKxxnIlgKMPn10hIZxOOEzA96CDMQtQ2+180HL +fSTErLWzQFNeP6jRDcbXTN0wtYJlIUmVJtPaj7Dh4VvpORhRwAPZt9bkHcKKFCIa +GYj61YCv3YpNyBSfJ0vwgATDYn6I2R8nobMKau/hMk4SpPZ6Z3pwSEt0GHd9/cE7 +t1WvE4BhqIjznexeFO+YrgvF2ea4j7u4hJxezZhzAqOUyqtlbfkHQwXXzg/93PxB +Y5Y1mUPszjY+doGhW3DfTI1OqgU2OfAoFZ6SKtUphUG/gt5DKHvKeARCWMEaUXC9 +UkyzhSNIl7s8qnRzweZwyOIkKClryNQCtTjHOwIDAQABAoIBABS0H/Gr9exgQ7iF +pmb/m4ZrPqRpqncvmxOIDx/KRFomNq34l96vUur9PRQe8PDVHYGRpWjXg037VLFR +1DLABaJKgaMkLBd8G8Lk6rVlQHIKqn24mPxT3cgVifhxI1rm6BdfeztQzETMWv0B +WM/C75qaV4jXY31SJqQQ2iE/uoXpuqHtBqxVE9TnBi0NvN2ZXlcxGgwnv7SYKrkE +4c9M5q0F5mJAAkHsrgyyQY18/op/vtQGbKvsdkuT9ihzruaeXxB6M04nevxdDn3r +dC5GUz05c+GCqCmMppU2gRPKYH0t/mvXfZhoGiOujfhTUbiIjQBle1kaxXmZl7Zr +Kz+lO+kCgYEA8IOstfsxJ6Zdf4Xvqi6MLr3MKZT3MmSpKT1dOixzYtD1IS1qc0hF +t4+SNhlP1ny5TlFF12356AC4TMM+kjlhCu9uAsvjqI5M/XSQ00SvybADbYoQc7jy +v9d69AEPOslmfQ7GYDAlFKT5NTK6tXEVpX1MIs6+LSl2pi4emtW7EzUCgYEAxjDG +Db/yEzanLyPC2Yfjk8KotnmprVZmXvmSWl0frOjWxbmYq2auVMNgBysY0+k8OHWk +MQjtjbVqA5b4Ze5Rm0Z7XlWieioxLt1naG3Gb0NAtaivmouaovlrIlZf7GtT4haC +Q4/GN9gGUxdjLLJRJ/WcdOG4X4gp7Opj19eazq8CgYAXVF5rZIs3El8dYIuH0W4N +lqF4Ixf7TmJOOsKRQwCKRESSzEn4FrmUfZusHbZt0rlSzHVe2S8VfwRhhcrK+j/c +hK8CHG7fybXUG/t0UsROZwFeHbdM0lLRowAtLPEiPajwVn+Nkv31y67UpzAPK4Hz +BH1fHvi5fr0gj3auhC7aRQKBgEEAAhTEXSp8BDzrp54ceUEe2KJwKHwXGCASDjPg +0uCsxLO4eR/N32MhaL8xHUVy+zMxMhZ67R5K32gp/XHAxbb9WLzJrS4P5G2QY7fW +OPyIvBJYLq+rFZ5Z2w858N/jG3HNHA/4eXQbP4fE5dvk58UJQrT6yrNaPxXakcBa +kAU1AoGBAJSSjgV9kR2tGzhBFqL0K11E5GP9uzO3sib3Zd7gtOJTO1cvJaLES3BV +Q6sxR9gPJ5cSpTXCNbaJwZ+jAsTfhJj8PE15am/JG7d7xZkflZIdfSf9/23g26w1 +dagOuDPRC2mcbjzprdPRLbNk3NfI/Llw+CboMP6R/smOYf/HRpS9 +-----END RSA PRIVATE KEY----- diff --git a/test/extensions/clusters/dynamic_forward_proxy/cluster_test.cc b/test/extensions/clusters/dynamic_forward_proxy/cluster_test.cc index d15870581e24f..6d8db1e762b73 100644 --- a/test/extensions/clusters/dynamic_forward_proxy/cluster_test.cc +++ b/test/extensions/clusters/dynamic_forward_proxy/cluster_test.cc @@ -67,6 +67,7 @@ class ClusterTest : public testing::Test, // Allow touch() to still be strict. EXPECT_CALL(*host_map_[host], address()).Times(AtLeast(0)); + EXPECT_CALL(*host_map_[host], resolvedHost()).Times(AtLeast(0)); } void updateTestHostAddress(const std::string& host, const std::string& address) { diff --git a/test/extensions/common/dynamic_forward_proxy/mocks.cc b/test/extensions/common/dynamic_forward_proxy/mocks.cc index f2d6c207c009c..9fc2137943343 100644 --- a/test/extensions/common/dynamic_forward_proxy/mocks.cc +++ b/test/extensions/common/dynamic_forward_proxy/mocks.cc @@ -3,6 +3,7 @@ using testing::_; using testing::Return; using testing::ReturnPointee; +using testing::ReturnRef; namespace Envoy { namespace Extensions { @@ -22,6 +23,7 @@ MockDnsCacheManager::~MockDnsCacheManager() = default; MockDnsHostInfo::MockDnsHostInfo() { ON_CALL(*this, address()).WillByDefault(ReturnPointee(&address_)); + ON_CALL(*this, resolvedHost()).WillByDefault(ReturnRef(resolved_host_)); } MockDnsHostInfo::~MockDnsHostInfo() = default; diff --git a/test/extensions/common/dynamic_forward_proxy/mocks.h b/test/extensions/common/dynamic_forward_proxy/mocks.h index 0d2bfad3f1c7b..0c65895c1f7dd 100644 --- a/test/extensions/common/dynamic_forward_proxy/mocks.h +++ b/test/extensions/common/dynamic_forward_proxy/mocks.h @@ -62,9 +62,11 @@ class MockDnsHostInfo : public DnsHostInfo { ~MockDnsHostInfo(); MOCK_METHOD0(address, Network::Address::InstanceConstSharedPtr()); + MOCK_METHOD0(resolvedHost, const std::string&()); MOCK_METHOD0(touch, void()); Network::Address::InstanceConstSharedPtr address_; + std::string resolved_host_; }; class MockUpdateCallbacks : public DnsCache::UpdateCallbacks { diff --git a/test/extensions/filters/http/dynamic_forward_proxy/BUILD b/test/extensions/filters/http/dynamic_forward_proxy/BUILD index f3b9f0a3edff7..881a1be457d7f 100644 --- a/test/extensions/filters/http/dynamic_forward_proxy/BUILD +++ b/test/extensions/filters/http/dynamic_forward_proxy/BUILD @@ -26,6 +26,9 @@ envoy_extension_cc_test( envoy_extension_cc_test( name = "proxy_filter_integration_test", srcs = ["proxy_filter_integration_test.cc"], + data = [ + "//test/config/integration/certs", + ], extension_name = "envoy.filters.http.dynamic_forward_proxy", deps = [ "//source/extensions/clusters/dynamic_forward_proxy:cluster", diff --git a/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc b/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc index ae7d163746824..b2750046922b6 100644 --- a/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc +++ b/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc @@ -1,3 +1,6 @@ +#include "extensions/transport_sockets/tls/context_config_impl.h" +#include "extensions/transport_sockets/tls/ssl_socket.h" + #include "test/integration/http_integration.h" namespace Envoy { @@ -36,11 +39,19 @@ name: envoy.filters.http.dynamic_forward_proxy config_helper_.addFilter(filter); config_helper_.addConfigModifier( - [max_hosts](envoy::config::bootstrap::v2::Bootstrap& bootstrap) { + [this, max_hosts](envoy::config::bootstrap::v2::Bootstrap& bootstrap) { auto* cluster_0 = bootstrap.mutable_static_resources()->mutable_clusters(0); cluster_0->clear_hosts(); cluster_0->set_lb_policy(envoy::api::v2::Cluster::CLUSTER_PROVIDED); + if (upstream_tls_) { + auto context = cluster_0->mutable_tls_context(); + auto* validation_context = + context->mutable_common_tls_context()->mutable_validation_context(); + validation_context->mutable_trusted_ca()->set_filename( + TestEnvironment::runfilesPath("test/config/integration/certs/upstreamcacert.pem")); + } + const std::string cluster_type_config = fmt::format(R"EOF( name: envoy.clusters.dynamic_forward_proxy @@ -58,6 +69,36 @@ name: envoy.clusters.dynamic_forward_proxy HttpIntegrationTest::initialize(); } + + void createUpstreams() override { + if (upstream_tls_) { + fake_upstreams_.emplace_back(new FakeUpstream( + createUpstreamSslContext(), 0, FakeHttpConnection::Type::HTTP1, version_, timeSystem())); + } else { + HttpIntegrationTest::createUpstreams(); + } + } + + // TODO(mattklein123): This logic is duplicated in various places. Cleanup in a follow up. + Network::TransportSocketFactoryPtr createUpstreamSslContext() { + envoy::api::v2::auth::DownstreamTlsContext tls_context; + auto* common_tls_context = tls_context.mutable_common_tls_context(); + auto* tls_cert = common_tls_context->add_tls_certificates(); + tls_cert->mutable_certificate_chain()->set_filename(TestEnvironment::runfilesPath( + fmt::format("test/config/integration/certs/{}cert.pem", upstream_cert_name_))); + tls_cert->mutable_private_key()->set_filename(TestEnvironment::runfilesPath( + fmt::format("test/config/integration/certs/{}key.pem", upstream_cert_name_))); + + auto cfg = std::make_unique( + tls_context, factory_context_); + + static Stats::Scope* upstream_stats_store = new Stats::IsolatedStoreImpl(); + return std::make_unique( + std::move(cfg), context_manager_, *upstream_stats_store, std::vector{}); + } + + bool upstream_tls_{}; + std::string upstream_cert_name_{"upstreamlocalhost"}; }; INSTANTIATE_TEST_SUITE_P(IpVersions, ProxyFilterIntegrationTest, @@ -142,5 +183,53 @@ TEST_P(ProxyFilterIntegrationTest, DNSCacheHostOverflow) { EXPECT_EQ(1, test_server_->counter("dns_cache.foo.host_overflow")->value()); } +// Verify that upstream TLS works with auto verification for SAN as well as auto setting SNI. +TEST_P(ProxyFilterIntegrationTest, UpstreamTls) { + upstream_tls_ = true; + setup(); + codec_client_ = makeHttpConnection(lookupPort("http")); + const Http::TestHeaderMapImpl request_headers{ + {":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", + fmt::format("localhost:{}", fake_upstreams_[0]->localAddress()->ip()->port())}}; + + auto response = codec_client_->makeHeaderOnlyRequest(request_headers); + waitForNextUpstreamRequest(); + + const Extensions::TransportSockets::Tls::SslSocket* ssl_socket = + dynamic_cast( + fake_upstream_connection_->connection().ssl()); + EXPECT_STREQ("localhost", + SSL_get_servername(ssl_socket->rawSslForTest(), TLSEXT_NAMETYPE_host_name)); + + upstream_request_->encodeHeaders(default_response_headers_, true); + response->waitForEndStream(); + checkSimpleRequestSuccess(0, 0, response.get()); +} + +// Verify that auto-SAN verification fails with an incorrect certificate. +TEST_P(ProxyFilterIntegrationTest, UpstreamTlsInvalidSAN) { + upstream_tls_ = true; + upstream_cert_name_ = "upstream"; + setup(); + fake_upstreams_[0]->set_allow_unexpected_disconnects(true); + + codec_client_ = makeHttpConnection(lookupPort("http")); + const Http::TestHeaderMapImpl request_headers{ + {":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", + fmt::format("localhost:{}", fake_upstreams_[0]->localAddress()->ip()->port())}}; + + auto response = codec_client_->makeHeaderOnlyRequest(request_headers); + response->waitForEndStream(); + EXPECT_EQ("503", response->headers().Status()->value().getStringView()); + + EXPECT_EQ(1, test_server_->counter("cluster.cluster_0.ssl.fail_verify_san")->value()); +} + } // namespace } // namespace Envoy diff --git a/test/integration/xfcc_integration_test.cc b/test/integration/xfcc_integration_test.cc index b7e8504864995..2e9a5f12d8a65 100644 --- a/test/integration/xfcc_integration_test.cc +++ b/test/integration/xfcc_integration_test.cc @@ -70,16 +70,16 @@ Network::TransportSocketFactoryPtr XfccIntegrationTest::createClientSslContext(b } Network::TransportSocketFactoryPtr XfccIntegrationTest::createUpstreamSslContext() { - std::string json = R"EOF( -{ - "cert_chain_file": "{{ test_rundir }}/test/config/integration/certs/upstreamcert.pem", - "private_key_file": "{{ test_rundir }}/test/config/integration/certs/upstreamkey.pem" -} -)EOF"; + envoy::api::v2::auth::DownstreamTlsContext tls_context; + auto* common_tls_context = tls_context.mutable_common_tls_context(); + auto* tls_cert = common_tls_context->add_tls_certificates(); + tls_cert->mutable_certificate_chain()->set_filename( + TestEnvironment::runfilesPath("test/config/integration/certs/upstreamcert.pem")); + tls_cert->mutable_private_key()->set_filename( + TestEnvironment::runfilesPath("test/config/integration/certs/upstreamkey.pem")); - Json::ObjectSharedPtr loader = TestEnvironment::jsonLoadFromString(json); auto cfg = std::make_unique( - *loader, factory_context_); + tls_context, factory_context_); static Stats::Scope* upstream_stats_store = new Stats::TestIsolatedStoreImpl(); return std::make_unique( std::move(cfg), *context_manager_, *upstream_stats_store, std::vector{});