Here you will find instructions for configuring incoming and outgoing TLS communications in Spring Cloud Gateway for Kubernetes.

Spring Cloud Gateway acts as a servier in the TLS communication.

TLS termination - Server TLS

You can encrypt traffic between an API Consumer and Spring Cloud Gateway using different certificates bound to multiple hosts. Spring Cloud Gateway will act as a server in the TLS communication.

For each certificate, provide:

  • hosts: one or more hostnames that will be bound to the certificate
  • secretName: TLS secret name that contains the certificate(s)/key pair you want to use for HTTPs between the consumer and SCG

Next:

  1. Verify that the client with which you make requests to your gateway supports Server Name Indication, in order to pass the requested host to the gateway as part of the TLS handshake.
  2. Create a TLS-type secret for each certificate you would like the Gateway to serve. The easiest way to do this is with kubectl and PEM encoded certificate and key files:
kubectl create secret tls tls-secret-1 --cert=path/to/tls.crt --key=path/to/tls.key
  • The tls.crt file can contain multiple CA certificates concatenated together with the server certificate to represent a complete chain of trust.
  • The tls.key file should contain the private key for the server certificate in PKCS#8 or PKCS#1 format.

For more information, see Kubernetes TLS secrets.

  1. Create a Gateway resource with the spec.server.tls describing each secretName of the certificates to use and the hosts list bound to the certificate.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: test-gateway-tls
spec:
  server:
    tls:
      - hosts:
          - host-a.my-tls-gateway.my-example-domain.com
          - host-b.my-tls-gateway.my-example-domain.com
        secretName: tls-secret-1
      - hosts:
          - host-c.my-tls-gateway.my-example-domain.com
          - host-d.my-tls-gateway.my-example-domain.com
        secretName: tls-secret-2

For the above Gateway resource

  • Any incoming HTTPS request whose Host is host-a.my-tls-gateway.my-example-domain.com or host-b.my-tls-gateway.my-example-domain.com will use the certificate tls-secret-1
  • Any incoming HTTPS request whose Host is host-c.my-tls-gateway.my-example-domain.com or host-d.my-tls-gateway.my-example-domain.com will use the certificate tls-secret-2

Note As the definition for SpringCloudGateway specifies, the spec.tls property has been deprecated and will be removed soon. Please, only if you are running version 2.0.2 or greater, we recommend changing existing configurations to the new format using spec.server.tls. For previous versions, keep spec.tls property.

  1. To verify that everything is working as expected, you can use openssl to check the certificates that are returned for each of the configured hosts. For example:
openssl s_client -showcerts -servername host-a.my-tls-gateway.my-example-domain.com -connect <your ingress ip>:443 | openssl x509 -text

where <your ingress ip> should be replaced with the external IP of your TLS passthrough activated ingress.

Note Server TLS supports hot reload of the associated secret, so if this secret is changed, the Gateway will read the new contents of the secret automatically without the need for a restart.
Please note that Kubernetes can take between 15 and 45 seconds to detect the change of a secret, so this delay may affect incoming requests at the time of the change is produced.

TLS for upstream services - Client TLS

Connection between the Gateway and upstream services can be protected using TLS, in that scenario Spring Cloud Gateway will act as a Client in the TLS communication. If the upstream service's certificate is valid for a public CA, you don't need to anything. Otherwise, for self-signed certificates or private CA, configure Spring Cloud Gateway for recognising those connections as trusted following the next steps:

  1. Create the secret with the public certificate to connect to upstream services through HTTPS.

Get the public key from an administrator or extract it from your key pair.

openssl rsa -in my-key-pair.pem -pubout > tls.crt

The Kubernetes CLI does not allow creating a tls secret with only a certificate. You need to create a resource and apply it. You can do it in a single step as described in the following code for a TLS certificate located at path/to/tls.crt.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: secret-client-1
type: tls
data:
  tls.crt: $(cat path/to/tls.crt | base64 | tr -d '\n')
EOF

The tls.crt file can contain multiple CA certificates concatenated together to represent a complete chain of trust, and it must have the FQDN in a x.509 extension or as CN. To check it out openssl x509 -in path/to/tls.crt -text -noout allows to see the information:

  • FQDN in a x.509 extension: under X509v3 extensions property you should see the X509v3 Subject Alternative Name so Issuer is not used.
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 16347908130272346071 (0xe2df6fd45d9a7fd7)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=tls-client.demo
        Validity
            Not Before: Jul 13 11:12:45 2022 GMT
            Not After : Jul 10 11:12:45 2032 GMT
        Subject: CN=tls-server.demo
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:be:cd:a9:c4:73:80:68:67:46:68:f5:1e:8d:de:
                    ...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                57:17:8D:DB:1C:85:C1:90:F3:CB:FD:F7:BD:A5:CC:38:31:45:58:1F
            X509v3 Subject Alternative Name:
                DNS:test-tls-client, DNS:test-tls-client.namespace
  • FQDN as CN: under X509v3 extensions property you should not see any X509v3 Subject Alternative Name so Issuer is used using CN data
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 18235127832164825612 (0xfd1030264605fa0c)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=test-tls-server-service.tls-test-namespace
        Validity
            Not Before: Jul 13 11:14:28 2022 GMT
            Not After : Jul 10 11:14:28 2032 GMT
        Subject: CN=test-tls-server-service.tls-test-namespace
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:ac:72:1c:f2:a4:1b:cb:47:41:73:92:67:b5:ce:
                    ...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                B0:03:25:9A:EC:C9:8F:8A:3F:9E:57:CB:AE:A5:2A:1E:7B:FF:B9:BA
  1. Create a Gateway resource with the spec.client.tls.secretNames containing all the certificates to use. The gateway will serve the certificate for the upstream request from the matching secrets.
apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGateway
metadata:
  name: test-gateway-tls
spec:
  client:
    tls:
      secretNames:
        - secret-client-1
        - secret-client-2

In the above example, the Gateway will use the appropriate certificate based on the CN or FQDN of the request.

TLS for single sign-on (SSO) with self-signed certificates

The certificates set via spec.client.tls.secretNames are not applied when communicating to a Single Sign-On provider with a self-signed certificate. See the TLS Configuration for configuring single sign-on with self-signed certificates.

Note Client TLS supports hot reload of the associated secret, so if this secret is changed, the Gateway will read the new contents of the secret automatically without the need for a restart.
Please note that Kubernetes can take between 15 and 45 seconds to detect the change of a secret, so this delay may affect incoming requests at the time of the change is produced.

check-circle-line exclamation-circle-line close-line
Scroll to top icon