11 min • read

Transport Layer Security (TLS)

Emissary-ingress's robust TLS support exposes configuration options for many different TLS use cases, using the Host and TLSContext resources in concert.

Certificates and Secrets

Properly-functioning TLS requires the use of TLS certificates to prove that the various systems communicating are who they say they are. At minimum, Emissary-ingress must have a server certificate that identifies it to clients; when mTLS or client certificate authentication are in use, additional certificates are needed.

You supply certificates to Emissary-ingress in Kubernetes TLS Secrets. These Secrets must contain valid X.509 certificates with valid PKCS1, PKCS8, or Elliptic Curve private keys. If a Secret does not contain a valid certificate, an error message will be logged, for example:

If you set the AMBASSADOR_FORCE_SECRET_VALIDATION environment variable, the invalid Secret will be rejected, and a Host or TLSContext resource attempting to use an invalid certificate will be disabled entirely. Note that in Emissary-ingress 3.3.0, this includes disabling cleartext communication for such a Host.

Host

A Host represents a domain in Emissary-ingress and defines how the domain manages TLS. For more information on the Host resource, see The Host CRD reference documentation.

If no Hosts are present, Emissary-ingress synthesizes a Host that allows only cleartext routing. You will need to explictly define Hosts to enable TLS termination.

Bring your own certificate

The Host can read a certificate from a Kubernetes Secret and use that certificate to terminate TLS on a domain.

The following example shows the certificate contained in the Kubernetes Secret named host-secret configured to have Emissary-ingress terminate TLS on the host.example.com domain:

By default, tlsSecret will only look for the named secret in the same namespace as the Host. In the above example, the secret host-secret will need to exist within the default namespace since that is the namespace of the Host.

To reference a secret that is in a different namespace from the Host, the namespace field is required. The below example will configure the Host to use the host-secret secret from the example namespace.

Advanced TLS configuration with the Host

You can specify TLS configuration directly in the Host via the tls field. This is the recommended method to do more advanced TLS configuration for a single Host.

For example, the configuration to enforce a minimum TLS version on the Host looks as follows:

The following fields are accepted in the tls field:

These fields have the same function as in the TLSContext resource, as described below.

Host and TLSContext

You can link a Host to a TLSContext instead of defining tls settings in the Host itself. This is primarily useful for sharing settings between multiple Hosts.

To link a TLSContext with a Host, create a TLSContext with the desired configuration and link it to the Host by setting the tlsContext.name field in the Host. For example, to enforce a minimum TLS version on the Host above, create a TLSContext with any name with the following configuration:

Next, link it to the Host via the tlsContext field as shown:

See TLSContext below to read more on the description of these fields.

Create a TLSContext with the name {{AMBASSADORHOST}}-context (DEPRECATED)

The Host will implicitly link to the TLSContext when a TLSContext exists with the following:

  • the name {{NAME_OF_AMBASSADORHOST}}-context
  • hosts in the TLSContext set to the same value as hostname in the Host, and
  • secret in the TLSContext set to the same value as tlsSecret in the Host

As noted above, this implicit linking is deprecated.

For example, another way to enforce a minimum TLS version on the Host above would be to simply create the TLSContext with the name example-host-context and then not modify the Host:

Full reference for all options available to the TLSContext can be found below.

TLSContext

The TLSContext is used to configure advanced TLS options in Emissary-ingress. Remember, a TLSContext must always be paired with a Host.

A full schema of the TLSContext can be found below with descriptions of the different configuration options.

ALPN protocols

The alpn_protocols setting configures the TLS ALPN protocol. To use gRPC over TLS, set alpn_protocols: h2. If you need to support HTTP/2 upgrade from HTTP/1, set alpn_protocols: h2,http/1.1 in the configuration.

HTTP/2 support

The alpn_protocols setting is also required for HTTP/2 support.

Without setting alpn_protocols as shown above, HTTP2 will not be available via negotiation and will have to be explicitly requested by the client.

If you leave off http/1.1, only HTTP2 connections will be supported.

TLS parameters

The min_tls_version setting configures the minimum TLS protocol version that Emissary-ingress will use to establish a secure connection. When a client using a lower version attempts to connect to the server, the handshake will result in the following error: tls: protocol version not supported.

The max_tls_version setting configures the maximum TLS protocol version that Emissary-ingress will use to establish a secure connection. When a client using a higher version attempts to connect to the server, the handshake will result in the following error: tls: server selected unsupported protocol version.

The cipher_suites setting configures the supported ciphers found below using the configuration parameters for BoringSSL when negotiating a TLS 1.0-1.2 connection. This setting has no effect when negotiating a TLS 1.3 connection. When a client does not support a matching cipher a handshake error will result.

The ecdh_curves setting configures the supported ECDH curves when negotiating a TLS connection. When a client does not support a matching ECDH a handshake error will result.

The crl_secret field allows you to reference a Kubernetes Secret that contains a certificate revocation list. If specified, Emissary-ingress will verify that the presented peer certificate has not been revoked by this CRL even if they are otherwise valid. This provides a way to reject certificates before they expire or if they become compromised. The crl_secret field takes a PEM-formatted Certificate Revocation List in a crl.pem entry.

Note that if a CRL is provided for any certificate authority in a trust chain, a CRL must be provided for all certificate authorities in that chain. Failure to do so will result in verification failure for both revoked and unrevoked certificates from that chain.