Secure Your Microservices with Istio*
Istio is an open source project intended to manage the communications between microservices on the cloud. It is platform-independent, but usually and mainly works with Kubernetes*. Istio provides several key capabilities, such as traffic management, security, and observability. In this article, we will focus on Istio’s security capability, including strong identity, transparent TLS encryption, authentication, and authorization. We deploy Istio on a Kubernetes cluster and go through the Istio security features step by step, talking about how these features protect your services.
We use the sample application Bookinfo, which is provided by Istio, to demonstrate Istio’s features in this article. Let’s examine the architectures of Istio security and Bookinfo.
Istio security architecture
Istio security involves multiple components; the following diagram shows the architecture. In the Istiod component of the control plane, we have a CA (Certificate Authority) to manage the certificates, and the relevant configurations are sent to the data plane (Envoy*) through the API server. Envoy works as Policy Enforcement Points (PEPs) to protect the communication security between the client and the server in the mesh or between the outside and the inside of the mesh.
Bookinfo application architecture
The Bookinfo application is divided into four separate microservices:
· productpage: calls the details and reviews microservices to populate the page
· details: contains book detailed information
· reviews: calls the ratings microservice to generate book reviews
· ratings: contains ranking information that accompanies a book review
There are three versions of the reviews microservice; productpage accesses these versions in round robin fashion:
· Version v1 doesn’t call the ratings service.
· Version v2 calls the ratings service and displays each rating as 1 to 5 black stars.
· Version v3 calls the ratings service and displays each rating as 1 to 5 red stars.
The end-to-end architecture of the application is shown below. These are original pure services deployed without the Istio sidecar.
If you have already installed Istio, you can run the sample without making any changes to the application. Or, you can simply configure and run the services in an Istio-enabled environment, with Envoy sidecars injected alongside each service. The resulting deployment looks like this:
Here we deliberately deploy the review-v2 without sidecars and other services with sidecars. This is easily controlled by setting the Kubernetes namespace label “istio-injection=enabled/disabled”. Once we inject a sidecar for a pod or just set up a single edge proxy as ingress gateway, Istio identity takes effect.
The Istio identity model uses the first-class service identity to determine the identity of a request’s origin. On Kubernetes, Istio uses the Kubernetes service account for identity. The diagram below shows the identity provisioning workflow of Istio.
1. Start a pod with Istio injected, which also starts an instance of Envoy as a sidecar for the pod.
2. When the workload is started, Envoy requests the certificate from the Istio agent via the Envoy secret discovery service (SDS) API.
3. The Istio agent sends certificate signing requests (CSR) with its credentials (JWT) to istiod for signing.
4. The Istio agent sends the certificates received from istiod signed with SPIFFE format to Envoy via the Envoy SDS API.
The certificate here is x.509 and the URL in SPIFFE format is used as an extension field of the x.509 certificate for identifying. SPIFFE is open source; the format in the Istio identity under a k8s environment is similar to “spiffe://<domain>/ns/<namespace>/sa/<serviceaccount>””. We can obtain the certificate by using the Istioctl tool and parsing the Spiffe URL from the certificate manually. We can also dump and check the configuration of the sidecar to verify the URL is injected into it.
Istio supports mutual TLS to encrypt the data being transported between services. In the Bookinfo application, all services originally communicate with each other based on pure HTTP protocol where the data is not encrypted. When a workload sends a request to another workload using the mutual TLS authentication policy, the data between the workload and the sidecar is still in plain text, while the client-side Envoy and the server-side Envoy establish a mutual TLS connection.
After applying the peer authentication policy (shown above), Istio automatically upgrades all traffic between two PEPs to mutual TLS. Reviews-v2 can still be accessed via HTTP since auto-mTLS of Istio is enabled by default. Auto-mTLS in Istio helps to decide what type of traffic the client sidecar can send:
· If DestinationRule is configured, respect it
· If server has a sidecar and allows mTLS, send mTLS – reviews-v1 & v3
· Otherwise, send plain text – reviews-v2
Peer authentication only defines which type of traffic the server sidecar can receive. reviews-v2 does not have a sidecar, so the client sends plain text to it. The server side is in PERMISSIVE mode by default, which means the server side can accept both plain text and mTLS. This is very useful when starting to integrate your cluster with service mesh because usually the operator cannot install an Istio sidecar for all clients at the same time or does not even have the permissions to do so on some clients.
In contrast with peer authentication, destination rule defines which type of traffic the client sidecar can send. After applying the destination rule policy (shown above), reviews-v2 cannot be accessed any more, since destination rule restricts the productpage sidecar to send mTLS traffic, and reviews-v2 can only receive plain text.
Secure ingress traffic
Istio supports exposing a secure HTTPS service to external traffic via the ingress gateway, so there is no need to change internal protocols. It supports a total of four modes to enable TLS on ingress. SIMPLE/MUTUAL and ISTIO_MUTUAL perform TLS terminations on incoming requests; they are used to configure HTTPS ingress access to HTTP service. PASSTHROUGH and AUTO_PASSTHROUGH only pass the ingress traffic AS IS instead of with TLS termination.
Authorize ingress traffic
Add a request authentication policy that requires end-user JWT for the ingress gateway. If you provide a token in the authorization header—its implicitly default location—Istio validates the token using the public key set and rejects requests if the bearer token is invalid. However, requests without tokens are accepted.
To reject requests without valid tokens, add an AuthorizationPolicy with a rule specifying an ALLOW action for requests with request principals, which is shown as requestPrincipals in the above example. requestPrincipals are available only when valid JWT tokens are provided. Therefore, the rule only allows requests with valid tokens.
Apply RequestAuthentication, as shown above
· request with valid JWT token √
· request without JWT token √
· request with invalid JWT token ×
Apply AuthorizationPolicy, as shown above
· request with valid JWT token √
· request without JWT token ×
· request with invalid JWT token ×
Authorize in mesh traffic
Not only can AuthorizationPolicy be applied on an ingress gateway, it can also be used to control access inside mesh. An authorization policy spec includes a selector, an action, and a list of rules:
· The selector field specifies the target of the policy
· The action field specifies whether to allow or deny the request; the default value is “ALLOW”
· The rules specify when to trigger the action
o The from field in the rules specifies the sources of the request
o The to field in the rules specifies the operations of the request
o The when field specifies the conditions needed to apply the rule
If you apply a deny-all AuthorizationPolicy, all requests between services under the default namespace will be denied. If you then apply productpage-viewer as shown in the example below, it allows a “GET” operation to the productpage service.
Compared with productpage-viewer AuthorizationPolicy, reviews-viewer has one more configuration in the source field of the spec rule; it specifies that only allowing the services with “["cluster.local/ns/default/sa/bookinfo-productpage"]” service account to send a “GET” request. Apply other AuthorizationPolicy one by one and test the productpage. Different information provided by the Bookinfo services will all appear again on your web page.
Istio provides strong identification automatically. It also has Mutual TLS that encrypts traffic to defend against man-in-the-middle attacks. Auto-mTLS helps you onboard Istio, and PeerAuthentication and DestinationRule ease the process of making subtle adjustments to configurations. Besides, Istio provides flexible service access control, so you can use RequestAuthentication, AuthorizationPolicy, etc. to set fine-grained access policies.
· Istio official document: https://istio.io/latest/docs/