Aqua Blog

Istio Security: Zero-Trust Networking

Istio Security: Zero-Trust Networking

This is the second in our series of blog posts on Istio, and will focus on Istio’s security features: what they are, how they work and how they help protect your workloads and your data.

Building, deploying and maintaining secure, cloud native software requires multiple overlapping solutions at different stages of the software development lifecycle. The Istio service mesh concerns itself with security problems that are closer to the runtime end of that journey, but it is not an intrusion detection system or simply a monitoring solution; it is a preventative control.

istio kubernetes security

Istio provides a foundation of application security that sits well with the zero-trust networking model. Zero-trust networking practices are based on the assumption that code is vulnerable and the network is compromised; all communications are encrypted, centrally authorized, and continually validated against mesh policy.

Istio achieves this by pushing centralized policy configuration into the Envoy sidecar proxies. These proxies live in each pod and are the gateways for network ingress and egress for all workloads, where they make policy and security decisions for the traffic in the mesh.

How does Istio fit in to our Security Strategy?

Delivering secure software includes, but is not limited to:

  • Securing your infrastructure
  • Securing your builds to protect against supply-chain attacks and known security vulnerabilities
  • Securing your pipeline to prevent compromise of build servers and the credentials they hold
  • Securing your application code to minimize exploitable vulnerabilities
  • Securing your application at runtime to prevent intrusion and limit the blast radius of compromised services
  • Addressing all of the above globally and reliably, and with minimal impact on the application developers

Istio’s security features fall mostly into the final category. Istio secures application-to-application communications with network policy, but also indirectly provides security with configurable traffic flow rules that can assist with attacks that seek to overload your network.

Where Istio security shines is in limiting the damage resulting from a compromised service, so that if one area of your application is compromised, it would be difficult for an attacker to use that area as a launching pad to continue the attack across the network or cluster. As zero-trust networking wisdom teaches us, our code is vulnerable and malicious actors are inside our network. That compromise may come via the supply chain (internal or external attacker) or via a compromised public-facing service. The last thing we want is for a compromised front-end application to be able to eavesdrop on cluster traffic, or make SQL queries to the database and exfiltrate the results across the internet. With mutual TLS, robust workload identity and network policy, an attacker trying to pivot from a compromised service will have limited options.

Whilst Kubernetes itself provides network policy, Istio allows us to express it at the application level by leveraging workload identity to provide service-level RBAC built on a strong chain of trust.

In this way, Istio protects us against both malicious internal actors and external attackers.

Network policy prevents unauthorized service-to-service communication

Network policy prevents unauthorized service-to-service communication

Istio Security Features

Encryption and Authentication via Mutual TLS Between Services Citadel, Istio’s certificate authority, issues certificates for each workload, providing mutual TLS for service-to-service and end-user communications. You can even upgrade unencrypted traffic transparently in the service mesh. Istio can handle end-user authentication using the originating end-user JWT (JSON Web Token) credential.

Mutual TLS (or mTLS) is simply the TLS handshake performed twice, establishing the same level of trust in both directions (as opposed to one directional client-server trust).

istio kubernetes security

Self-signed certificates are a security no-no on the wider Internet — we need to ensure that the credential being presented to us is from a source we trust. This is less of an issue inside the cluster, as the “authority” of a top-level CA has less meaning in this domain. It is possible, however, to use an CA external to the cluster if self-signed certificates aren’t sufficient for your organisation.

Citadel knows the lifetime of the certificates it generates, and will automatically rotate them via Kubernetes secrets.

Service Identity

Just as users have identity, can be authenticated (i.e. prove their identity) and authorized (allowed to access only what they have permission to access), so too can applications. Istio issues each service a secure identity, or SVID, which is used to identity the service across the mesh, and upon which Istio RBAC and policy is layered. SVIDs are an extension to x509 certificates that encode a unique Kubernetes service account into the certificate, ensuring that service-to-service communications can be trusted as coming from where they claim to originate. To achieve this, the Pilot maintains secure naming information, which is a mapping from a service’s identity to the service account authorized to run it. Envoy will check the secure naming information encoded within a service’s certificate as part of establishing trust. Attempting to impersonate services in order to thwart network policy is therefore made significantly more difficult.

RBAC and Network Policy

Whilst Kubernetes has API RBAC to control user access to the Kubernetes API and a network policy that specifies which services can speak to which other services, Istio RBAC is based on service identity, allowing for a richer expression of network policy defined at the application level.

