Using TLS
Configuration
TLS keys and certificates are taken from Kubernetes Secret resources according
to the tls
attribute of each Ingress resource. See the
Ingress documentation
for details on how to configure TLS.
TLS Server Name Indication support is required for TLS to work; clients without SNI support will receive a TLS negotiation error. There is no default certificate for non-SNI-capable clients.
If you don't want to use Kubernetes for TLS, set tls: false
in
kubernetes.config
or set the $TS_TLS
environment variable to "false"
.
You will need to provide TLS configuration some other way, like
ssl_multicert.config
or the ssl-cert-loader
plugin, or else terminate TLS
before traffic reaches Traffic Server.
Redirecting HTTP to HTTPS
By default, insecure HTTP requests to an Ingress which has TLS configured will
be redirected to HTTPS with an HTTP 301 response. To disable this behaviour,
set the ingress.kubernetes.io/ssl-redirect
annotation to false
.
This redirect only happens when a valid TLS certificate could be loaded for the Ingress, so if you're using kube-lego and it hasn't issued a certificate yet, the redirect won't be done; this allows kube-lego to do the initial domain validation correctly.
To force a redirect to HTTPS even when TLS is not configured on the Ingress, set
the ingress.kubernetes.io/force-ssl-redirect
annotation to "true"
. This
will not work unless you are offloading TLS termination in front of Traffic
Server.
Connecting to pods via HTTPS
Usually, communication between Traffic Server and backends (e.g. pods) is via
insecure HTTP, even if the request was made over HTTPS. To use HTTPS for
communicate with the backend, set the ingress.kubernetes.io/secure-backends
annotation to "true"
. This is not very useful when the backend is a pod,
because TS connects to the pod by its IP address, and it's extremely unlikely
the pod will have a TLS certificate for that IP address. However, this can be
useful when using external proxying.
A better method to secure traffic between Traffic Server and pods is to use a network CNI plugin that supports encryption, such as Weave Net.
HSTS
To enable HTTP Strict Transport Security (HSTS), set the
ingress.kubernetes.io/hsts-max-age
annotation on the Ingress to the HSTS
max-age time in seconds. To be useful, this should be set to at least six
months (15768000 seconds), but you should start with a lower value and gradually
increase it. Do not set it to a large value without testing it first, because,
by design, it cannot be turned off for browsers that already saw the HSTS
header until the max-age expires.
HSTS headers are per-hostname, not per-path. Therefore, hsts-max-age
can only
be set on the Ingress that includes the root path for a particular hostname
(i.e., where the Ingress rule has no path
attribute).
To apply HSTS to subdomains as well, set the
ingress.kubernetes.io/hsts-include-subdomains
annotation.
Configuring the TLS cypher list
You cannot configure the cypher list on the Ingress level; this was judged to be too risky, as users are likely to set a cypher list and not keep it up to date with changes in best practice. (If you require this feature, please open a Github issue.)
To configure the global cypher list, set proxy.config.ssl.server.cipher_suite
in the TS records.config
file to an OpenSSL cypher string, or set the
$PROXY_CONFIG_SSL_SERVER_CIPHER_SUITE
environment variable:
PROXY_CONFIG_SSL_SERVER_CIPHER_SUITE=ECDH+AES:DH+AES:RSA+AES:!aNULL:!MD5:!DSS
Configuring the minimum TLS version
To set the minimum TLS version on an Ingress, set the
ingress.kubernetes.io/tls-minimum-version
annotation:
metadata:
annotations:
ingress.kubernetes.io/tls-minimum-version: "1.1"
Accepted values are "1.0"
, "1.1"
and "1.2"
. TLS 1.3 is not supported.
Due to limitations in OpenSSL and Traffic Server, this will not work correctly
if you have configured TLS certificates in ssl_multicert.config
.
To configure the global minimum TLS version, set one or more of the following environment variables:
PROXY_CONFIG_SSL_TLSV1=0
: disable TLS 1.0PROXY_CONFIG_SSL_TLSV1_1=0
: disable TLS 1.1PROXY_CONFIG_SSL_TLSV1_2=0
: disable TLS 1.2
Configuring detault TLS certificates
Default certificates can be configured by setting tls-certificates
ConfigMap configuration. This can be used
to provide TLS without giving users access to the TLS certificate and key, or to
use a wildcard certificate for all Ingresses in a particular domain without
having to configure a copy of the certificate in every namespace.
tls-certificates
should be a whitespace-separated list of
[<domain>[,<domain>...]]:<namespace>/<cert>
, which maps the given TLS
certificate to that domain. This certificate will be used for every host
configured in that Ingress, even if it does not have TLS configured. If TLS is
configured explicitly for a particular host in the Ingress, the Ingress
configuration will be used instead of the default certificate.
For example, to use the certificate staging-cert
in the namespace
trafficserver
for all Ingresses in myapp-staging.com
:
tls-certificates: *myapp-staging.com:trafficserver/staging-cert
*.domain.com
will match sub.domain.com
, but not domain.com
or
sub.sub.domain.com
.
*domain.com
will match both domain.com
and sub.domain.com
, but not
otherdomain.com
or sub.sub.domain.com
.
Using kube-lego
kube-lego is a Kubernetes controller that automatically provisions TLS certificates using an ACME provider such as Let's Encrypt. It is ideal for test or staging environments (or even production environments when domain-validated TLS certificates are sufficient), but it currently doesn't support any Ingress controllers other than nginx and GCE.
To use the TS Ingress controller with kube-lego, you should configure kube-lego
as if you were using the nginx Ingress controller, then tell TS to handle the
"nginx"
Ingress class, either by setting the environment variable
$TS_INGRESS_CLASSES
to trafficserver nginx
, or in kubernetes.config
:
ingress_classes: trafficserver nginx