Skip to content

TLS details

Gateway API allow for a variety of ways to configure TLS. This document lays out various TLS settings and gives general guidelines on how to use them effectively.

Client/Server and TLS

overview

For Gateways, there are two connections involved:

  • downstream: This is the connection between the client and the Gateway.
  • upstream: This is the connection between the Gateway and backend resources specified by routes. These backend resources will usually be Services.

With Gateway API, TLS configuration of downstream and upstream connections is managed independently.

Depending on the Listener Protocol, different TLS modes and Route types are supported.

Listener Protocol TLS Mode Route Type Supported
TLS Passthrough TLSRoute
TLS Terminate TCPRoute
HTTPS Terminate HTTPRoute

Please note that in case of Passthrough TLS mode, no TLS settings take effect as the TLS session from the client is NOT terminated at the Gateway. The rest of the document assumes that TLS is being terminated at the Gateway, which is the default setting.

Downstream TLS

Downstream TLS settings are configured using listeners at the Gateway level.

Listeners and TLS

Listeners expose the TLS setting on a per domain or sub-domain basis. TLS settings of a listener are applied to all domains that satisfy the hostname criteria.

In the following example, the Gateway serves the TLS certificate defined in the default-cert Secret resource for all requests. Although, the example refers to HTTPS protocol, one can also use the same feature for TLS-only protocol along with TLSRoutes.

listeners:
- protocol: HTTPS # Other possible value is `TLS`
  port: 443
  tls:
    mode: Terminate # If protocol is `TLS`, `Passthrough` is a possible mode
    certificateRef:
      kind: Secret
      group: core
      name: default-cert
    routeOverride:
      certificate: Deny

If hostname.match is set to Exact, then the TLS settings apply to only the specific hostname that is set in hostname.name.

Specifying tls.routeOverride.certificate: Deny is recommended because it centralizes TLS configuration within the Gateway specification and should suffice for the majority of use-cases. Please take a look at the examples below for various alternatives.

Routes and TLS

If listeners[].tls.routeOverride.certificate is set to Allow, TLS certificates can be configured on routes that are bound to the Gateway. This feature is primarily meant for a cluster with a self-service model where Application developers bring their own TLS certificates. This feature also mirrors the behavior of TLS as defined in the Ingress v1 resource. One should use this feature only when the Cluster Operator wishes to delegate TLS configuration to the Application Developer. With this feature, the certificate defined in the route overrides any certificate defined in the Gateway.

When using this feature, please note that the TLS certificate to serve is chosen before an HTTPRoute is selected. This is because the TLS handshake is completed before an HTTP request is sent from the client.

TLS Certificate in Route provides an example of how this feature can be used.

Also, as mentioned above, the Route Kind (HTTPRoute, TLSRoute, TCPRoute) is dependent on the protocol on the listener level. Listeners with HTTPS or HTTP protocols can use HTTPRoute as the TLS Termination is done at the listener level and thus, only HTTP information is used for routing.

Listeners with the TLS protocol must use TLSRoute when the mode is set to Passthrough and TCPRoute when the mode is Terminate.

Listeners with the TCP protocol must use TCPRoute for plain TCP Routing.

Examples

TLS in listener

In this example, the Gateway is configured to serve the foo.example.com and bar.example.com domains. The certificate for these domains is specified in the Gateway.

apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata:
  name: tls-basic
spec:
  gatewayClassName: acme-lb
  listeners:
  - protocol: HTTPS
    port: 443
    hostname: foo.example.com
    tls:
      certificateRef:
        kind: Secret
        group: core
        name: foo-example-com-cert
      routeOverride:
        certificate: Deny
    routes:
      kind: HTTPRoute
  - protocol: HTTPS
    port: 443
    hostname: bar.example.com
    tls:
      certificateRef:
        kind: Secret
        group: core
        name: bar-example-com-cert
      routeOverride:
        certificate: Deny
    routes:
      kind: HTTPRoute

Wildcard TLS listeners

In this example, the Gateway is configured with a wildcard certificate for *.example.com and a different certificate for foo.example.com. Since a specific match takes priority, the Gateway will serve foo-example-com-cert for requests to foo.example.com and wildcard-example-com-cert for all other requests.

apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata:
  name: wildcard-tls-gateway
spec:
  gatewayClassName: acme-lb
  listeners:
  - protocol: HTTPS
    port: 443
    hostname: foo.example.com
    tls:
      certificateRef:
        kind: Secret
        group: core
        name: foo-example-com-cert
      routeOverride:
        certificate: Deny
    routes:
      kind: HTTPRoute
  - protocol: HTTPS
    port: 443
    hostname: "*.example.com"
    tls:
      certificateRef:
        kind: Secret
        group: core
        name: wildcard-example-com-cert
      routeOverride:
        certificate: Deny
    routes:
      kind: HTTPRoute

TLS Certificate in Route

In this example, the Gateway is configured with a default certificate that will be served for all hostnames. In addition, tls.routeOverride.certificate is set to Allow, meaning routes can specify TLS certificates for any domains. Next, there are two HTTPRoute resources which specify certificates for foo.example.com and bar.example.com.

apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata:
  name: cert-in-route-gateway
spec:
  gatewayClassName: acme-lb
  listeners:
  - protocol: HTTP
    port: 80
    routes:
      kind: HTTPRoute
  - protocol: HTTPS
    port: 443
    tls:
      mode: Terminate
      certificateRef:
        kind: Secret
        group: core
        name: default-cert
      routeOverride:
        certificate: Allow
    routes:
      kind: HTTPRoute
---
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: http-app-1
spec:
  hostnames:
  - "foo.example.com"
  tls:
    certificateRef:
      kind: Secret
      group: core
      name: foo-example-com-cert
  rules:
  - matches:
    - path:
        type: Prefix
        value: /
    forwardTo:
    - serviceName: my-service
      port: 8080
---
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: http-app-2
spec:
  hostnames:
  - "bar.example.com"
  tls:
    certificateRef:
      kind: Secret
      group: core
      name: bar-example-com-cert
  rules:
  - matches:
    - path:
        type: Prefix
        value: /
    forwardTo:
    - serviceName: my-service
      port: 8080

Upstream TLS

Upstream TLS configuration applies to the connection between the Gateway and Service.

There is only one way to configure upstream TLS: using the BackendPolicy resource.

Please note that the TLS configuration is related to the Service or backend resource and not related to a specific route resource.

Example

The following example shows how upstream TLS can be configured. We have omitted downstream TLS configuration for simplicity. As noted before, it doesn't matter how downstream TLS is configured for the specific listener or route.

apiVersion: networking.x-k8s.io/v1alpha1
kind: BackendPolicy
metadata:
  name: my-app
  annotations:
    networking.x-k8s.io/app-protocol: https
spec:
  backendRefs:
  - name: my-service
    group: core
    kind: Service
    port: 443
  tls:
    certificateAuthorityRef:
      name: my-cluster-ca
      group: core
      kind: Secret
    options: {}
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
  - name: http
    port: 80
  - name: https
    port: 443
  selector:
    app: my-service
---
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
  name: my-service-route
spec:
  hostnames:
  - "foo.com"
  rules:
  - matches:
    - path:
        type: Prefix
        value: /
    forwardTo:
    - serviceName: my-service
      port: 443

Extensions

Both upstream and downstream TLS configs provide an options map to add additional TLS settings for implementation-specific features. Some examples of features that could go in here would be TLS version restrictions, or ciphers to use.

Back to top