Mutual TLS Migration

This task shows how to migrate your existing Istio services’ traffic from plaintext to mutual TLS without breaking live traffic.

In the scenario where there are many services communicating over the network, itmay be desirable to gradually migrate them to Istio. During the migration, some services have Envoysidecars while some do not. For a service with a sidecar, if you enablemutual TLS on the service, the connections from legacy clients (i.e., clients withoutEnvoy) will lose communication since they do not have Envoy sidecars and client certificates.To solve this issue, Istio authentication policy provides a “PERMISSIVE” mode to solvethis problem. Once “PERMISSIVE” mode is enabled, a service can take both HTTPand mutual TLS traffic.

You can configure Istio services to send mutualTLS traffic to that service while connections from legacy services will notlose communication. Moreover, you can use theGrafana dashboard to check which services arestill sending plaintext traffic to the service in “PERMISSIVE” mode and choose to lockdown once the migration is done.

Before you begin

  • Understand Istio authentication policy and related mutual TLS authentication concepts.

  • Have a Kubernetes cluster with Istio installed, without global mutual TLS enabled (e.g use the demo configuration profile as described ininstallation steps, or set the global.mtls.enabled installation option to false).

  • For demo

    • Create the following namespaces and deploy httpbin and sleep with sidecar on both of them.

      • foo
      • bar
    • Create the following namespace and deploy sleep without sidecar

  1. $ kubectl create ns foo
  2. $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n foo
  3. $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@) -n foo
  4. $ kubectl create ns bar
  5. $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n bar
  6. $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@) -n bar
  7. $ kubectl create ns legacy
  8. $ kubectl apply -f @samples/sleep/sleep.yaml@ -n legacy
  • Verify setup by sending an http request (using curl command) from any sleep pod (among those in namespace foo, bar or legacy) to httpbin.foo. All requests should success with HTTP code 200.
  1. $ for from in "foo" "bar" "legacy"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.foo: %{http_code}\n"; done
  2. sleep.foo to httpbin.foo: 200
  3. sleep.bar to httpbin.foo: 200
  4. sleep.legacy to httpbin.foo: 200
  • Also verify that there are no authentication policies or destination rules (except control plane’s) in the system:
  1. $ kubectl get policies.authentication.istio.io --all-namespaces
  2. NAMESPACE NAME AGE
  3. istio-system grafana-ports-mtls-disabled 3m
  1. $ kubectl get destinationrule --all-namespaces
  2. NAMESPACE NAME AGE
  3. istio-system istio-policy 25m
  4. istio-system istio-telemetry 25m

Configure clients to send mutual TLS traffic

Configure Istio services to send mutual TLS traffic by setting DestinationRule.

  1. $ cat <<EOF | kubectl apply -n foo -f -
  2. apiVersion: "networking.istio.io/v1alpha3"
  3. kind: "DestinationRule"
  4. metadata:
  5. name: "example-httpbin-istio-client-mtls"
  6. spec:
  7. host: httpbin.foo.svc.cluster.local
  8. trafficPolicy:
  9. tls:
  10. mode: ISTIO_MUTUAL
  11. EOF

sleep.foo and sleep.bar should start sending mutual TLS traffic to httpbin.foo. And sleep.legacy still sends plaintexttraffic to httpbin.foo since it does not have sidecar thus DestinationRule does not apply.

Now we confirm all requests to httpbin.foo still succeed.

  1. $ for from in "foo" "bar" "legacy"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.foo: %{http_code}\n"; done
  2. 200
  3. 200
  4. 200

You can also specify a subset of the clients’ request to use ISTIO_MUTUAL mutual TLS inDestinationRule.After verifying it works by checking Grafana to monitor,then increase the rollout scope and finally apply to all Istio client services.

Lock down to mutual TLS (optional)

After migrating all clients to Istio services, injecting Envoy sidecar, we can lock down the httpbin.foo to only accept mutual TLS traffic.

  1. $ cat <<EOF | kubectl apply -n foo -f -
  2. apiVersion: "authentication.istio.io/v1alpha1"
  3. kind: "Policy"
  4. metadata:
  5. name: "example-httpbin-strict"
  6. namespace: foo
  7. spec:
  8. targets:
  9. - name: httpbin
  10. peers:
  11. - mtls:
  12. mode: STRICT
  13. EOF

Now you should see the request from sleep.legacy fails.

  1. $ for from in "foo" "bar" "legacy"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.foo: %{http_code}\n"; done
  2. 200
  3. 200
  4. 503

If you can’t migrate all your services to Istio (injecting Envoy sidecar), you have to stay at PERMISSIVE mode.However, when configured with PERMISSIVE mode, no authentication or authorization checks will be performed for plaintext traffic by default.We recommend you use Istio Authorization to configure different paths with different authorization policies.

Cleanup

Remove all resources.

  1. $ kubectl delete ns foo bar legacy
  2. Namespaces foo bar legacy deleted.

相关内容

Authentication Policy

Shows you how to use Istio authentication policy to setup mutual TLS and basic end-user authentication.

安全

描述 Istio 的授权与鉴权功能。

Multi-mesh deployments for isolation and boundary protection

Deploy environments that require isolation into separate meshes and enable inter-mesh communication by mesh federation.

App Identity and Access Adapter

Using Istio to secure multi-cloud Kubernetes applications with zero code changes.

Change in Secret Discovery Service in Istio 1.3

Taking advantage of Kubernetes trustworthy JWTs to issue certificates for workload instances more securely.

Istio 1.2.4 sidecar image vulnerability

An erroneous 1.2.4 sidecar image was available due to a faulty release operation.