.. _arch_overview_ssl: TLS === Envoy supports both :ref:`TLS termination ` in listeners as well as :ref:`TLS origination ` 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: * **Configurable ciphers**: Each TLS listener and client can specify the ciphers that it supports. * **Client certificates**: Upstream/client connections can present a client certificate in addition to server certificate verification. * **Certificate verification and pinning**: Certificate verification options include basic chain verification, subject name verification, and hash pinning. * **Certificate revocation**: Envoy can check peer certificates against a certificate revocation list (CRL) if one is :ref:`provided `. * **ALPN**: TLS listeners support ALPN. The HTTP connection manager uses this information (in addition to protocol inference) to determine whether a client is speaking HTTP/1.1 or HTTP/2. * **SNI**: SNI is supported for both server (listener) and client (upstream) connections. * **Session resumption**: Server connections support resuming previous sessions via TLS session tickets (see `RFC 5077 `_). Resumption can be performed across hot restarts and between parallel Envoy instances (typically useful in a front proxy configuration). * **BoringSSL private key methods**: TLS private key operations (signing and decrypting) can be performed asynchronously from :ref:`an extension `. This allows extending Envoy to support various key management schemes (such as TPM) and TLS acceleration. This mechanism uses `BoringSSL private key method interface `_. * **OCSP Stapling**: Online Certificate Stapling Protocol responses may be stapled to certificates. Underlying implementation ------------------------- Currently Envoy is written to use `BoringSSL `_ as the TLS provider. .. _arch_overview_ssl_fips: FIPS 140-2 ---------- BoringSSL can be built in a `FIPS-compliant mode `_, following the build instructions from the `Security Policy for BoringCrypto module `_, using ``--define boringssl=fips`` Bazel option. Currently, this option is only available on Linux-x86_64. The correctness of the FIPS build can be verified by checking the presence of ``BoringSSL-FIPS`` in the :option:`--version` output. 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 `_ and/or an `accredited CMVP laboratory `_. 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: Enabling certificate 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 ` along with :ref:`match_subject_alt_names ` makes Envoy verify the server identity of *127.0.0.2: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: * /etc/ssl/certs/ca-certificates.crt (Debian/Ubuntu/Gentoo etc.) * /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem (CentOS/RHEL 7) * /etc/pki/tls/certs/ca-bundle.crt (Fedora/RHEL 6) * /etc/ssl/ca-bundle.pem (OpenSUSE) * /usr/local/etc/ssl/cert.pem (FreeBSD) * /etc/ssl/cert.pem (OpenBSD) See the reference for :ref:`UpstreamTlsContexts ` and :ref:`DownstreamTlsContexts ` for other TLS options. .. attention:: If only :ref:`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. .. _arch_overview_ssl_cert_select: Certificate selection --------------------- :ref:`DownstreamTlsContexts ` support multiple TLS certificates. These may be a mix of RSA and P-256 ECDSA certificates. The following rules apply: * Only one certificate of a particular type (RSA or ECDSA) may be specified. * Non-P-256 server ECDSA certificates are rejected. * If the client supports P-256 ECDSA, a P-256 ECDSA certificate will be selected if one is present in the :ref:`DownstreamTlsContext ` and it is in compliance with the OCSP policy. * If the client only supports RSA certificates, a RSA certificate will be selected if present in the :ref:`DownstreamTlsContext `. * Otherwise, the first certificate listed is used. This will result in a failed handshake if the client only supports RSA certificates and the server only has ECDSA certificates. * Static and SDS certificates may not be mixed in a given :ref:`DownstreamTlsContext `. * The selected certificate must adhere to the OCSP policy. If no such certificate is found, the connection is refused. Only a single TLS certificate is supported today for :ref:`UpstreamTlsContexts `. Secret discovery service (SDS) ------------------------------ 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 ` or by pushing updates from the SDS server. Please see :ref:`SDS ` for details. .. _arch_overview_ssl_ocsp_stapling: OCSP Stapling ------------- :ref:`DownstreamTlsContexts ` 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 ` 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 `_ 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 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. The following runtime flags are provided to adjust the requirements of OCSP responses and override the OCSP policy. These flags default to ``true``. * ``envoy.reloadable_features.require_ocsp_response_for_must_staple_certs``: Disabling this allows the operator to omit an OCSP response for must-staple certs in the config. * ``envoy.reloadable_features.check_ocsp_policy``: Disabling this will disable OCSP policy checking. OCSP responses are stapled when available if the client supports it, even if the response is expired. Stapling is skipped if no response is present. OCSP responses are ignored for :ref:`UpstreamTlsContexts `. .. _arch_overview_ssl_auth_filter: Authentication 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 `. .. _arch_overview_ssl_custom_handshaker: Custom handshaker extension --------------------------- The :ref:`CommonTlsContext ` 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 ` described above. To avoid reimplementing all of the `Ssl::ConnectionInfo `_ interface, a custom implementation might choose to extend `Envoy::Extensions::TransportSockets::Tls::SslHandshakerImpl `_. Custom handshakers need to explicitly declare via `HandshakerCapabilities `_ 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 `_ and demonstrates special-case ``SSL_ERROR`` handling and callbacks. .. _arch_overview_ssl_trouble_shooting: Trouble shooting ---------------- When Envoy originates TLS when making connections to upstream clusters, any errors will be logged into :ref:`UPSTREAM_TRANSPORT_FAILURE_REASON` field or :ref:`AccessLogCommon.upstream_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 `_