This is a form of micro-segmentation, and can prevent an attacker from pivoting from one compromised service into other parts of the application. For example, if a host is compromised through an attack on a front-end service, we don’t want the attacker to be able to connect to more sensitive parts of the network, e.g. the database.

Istio network policy is enforced at the pod level (in the Envoy proxy), in user-space, at layer 7, as opposed to Kubernetes network policy, which is in kernel-space at layer 4, and is enforced on the host. By operating at layer 7, Istio has a richer set of attributes to express and enforce policy in the protocols it understands (e.g. HTTP headers). Kubernetes’ layer 4 network policy applies to all protocols and therefore forms a solid base layer of policy.

The two systems can be used in conjunction.

Istio RBAC policies are expressed in YAML; the following example is permitting read-only HTTP access for an application based on labels:

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: service-viewer
  namespace: default
spec:
  rules:
  - services: ["*"]
    methods: ["GET"]
   constraints:
   - key: "destination.labels[app]"
     values: ["productpage", "details", "reviews", "ratings"]
# ...

Rate Limiting, Circuit Breaking and Whitelisting/Blacklisting

We will be covering Istio’s traffic management features in more depth in the next article in the series, but these have security implications as well. Just as a denial-of-service attack on a website is obviously a security issue, traffic flow within our network can be manipulated to create security problems.

A circuit breaker pattern allows one to minimize the impact of overwhelmed systems. We can use rate limiting to prevent a compromised service from DoSing other components of our system, or become a base for DoSing external services. Flooding techniques could conceivably be used to overwhelm and disable components of our application, which could modify the attack surface of the application.

Similar to network policy, we can use whitelists and blacklists in Istio to enforce policy; again, at layer 7 Istio has a richer set of attributes with which to express and enforce these policies, and can work in conjunction with Kubernetes Network Policy. This type of policy enforcement is useful for limiting the source of ingress that is permitted to the application.

Mitigated Attacks

The Istio security features outlined in this article allow us to mitigate against the following types of attacks:

  • Microservice impersonation (mitigated by Authentication, Secure Naming and mTLS): Istio Authentication makes it difficult for a compromised service to pivot into another co-tenanted application’s flow by impersonating the target application’s microservice
  • Unauthorized access (mitigated by Authorization): Istio Authorization provides Service-to-Service level RBAC, preventing communication between services that don’t require it
  • Using existing permissions at a rapid rate to exfiltrate data/DoS (mitigated by Authorisation and traffic control): Rate limiting enforced via mixer can shut down traffic that exceeds that exhibited in normal operation
  • Packet sniffing (mitigated through mTLS)

Remember that Istio is doing all this transparently in the service mesh, driven by central policy config, without the application developers even knowing about it.

Conclusion

Even if you are confident that your infrastructure and Kubernetes cluster are sufficiently hardened, and that you have taken steps to mitigate against supply-chain attacks in your CI pipeline, you are still at risk of malicious code from an internal actor being deployed and run in your cluster, or an external attacker gaining control of a container or host by exploiting a security vulnerability. You must assume this is going to happen, and design for it.

Istio’s authentication, encryption and access control features enable you to limit the damage when this occurs and protect your organization’s valuable assets from compromise and exfiltration. Istio’s service mesh design allows you to achieve this without modifying your application code.

Istio’s security domain is layer 7, the application layer, and therefore the level at which security restrictions are expressed is the application level. This is the domain of developers, and Istio allows them to express application-level network policy without a deep knowledge of Kubernetes and networking. However, our experience has shown us that developers have a tendency towards more permissive security configurations that aid their productivity. This could arguably be attributed, at least in part, to security tooling that is arcane to them. Istio has the potential to change that, without sacrificing governance.

In the next article in the series we will explore Istio’s traffic management features, and the canary deployments and other rollout techniques they make possible.

Note: This is a guest blog post by Luke Bond from Control Plane.

Aqua Team
Aqua Security is the largest pure-play cloud native security company, providing customers the freedom to innovate and accelerate their digital transformations. The Aqua Platform is the leading Cloud Native Application Protection Platform (CNAPP) and provides prevention, detection, and response automation across the entire application lifecycle to secure the supply chain, secure cloud infrastructure and secure running workloads wherever they are deployed. Aqua customers are among the world’s largest enterprises in financial services, software, media, manufacturing and retail, with implementations across a broad range of cloud providers and modern technology stacks spanning containers, serverless functions and cloud VMs.