Istio | TLS mutual-auth without using Istio ingress gateway

1.1k views Asked by At

I want to achieve TLS mutual auth between my different services running in a kubernetes cluster and I have found that Istio is a good solution to achieve this without making any changes in code.

I am trying to use Istio sidecar injection to do TLS mutual auth between services running inside the cluster.

  • Outside traffic enters the mesh through nginx ingress controller. We want to keep using it instead of the Istio ingress controller(we want to make as little changes as possible).
  • The services are able to communicate with each other properly when the Istio Sidecar injection is disabled. But as soon as I enable the sidecar in the application's namespace, the app is not longer able to serve requests(I am guessing the incoming requests are dropped by the envoy sidecar proxy).

My architecture looks like this

What I want to do:

  • Enable istio sidecar proxy injection on namespace-2(nginx ingress controller, service 1 and service 2) so that all services communicate with each other through TLS mutual auth.

What I don't want to do:

  • Enable istio sidecar proxy injection on the nginx ingress controller(I don't want to make any changes in it as it is serving as frontend for multiple other workloads).

I have been trying to make it work since a couple of weeks with no luck. Any help from the community will be greatly appreciated.

1

There are 1 answers

0
Jakub On

my goal is to atleast enable TLS mutual auth between service-1 and service-2

AFAIK if you have enabled injection in namespace-2 then services here already have mTLS enabled. It's enabled by default since istio 1.5 version. There are related docs about this.

Automatic mutual TLS is now enabled by default. Traffic between sidecars is automatically configured as mutual TLS. You can disable this explicitly if you worry about the encryption overhead by adding the option -- set values.global.mtls.auto=false during install. For more details, refer to automatic mutual TLS.

Take a look here for more information about how mtls between services works.

Mutual TLS in Istio

Istio offers mutual TLS as a solution for service-to-service authentication.

Istio uses the sidecar pattern, meaning that each application container has a sidecar Envoy proxy container running beside it in the same pod.

  • When a service receives or sends network traffic, the traffic always goes through the Envoy proxies first.

  • When mTLS is enabled between two services, the client side and server side Envoy proxies verify each other’s identities before sending requests.

  • If the verification is successful, then the client-side proxy encrypts the traffic, and sends it to the server-side proxy.

  • The server-side proxy decrypts the traffic and forwards it locally to the actual destination service.

enter image description here

NGINX

But the problem is, the traffic from outside the mesh is getting terminated at the ingress resource. The nginx reverse proxy in namespace-2 does not see the incoming calls.

I see there is similar issue on github about that, worth to try with this.

Answer provided by @stono.

Hey, This is not an istio issue, getting nginx to work with istio is a little bit difficult. The issue is because fundamentally nginx is making an outbound request to an ip that is has resolved from your hostname foo-bar. This won't work as envoy doesn't know what cluster ip belongs to, so it fails.

I'd suggest using the ingress-nginx kubernetes project and in turn using the following value in your Ingress configuration:

annotations: nginx.ingress.kubernetes.io/service-upstream: "true" What this does is ensure that nginx doesn't resolve the upstream address to an ip, and maintains the correct Host header which the sidecar uses in order to route to your destination.

I recommend using this project because I use it, with Istio, with a 240 odd service deployment.

If you're not using ingress-nginx, I think you can set proxy_ssl_server_name on; or another thing you could try is forcefully setting the Host header on the outbound request to the internal fqdn of the service so:

proxy_set_header Host foo-bar; Hope this helps but as I say, it's an nginx configuration rather than an istio problem.