How to provide mutual TLS (mTLS) with Spring application in Kubernetes?

2/1/2022

I have an interesting problem, maybe you could help me out.

There are given two spring applications, called app1 and app2. There is plenty of REST calls are happening to both of the services. I need to implement a security solution where both of them can communicate with each other on REST but it is protected by mutual TLS (mTLS where both app has its own cert for each other)

Implementing it the standard way its not that hard, Spring has solutions for it (with keystores and etc.), but the twist is, I have to create it in a Kubernetes environment. The two app is not in the same cluster, so app1 is in our cluster but app2 deployed in one of our partner's system.
I am pretty new to k8s and not sure what is the best method to achieve this. Should I store the certs or the keystore(s) as secrets? Use and configure nginx ingress somehow, maybe Istio would be useful? I would really want to find the optimal solution but I don't know the right way. I would really like if I could configure it outside my app and let k8s take care about it but I am not sure if it is the right thing to do.

Any help would be really appreciated, some guidance to find the right path or some kind of real life examples.
Thank you for your help!

-- Five
kubernetes
kubernetes-ingress
spring
spring-security
ssl

2 Answers

2/2/2022

Mikolaj has probably covered everything but still let me add my cent

i don't have much experience working with Istio, however i would also suggest checking out the Linkerd service mesh.

Step 1.

Considering if you are on multi could GKE & EKS or so still it will work.

Multicluster guide details and installation details

Linkerd will use the Trust anchor between the cluster so traffic can flow encrypted and not get open to the public internet.

You have to generate the certificate which will form a common base of trust between clusters.

Each proxy will get copy of the certificate and use it for validation.

-- Harsh Manvar
Source: StackOverflow

2/2/2022

The answer to your problem will be more complex as there is no one-size-fits-all solution that turns out to be the best. It all depends on what exactly you want to do and what tools you have for it. suren mentioned it very well in the comment:

if you are still in the stage of PoC, then note that there are couple of ways of achieving what you want. Istio would be a valid way, for example. You could have the other service in a ServiceEntry, enable mTLS and there you go. You don't have to even manage secrets for this specific scenario, as it is automatic. But there are other ways. Even with Istio there are other ways. If you are on any cloud provider, you might have some managed services as well

This is a very good comment and I would also recommend an istio based solution to you. First of all check the official mTLS documentation for istio first. You will also find specific usage examples and sample configuration files there.

You also mentioned in the question that your application will run between two clusters. Take a look at this tutorial, which shows exactly how to solve this situation:

Istio injects an envoy sidecar to every pod and makes sure all the traffic goes through the envoy proxy. Envoy proxies compose the data plane. The control plane manages the Envoy sidecars. In previous versions of Istio, the control plane used to have other components, such as Pilot, Citadel, and Galley. These components got consolidated into a single binary called “istiod”. The control plane also deals with the configurations, certificates, secrets, and health checking.

For more information look also at related problem on stackoverflow and another tutorial.

Take into account that in addition to istio itself, you will be able to use ready-made cloud solutions, for example available at GKE i.e. Configuring TLS and mTLS on the Istio ingress .

Another way might be to use a tool Anthos Service Mesh by example: mTLS.

-- Mikołaj Głodziak
Source: StackOverflow