apiVersion: maistra.io/v1
kind: ServiceMeshControlPlane
spec:
istio:
global:
mtls:
enabled: true
If your service mesh application is constructed with a complex array of microservices, you can use Red Hat OpenShift Service Mesh to customize the security of the communication between those services. The infrastructure of OpenShift Container Platform along with the traffic management features of Service Mesh can help you manage the complexity of your applications and provide service and identity security for microservices.
Mutual Transport Layer Security (mTLS) is a protocol where two parties authenticate each other. It is the default mode of authentication in some protocols (IKE, SSH) and optional in others (TLS).
mTLS can be used without changes to the application or service code. The TLS is handled entirely by the service mesh infrastructure and between the two sidecar proxies.
By default, Red Hat OpenShift Service Mesh is set to permissive mode, where the sidecars in Service Mesh accept both plain-text traffic and connections that are encrypted using mTLS. If a service in your mesh is communicating with a service outside the mesh, strict mTLS could break communication between those services. Use permissive mode while you migrate your workloads to Service Mesh.
If your workloads do not communicate with services outside your mesh and communication will not be interrupted by only accepting encrypted connections, you can enable mTLS across your mesh quickly. Set spec.istio.global.mtls.enabled
to true
in your ServiceMeshControlPlane
resource. The operator creates the required resources.
apiVersion: maistra.io/v1
kind: ServiceMeshControlPlane
spec:
istio:
global:
mtls:
enabled: true
Create a destination rule to configure Service Mesh to use mTLS when sending requests to other services in the mesh.
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "default"
namespace: <CONTROL_PLANE_NAMESPACE>>
spec:
host: "*.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
If your environment has specific requirements for encrypted traffic in your service mesh, you can control the cryptographic functions that are allowed by setting the spec.security.controlPlane.tls.minProtocolVersion
or spec.security.controlPlane.tls.maxProtocolVersion
in your ServiceMeshControlPlane
resource. Those values, configured in your control plane resource, define the minimum and maximum TLS version used by mesh components when communicating securely over TLS.
apiVersion: maistra.io/v2
kind: ServiceMeshControlPlane
metadata:
name: basic-install
namespace: istio-system
spec:
security:
controlPlane:
tls:
minProtocolVersion: TLSv1_2
maxProtocolVersion: TLSv1_3
The default is TLS_AUTO
and does not specify a version of TLS.
Value | Description |
---|---|
|
default |
|
TLS version 1.0 |
|
TLS version 1.1 |
|
TLS version 1.2 |
|
TLS version 1.3 |
Cipher suites and Elliptic-curve Diffie–Hellman (ECDH curves) can help you secure your service mesh. You can define a comma separated list of cipher suites using spec.istio.global.tls.cipherSuites
and ECDH curves using spec.istio.global.tls.ecdhCurves
in your ServiceMeshControlPlane
resource. If either of these attributes are empty, then the default values are used.
The cipherSuites
setting is effective if your service mesh uses TLS 1.2 or earlier. It has no effect when negotiating with TLS 1.3.
Set your cipher suites in the comma separated list in order of priority. For example, ecdhCurves: CurveP256, CurveP384
sets CurveP256
as a higher priority than CurveP384
.
You must include either |
The supported cipher suites are:
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
The supported ECDH Curves are:
CurveP256
CurveP384
CurveP521
X25519
By default, Red Hat OpenShift Service Mesh generates a self-signed root certificate and key and uses them to sign the workload certificates. You can also use the user-defined certificate and key to sign workload certificates with user-defined root certificate. This task demonstrates an example to plug certificates and key into Service Mesh.
Install Red Hat OpenShift Service Mesh with mutual TLS enabled to configure certificates.
This example uses the certificates from the Maistra repository. For production, use your own certificates from your certificate authority.
Deploy the Bookinfo sample application to verify the results with these instructions.
OpenSSL is required to verify certificates.
To use an existing signing (CA) certificate and key, you must create a chain of trust file that includes the CA certificate, key, and root certificate. You must use the following exact file names for each of the corresponding certificates. The CA certificate is named ca-cert.pem
, the key is ca-key.pem
, and the root certificate, which signs ca-cert.pem
, is named root-cert.pem
. If your workload uses intermediate certificates, you must specify them in a cert-chain.pem
file.
Save the example certificates from the Maistra repository locally and replace <path>
with the path to your certificates.
Create a secret named cacert
that includes the input files ca-cert.pem
, ca-key.pem
, root-cert.pem
and cert-chain.pem
.
$ oc create secret generic cacerts -n istio-system --from-file=<path>/ca-cert.pem \
--from-file=<path>/ca-key.pem --from-file=<path>/root-cert.pem \
--from-file=<path>/cert-chain.pem
In the ServiceMeshControlPlane
resource set spec.security.dataPlane.mtls true
to true
and configure the certificateAuthority
field as shown in the following example. The default rootCADir
is /etc/cacerts
. You do not need to set the privateKey
if the key and certs are mounted in the default location. Service Mesh reads the certificates and key from the secret-mount files.
apiVersion: maistra.io/v2
kind: ServiceMeshControlPlane
spec:
security:
dataPlane:
mtls: true
certificateAuthority:
type: Istiod
istiod:
type: PrivateKey
privateKey:
rootCADir: /etc/cacerts
After creating/changing/deleting the cacert
secret, the control plane istiod
and gateway
pods must be restarted so the changes go into effect. Use the following command to restart the pods:
$ $ oc -n istio-system delete pods -l 'app in (istiod,istio-ingressgateway, istio-egressgateway)'
The Operator will automatically recreate the pods after they have been deleted.
Restart the bookinfo application pods so that the sidecar proxies pick up the secret changes. Use the following command to restart the pods:
$ oc -n bookinfo delete pods --all
You should see output similar to the following:
pod "details-v1-6cd699df8c-j54nh" deleted
pod "productpage-v1-5ddcb4b84f-mtmf2" deleted
pod "ratings-v1-bdbcc68bc-kmng4" deleted
pod "reviews-v1-754ddd7b6f-lqhsv" deleted
pod "reviews-v2-675679877f-q67r2" deleted
pod "reviews-v3-79d7549c7-c2gjs" deleted
Verify that the pods were created and are ready with the following command:
$ oc get pods -n bookinfo
Use the Bookinfo sample application to verify that the workload certificates are signed by the certificates that were plugged into the CA. This requires you have openssl
installed on your machine
To extract certificates from bookinfo workloads use the following command:
$ sleep 60
$ oc -n bookinfo exec "$(oc -n bookinfo get pod -l app=productpage -o jsonpath={.items..metadata.name})" -c istio-proxy -- openssl s_client -showcerts -connect details:9080 > bookinfo-proxy-cert.txt
$ sed -n '/-----BEGIN CERTIFICATE-----/{:start /-----END CERTIFICATE-----/!{N;b start};/.*/p}' bookinfo-proxy-cert.txt > certs.pem
$ awk 'BEGIN {counter=0;} /BEGIN CERT/{counter++} { print > "proxy-cert-" counter ".pem"}' < certs.pem
After running the command, you should have three files in your working directory: proxy-cert-1.pem
, proxy-cert-2.pem
and proxy-cert-3.pem
.
Verify that the root certificate is the same as the one specified by the administrator. Replace <path>
with the path to your certificates.
$ openssl x509 -in <path>/root-cert.pem -text -noout > /tmp/root-cert.crt.txt
Run the following syntax at the terminal window.
$ openssl x509 -in ./proxy-cert-3.pem -text -noout > /tmp/pod-root-cert.crt.txt
Compare the certificates by running the following syntax at the terminal window.
$ diff -s /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt
You should see the following result:
Files /tmp/root-cert.crt.txt and /tmp/pod-root-cert.crt.txt are identical
Verify that the CA certificate is the same as the one specified by the administrator. Replace <path>
with the path to your certificates.
$ openssl x509 -in <path>/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt
Run the following syntax at the terminal window.
$ openssl x509 -in ./proxy-cert-2.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt
Compare the certificates by running the following syntax at the terminal window.
$ diff -s /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt
You should see the following result:
Files /tmp/ca-cert.crt.txt and /tmp/pod-cert-chain-ca.crt.txt are identical.
Verify the certificate chain from the root certificate to the workload certificate. Replace <path>
with the path to your certificates.
$ openssl verify -CAfile <(cat <path>/ca-cert.pem <path>/root-cert.pem) ./proxy-cert-1.pem
You should see the following result:
./proxy-cert-1.pem: OK
To remove the certificates you added, follow these steps.
Remove the secret cacerts
. In this example, istio-system
is the name of the control plane project.
$ oc delete secret cacerts -n istio-system
Redeploy Service Mesh with a self-signed root certificate in the ServiceMeshControlPlane
resource.
apiVersion: maistra.io/v2
kind: ServiceMeshControlPlane
spec:
security:
dataPlane:
mtls: true