Organizations are migrating their monolithic workloads to the microservices architecture. Many organizations have already used microservices-based workloads in production. The benefits of the distributed microservices infrastructure are numerous. Many organizations make the mistake of assuming that since each containerized service is walled off from other containers, there is an inherent security in the cluster. Even though services are siloed, these services communicate with each other for the workload to function. Services use APIs to communicate with each other. And, it’s in the communication between these services where security is paramount.
Let’s get familiar with TLS first
You’ve probably heard of TLS. Transport Layer Security is often used when you connect to a server via your browser. For example, when you open a website, you might see a green lock icon next to the address bar, which denotes that TLS is enabled. When a client connects to a server using TLS, the client requests the server to identify itself by providing the client with its public certificate. The client, in turn, challenges the server to decrypt a known value that is encrypted using the server’s public key. Once the server decrypts the known value, the secure and encrypted connection between the server and the client is established. However, a malicious server could present the client with a bogus certificate. In such a case, the authenticity of this certificate will have to be checked via a trusted third-party certificate authority. The connection won’t be established if the certificate is not signed by a trusted root CA or its intermediate CAs.
TLS has been used for secure connections between a client and server for years. However, what if you want only specific clients to access the server. With TLS, any client can access any server. Usually, the client is validated with the help of two-factor authentication, as is the case when accessing your bank’s portal online. However, what if you want to restrict access to a particular server to only a specific department inside an organization. This can be done in several ways. However, in the current age of zero-trust security, mTLS is your best option.
What is mTLS?
Mutual TLS or mTLS, as the name suggests, establishes a secure connection between the client and the server after they both validate each other’s authenticity. This means that unlike TLS, where only the server was required to prove its authenticity, in mTLS, the server will need the client to authenticate itself, too. When the client requests access to a server, the server will provide its certificate to the client and, in turn, ask the client for its public certificate. This certificate will contain a public key, an identity, and a signature by a trusted certificate authority. Both entities will then look for the signature and climb the trust chain till they find a mutual certificate authority validating the authenticity of both entities and creating a secure and encrypted channel.
Since both entities have to be validated, mTLS can reduce the chances of attacks. This kind of zero-trust security finds its applications in many spheres, especially in the service mesh.
The microservices security challenges
Microservices offer a myriad of benefits. However, with distributed workloads comes complexity. This complexity is functional where developers might create a mesh of services that is. Enabling security in all the benefits and taking care of best practices to eliminate risks of attacks can be done while developing the tools. However, that can become extremely time-consuming and distract developers from working on more critical tasks. Many organizations might go the traditional route and try to create an in-house security infrastructure. However, as your workloads grow in size, your in-house security infrastructure might not be able to scale. This might lead to rework, which will again be a distraction from actual development.
Enter a service mesh. Service meshes like Istio help with inter-application communication, security management, traffic control, load balancing, and security. With a service mesh, you can simplify communication between services, create and manage communication and authorization policies across all your services and observe any traffic bottlenecks in real-time. Your service mesh control plane provides a certificate authority that signs your services’ public certificates and the authorization policies each service will have to comply with.
mTLS in service mesh
Two services trying to communicate with each other follow many steps to authenticate and establish a secure and encrypted connection. Microservice A will request Microservice B for its public certificate; microservice B will send forth its certificate and request microservice A for its certificate. Microservice A will then validate the certificate using trusted certificate authority and send its certificate along with an encrypted session key. Microservice B will then check the authenticity of microservice A using the certificate authority and the communication policies distributed by the configuration API server. If the services are meant to communicate, mTLS will establish the secure channel, or else the access will be denied.
The mTLS connection is established by sidecars — Microservices leverage sidecars to communicate with each other. Instead of having developers write code for authorization and communication policies inside each service, Sidecars can be used to do this efficiently and without any room for human error. Sidecars act as a bridge between two services and offload a lot of overhead related to security management. These sidecars are responsible for requesting certificates, checking their validity using the CA, and checking the authorization policies defined by the service mesh control plane. This way, the actual service code is not affected, and developers won’t have to spend time updating the code upon every release.
Non-mTLS communication is still vital
As you migrate your workloads to the service mesh, you might want to ensure that non-mTLS communication is allowed. Not all the services you create will have mTLS enabled. By strictly enabling mTLS across your service mesh, namespace, or application, you could run the risk of breaking your application. This is likely as big a problem as a security breach. Another scenario where you might need to enable non-mTLS communication is when you want your services to interact with external non-mTLS services. Since microservices-based workloads tend to get quite complex, you might have difficulty figuring out where the issue occurred.
The popular service mesh tool Istio comes with three different settings for mTLS:
- Permissive: Allows both mTLS and non-mTLS communications.
- Strict: Allows only mTLS communication.
- Disabled: allows only non-mTLS communication.
Istio enables the permissive mode by default in all its proxies. This is the best way to go if you are starting your migration journey. The permissive mode is not secure since rogue microservices can still interact with your critical services. However, in the beginning, your priority should be ensuring your workloads don’t break. Then, you can gradually implement the strict setting based on how the services interact.
A big boost for zero-trust security
mTLS is incredibly important for your service mesh. It helps enable zero-trust security across your workloads. mTLS prevents middle-man attacks and blocks rogue microservices from accessing critical data that could be very detrimental to your organization. Organizations should not underestimate the importance of mTLS. However, a service mesh enables mTLS differently. You must understand how it works and what kind of defaults it comes with to make the most of this powerful capability.
Featured image: Pixabay