Securing Your Microservices via Bi-Directional TLS
By- August 28, 2014
In the beginning, there was the monolithic webapp. Then, as the application grew and became harder to scale, pieces began to split off into separate services. Microservices have become an increasingly popular architecture choice for separating concerns while speeding up development and deployment. However, security remains a critical but rarely talked about piece. Microservices significantly increase your attack surface as these services send messages back and forth across a network rather than just processes on one machine. Security for microservices, or any service/network oriented architecture, comprises two components: the Transport Layer and Application Layer.
Hardening your transport layer is crucial, especially inside shared environments like AWS or Rackspace where you cannot be exactly sure where your network traffic is going or who might be listening in. Transport Layer Security (TLS), sometimes incorrectly still referred to as SSL (the predecessor to TLS), remains one of the cornerstones of encrypting and authenticating connections. Even if your services don’t communicate with HTTP(S) or RESTful APIs you can still wrap your network sockets with TLS.
It is usually prudent to secure all network traffic with TLS, despite the fact that engineers often seem to have misgivings about doing so. If you’re worried about performance loss from TLS, a load balancer can provide specialized hardware to efficiently terminate client TLS connections while also holding a persistent TLS connection open to the backend service. This persistent backend connection reduces the overhead of handshaking a new TLS connection with each request.
An often overlooked feature of TLS is authentication. While TLS can make guarantees about encrypting data as it moves across a network, it also provides a mechanism to enforce that the client and server don’t have a man-in-the-middle listening in. For public-facing services you must always rely on a public (paid) certificate authority. If you’re lucky enough to control both the server and every single client, you can roll your own certificate authority to sign your certificates.
During a typical TLS handshake the client and server exchange pleasantries and carefully begin setting up a secure tunnel. During this process the client should check that the certificate presented by the server is signed by a trusted authority (or chain of authorities). In addition, many TLS libraries allow the client to authenticate that the common name of the certificate matches the hostname it is trying to connect to. Both checks allow the client to assert that the server is actually who the client believes it is and communication is not being intercepted.
Besides transport security, services need to authenticate who is making the calls and ensure that they are authorized to do so. Conveniently TLS provides a mechanism to do this as well: not only can the client authenticate the server’s certificate is cryptographically valid, the server can similarly authenticate the client. During the handshake the server requests a certificate from the client, which it can provide. Mirroring the client, the server checks the validity of the certificate against a trusted certificate authority. However, the server can then extract out the details of the client from the certificate, such as the common name, and rather than checking against a hostname can use application-layer logic to authenticate the client is authenticated and authorized to do what they are trying to do. This bi-directional TLS authentication allows both sides of the connection to assert they are connecting with the other party they expect.
Bi-directional TLS is not often used, likely due to the pain points of creating and managing many certificates and the associated revocation lists. However, managing a set of allowed certificates is very similar to managing a set of allowed API keys. One way is to manage a specific set of revoked certificates, acting as a blacklist. However, if client certificates are treated as API keys you can instead manage allowed clients via a known whitelist. You gain cryptographic assurance that your client is who they say they are, while also ensuring your communication is encrypted.
Bi-directional TLS may not fit in every situation, but it’s a useful tool to have in one’s toolbox and may help leverage technology you’re already using. Tinfoil’s scanners are authenticated via bi-directional TLS, in addition to other network layer and application layer authentication methods. Just as you don’t want your application to have a single point of failure, you don’t want to depend on a single security method either.