Here you will find instructions for configuring incoming and outgoing TLS communications in Spring Cloud Gateway for Kubernetes.
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 certificatesecretName
: TLS secret name that contains the certificate(s)/key pair you want to use for HTTPs between the consumer and SCGNext:
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
tls.crt
file can contain multiple CA certificates concatenated together with the server certificate to represent a complete chain of trust.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.
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
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
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.
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.
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:
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:
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
X509v3 extensions
property you should not see any X509v3 Subject Alternative Name
so Issuer
is used using CN
dataCertificate:
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
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.
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.