docs/root/intro/arch_overview/security/ssl.rst
.. _arch_overview_ssl:
Envoy supports both :ref:TLS termination <envoy_v3_api_field_config.listener.v3.FilterChain.transport_socket> in listeners as well as
:ref:TLS origination <envoy_v3_api_field_config.cluster.v3.Cluster.transport_socket> when making connections to upstream
clusters. Support is sufficient for Envoy to perform standard edge proxy duties for modern web
services as well as to initiate connections with external services that have advanced TLS
requirements (TLS1.2, SNI, etc.). Envoy supports the following TLS features:
provided <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.crl>.RFC 5077 <https://www.ietf.org/rfc/rfc5077.txt>_). Resumption can be performed
across hot restarts and between parallel Envoy instances (typically useful in a front proxy
configuration).an extension <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.PrivateKeyProvider>. This allows extending Envoy to support various key
management schemes (such as TPM) and TLS acceleration. This mechanism uses
BoringSSL private key method interface <https://github.com/google/boringssl/blob/c0b4c72b6d4c6f4828a373ec454bd646390017d4/include/openssl/ssl.h#L1169>_.Currently Envoy is written to use BoringSSL <https://boringssl.googlesource.com/boringssl>_ as the
default TLS provider.
OpenSSL <https://openssl.org>_ can also be used as an alternative, when Envoy is built using
the --config=openssl Bazel option. OpenSSL libraries are not statically linked into the main Envoy executable;
they must be present at runtime and are loaded dynamically. HTTP/3 (QUIC) is not available with OpenSSL builds.
OpenSSL builds are not currently covered by the :repo:Envoy security policy <SECURITY.md>.
.. _arch_overview_ssl_fips:
BoringSSL can be built in a
FIPS-compliant mode <https://boringssl.googlesource.com/boringssl/+/main/crypto/fipsmodule/FIPS.md>,
following the build instructions from the Security Policy for BoringCrypto module <https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3678.pdf>,
using --config=boringssl-fips Bazel option. Currently, the BoringSSL/FIPS build will only work Linux-x86_64.
AWS-LC FIPS can also be used with --config=aws-lc-fips, and has wider architecture support.
When Envoy has been built for FIPS, you should see BoringSSL-FIPS or AWS-LC-FIPS
in the :option:--version output. When built with OpenSSL, the output will show OpenSSL.
It's important to note that while using FIPS-compliant module is necessary for FIPS compliance,
it's not sufficient by itself, and depending on the context, additional steps might be necessary.
The extra requirements may include using only approved algorithms and/or using only private keys
generated by a module operating in FIPS-approved mode. For more information, please refer to the
Security Policy for BoringCrypto module <https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3678.pdf>_
and/or an accredited CMVP laboratory <https://csrc.nist.gov/projects/testing-laboratories>_.
Please note that the FIPS-compliant build is based on an older version of BoringSSL than the non-FIPS build, and it doesn't support the most recent QUIC APIs.
.. _arch_overview_ssl_enabling_verification:
Certificate verification of both upstream and downstream connections is not enabled unless the validation context specifies one or more trusted authority certificates.
Example configuration ^^^^^^^^^^^^^^^^^^^^^
.. literalinclude:: _include/ssl.yaml :language: yaml
/etc/ssl/certs/ca-certificates.crt is the default path for the system CA bundle on Debian systems.
:ref:trusted_ca <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.trusted_ca> along with
:ref:match_typed_subject_alt_names <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.match_typed_subject_alt_names>
makes Envoy verify the server identity of 127.0.0.1:1234 as "foo" in the same way as e.g. cURL
does on standard Debian installations. Common paths for system CA bundles on Linux and BSD are:
See the reference for :ref:UpstreamTlsContexts <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.UpstreamTlsContext> and
:ref:DownstreamTlsContexts <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.DownstreamTlsContext> for other TLS options.
.. attention::
If only :ref:trusted_ca <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.trusted_ca> is
specified, Envoy will verify the certificate chain of the presented certificate, but not its
subject name, hash, etc. Other validation context configuration is typically required depending
on the deployment.
Custom Certificate Validator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The configuration explained above is used by the "default" certificate validator.
Envoy also supports custom validators in envoy.tls.cert_validator extension category which can be
configured on :ref:CertificateValidationContext <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.CertificateValidationContext>.
For example, Envoy can be configured to verify peer certificates following the SPIFFE <https://github.com/spiffe/spiffe>_ specification
with multiple trust bundles in a single listener or cluster.
For more detail, please refer to :ref:the documentation of custom_validator_config field<envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.custom_validator_config>.
.. _arch_overview_ssl_cert_select:
:ref:DownstreamTlsContexts <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.DownstreamTlsContext> support multiple TLS
certificates. These may be a mix of RSA and ECDSA certificates for multiple server name patterns.
Certificate config/loading rules:
DownstreamTlsContext <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.DownstreamTlsContext>.Certificate selection rules:
full_scan_certs_on_sni_mismatch <envoy_v3_api_field_extensions.transport_sockets.tls.v3.DownstreamTlsContext.full_scan_certs_on_sni_mismatch>,
go to full scan all certificates if it is enabled, otherwise pick the first certificate for handshake.full_scan_certs_on_sni_mismatch <envoy_v3_api_field_extensions.transport_sockets.tls.v3.DownstreamTlsContext.full_scan_certs_on_sni_mismatch>
is false or true... note::
With the support of SNI-based certificate selection, it allows configuring large number of certificates for multiple hostnames.
:ref:full_scan_certs_on_sni_mismatch <envoy_v3_api_field_extensions.transport_sockets.tls.v3.DownstreamTlsContext.full_scan_certs_on_sni_mismatch>
is introduced to determine if we continue full scan on SNI mismatch when the client provides SNI. SNI mismatch contains two cases in this context, one is there is no cert that matches to SNI,
another one is there are certs matches to SNI while OCSP policy fails on those certs. The :ref:full_scan_certs_on_sni_mismatch <envoy_v3_api_field_extensions.transport_sockets.tls.v3.DownstreamTlsContext.full_scan_certs_on_sni_mismatch>
defaults to false, so full scan is disabled by default. If full scan is enabled, it will look for the cert from the whole cert list on SNI mismatch,
this could be a problem for a potential DoS attack because of O(n) complexity.
Only a single TLS certificate is supported today for :ref:UpstreamTlsContexts <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.UpstreamTlsContext>.
TLS certificates can be specified in the static resource or can be fetched remotely.
Certificate rotation is supported for static resources by sourcing :ref:SDS configuration from the filesystem <xds_certificate_rotation> or by pushing updates from the SDS server.
Please see :ref:SDS <config_secret_discovery_service> for details.
.. _arch_overview_ssl_ocsp_stapling:
:ref:DownstreamTlsContexts <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.DownstreamTlsContext> support
stapling an Online Certificate Status Protocol (OCSP) response to a TLS certificate during the handshake. The
ocsp_staple field allows the operator to supply a pre-computed OCSP response per-certificate in the context.
A single response may not pertain to multiple certificates. If provided, OCSP responses must be valid and
affirm the certificate has not been revoked. Expired OCSP responses are accepted, but may cause downstream
connection errors depending on the OCSP staple policy.
:ref:DownstreamTlsContexts <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.DownstreamTlsContext>
support an ocsp_staple_policy field to control whether Envoy should stop using a certificate or
continue without stapling when its associated OCSP response is missing or expired.
Certificates marked as must-staple <https://tools.ietf.org/html/rfc7633>_ require a
valid OCSP response regardless of the OCSP staple policy. In practice, a must-staple certificate causes
cEnvoy to behave as if the OCSP staple policy is :ref:MUST_STAPLE<envoy_v3_api_enum_value_extensions.transport_sockets.tls.v3.DownstreamTlsContext.OcspStaplePolicy.MUST_STAPLE>.
Envoy will not use a must-staple certificate for new connections after its OCSP response expires.
OCSP responses are never stapled to TLS requests that do not indicate support for OCSP stapling
via the status_request extension.
OCSP responses are ignored for :ref:UpstreamTlsContexts <envoy_v3_api_msg_extensions.transport_sockets.tls.v3.UpstreamTlsContext>.
.. _arch_overview_ssl_auth_filter:
Envoy provides a network filter that performs TLS client authentication via principals fetched from a REST VPN service. This filter matches the presented client certificate hash against the principal list to determine whether the connection should be allowed or not. Optional IP allowlisting can also be configured. This functionality can be used to build edge proxy VPN support for web infrastructure.
Client TLS authentication filter :ref:configuration reference <config_network_filters_client_ssl_auth>.
.. _arch_overview_ssl_custom_handshaker:
The :ref:CommonTlsContext <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CommonTlsContext.custom_handshaker>
has a custom_handshaker extension which can be used to override SSL handshake
behavior entirely. This is useful for implementing any TLS behavior which is
difficult to express with callbacks. It is not necessary to write a custom
handshaker to use private key methods, see the
:ref:private key method interface <arch_overview_ssl> described above.
To avoid reimplementing all of the Ssl::ConnectionInfo <https://github.com/envoyproxy/envoy/blob/64bd6311bcc8f5b18ce44997ae22ff07ecccfe04/include/envoy/ssl/connection.h#L19>_ interface, a custom
implementation might choose to extend
Envoy::Extensions::TransportSockets::Tls::SslHandshakerImpl <https://github.com/envoyproxy/envoy/blob/64bd6311bcc8f5b18ce44997ae22ff07ecccfe04/source/extensions/transport_sockets/tls/ssl_handshaker.h#L40>_.
Custom handshakers need to explicitly declare via HandshakerCapabilities <https://github.com/envoyproxy/envoy/blob/64bd6311bcc8f5b18ce44997ae22ff07ecccfe04/include/envoy/ssl/handshaker.h#L68-L89>_
which TLS features they are responsible for. The default Envoy handshaker will
manage the remainder.
A useful example handshaker, named SslHandshakerImplForTest, lives in
this test <https://github.com/envoyproxy/envoy/blob/64bd6311bcc8f5b18ce44997ae22ff07ecccfe04/test/extensions/transport_sockets/tls/handshaker_test.cc#L174-L184>_
and demonstrates special-case SSL_ERROR handling and callbacks.
.. _arch_overview_ssl_trouble_shooting:
When Envoy originates TLS when making connections to upstream clusters, any errors will be logged into
:ref:UPSTREAM_TRANSPORT_FAILURE_REASON<config_access_log_format_upstream_transport_failure_reason> field or
:ref:AccessLogCommon.upstream_transport_failure_reason<envoy_v3_api_field_data.accesslog.v3.AccessLogCommon.upstream_transport_failure_reason> field.
When Envoy listener gets connection and perform TLS with downstream, any errors will be logged into
:ref:DOWNSTREAM_TRANSPORT_FAILURE_REASON<config_access_log_format_downstream_transport_failure_reason> field or
:ref:AccessLogCommon.downstream_transport_failure_reason<envoy_v3_api_field_data.accesslog.v3.AccessLogCommon.downstream_transport_failure_reason> field.
Common errors are:
Secret is not supplied by SDS: Envoy is still waiting SDS to deliver key/cert or root CA.SSLV3_ALERT_CERTIFICATE_EXPIRED: Peer certificate is expired and not allowed in config.SSLV3_ALERT_CERTIFICATE_UNKNOWN: Peer certificate is not in config specified SPKI.SSLV3_ALERT_HANDSHAKE_FAILURE: Handshake failed, usually due to upstream requires client certificate but not presented.TLSV1_ALERT_PROTOCOL_VERSION: TLS protocol version mismatch.TLSV1_ALERT_UNKNOWN_CA: Peer certificate CA is not in trusted CA.More detailed list of error that can be raised by BoringSSL can be found
here <https://github.com/google/boringssl/blob/main/crypto/err/ssl.errordata>_