Open fuhry opened 2 years ago
There's several things to track here.
Things we should do immediately:
trusted_ca
isn't set, no verification will be performed. Will need to clarify that this matters for downstream mTLS and upstream TLS, but not for downstream non-mutual TLS.Things that make obvious sense to add:
Things that need more discussion:
I agree with @ggreenway summary. In general I would like to move the defaults to be more secure, but it's difficult with compatibility guarantees.
Changing the validation defaults. Reject configuration that doesn't opt-in to not validating peer certs.
One thing I think we could do here that is relatively low friction would be to WARN on any config which is loaded that does not do validation. Then at least the user would be aware (most users look at warnings). We could then have some CLI flag or something to squelch this warning if people really truly do want this.
I know that @alyssawilk has also thought about this before and when we last talked about this we concluded that even figuring what "validation" means is tricky, as Envoy is capable of many different types of validation including pinning, etc.
yeah I think this overlaps some with https://github.com/envoyproxy/envoy/issues/17771 which unfortunately has been on the back burner for some time
Title: Decide whether to improve the default peer validation behavior in the
tls
transport_socket extension, at least for UpstreamTlsContext.Description: It is known and documented that Envoy's
tls
transport socket extension does not verify the peer at all by default. There are numerous reasons why a technical decision like this might be justified:CertificateValidationContext
is clearly aimed at this use case, and provides a great deal of flexibility for this type of deployment.ClientContextImpl::newSsl
) is distinct from the part that performs the validation (cert_validator extension), and while it does support SNI, assuming that the SNI value should always match the peer certificate CN/SAN limits flexibility for the use case above. It looks like only the certificate and configuration options are exposed to the validator extension. I haven't gotten too in the weeds withNetwork::TransportSocketOptions
but it doesn't look connection-specific which means the interface would need to be changed to add connection metadata (SNI value, peer socket address) to the verify callback.But a number of things have changed recently:
dynamic_forward_proxy
family of extensions, and if the DFP cluster extension is being used in a way that Envoy will be responsible for peer validation, it's important that this validation be robust when you're talking to internet hosts!dynamic_forward_proxy
actually independently verifies the peer SAN before selecting a connection out of the pool, and this was important enough to be verified with a functional test. This is really good actually, because it meansdynamic_forward_proxy
can be used in a secure manner without requiring clients to use a CONNECT tunnel, as long as the operator remembers to configuretrusted_ca
orwatched_directory
.SSL_set1_host
needs to be called before the handshake, which means the validation extension hasn't been called yet, and there's no provision in the current interface to hook connection setup.And of course there's the contradiction that when
CertificateValidationContext.trust_chain_verification
is set toVERIFY_TRUST_CHAIN
but thetrusted_ca
andwatched_directory
options are not also configured, no peer verification is actually done - and worse, this is the default. This configuration should be a fatal error, but currently it's silently accepted without even so much as a warning. It's really easy to trip up here and ship an insecure configuration if you miss that sentence in the docs!As a user, I would assume that if the default value of
trust_chain_verification
isVERIFY_TRUST_CHAIN
, then an unconfiguredtrusted_ca
would use the system trust store, and an unconfiguredmatch_typed_subject_alt_names
would check the peer SAN against the SNI value or hostname/IP of the peer according to the underlying socket. If this is not going to be the case, the docs should have a big warning box advising users to configure some sort of peer verification, and Envoy should reject configurations with trust chain verification enabled but no trusted roots configured.So the central question is:
Side questions:
trusted_ca
andtrust_chain_verification
are both unset? If this fails with a fatal error, how concerned are we that this would constitute a regression for existing configurations? Should we requiretrust_chain_verification=ACCEPT_UNTRUSTED
to be explicitly set in order to skip peer verification?Separate issues will be created to track technical work once we arrive at a decision here.
Relevant Links: