Efficient Golang Testing with Bufconn: Insecure, TLS, and mTLS

GS
Your Everyday Generalist
3 min readMar 7, 2023

Are you tired of the time and effort required to set up gRPC connections and free ports for your Golang tests, especially when working on securing your connections with TLS?

Setting up gRPC and choosing a free port for testing can be time-consuming and error-prone, as port conflicts can easily occur. Additionally, if you’re working on securing your gRPC connections with TLS, it’s essential to ensure that your unit tests are set up efficiently to avoid slowing down your development process and also maintain a high-level of confidence.

In this context, using Bufconn package in your Golang tests can simplify the process by allowing you to create secure connections in memory. This package implements the net.Conn using an in-memory buffer. This make it easy to not invest in additional test logic to manage unique ports for setting up your gRPC server. Let’s see how we can achieve various client <> server gRPC connection setups in Golang.

Example GreetService Proto Definition

Example GreetService RPC implementation

In order to setup gRPC TLS tests, we will need to create Root, Intermediate CAs along with Client and Server x.509 certificates. For the rest of the tutorial please assume that we have a testData data structure that holds self-signed Root, Intermediate CA, and also two client and one server x.509 certificates.

Sample CA hierarchy created under testData for our tests

gRPC Insecure

In this mode the gRPC connection is established between client and server without any security measures such as Transport Layer Security (TLS), it is considered insecure because the communication between the client and server is not encrypted or authenticated. This means that anyone who can access the network traffic can potentially eavesdrop on the messages sent between the client and server or even modify them.

gRPC TLS

In this mode the client and server both authenticate each other using their respective TLS certificates, but only the server is required to present a certificate. The client can verify the server’s certificate to ensure that it is communicating with the intended server and that the server’s certificate is trusted. However, the server does not need to verify the client’s certificate, as it is not necessary to authenticate the client in a one-way TLS connection. This setup is often used in scenarios where the client is unauthenticated or the server does not need to know the client’s identity.

gRPC mTLS

In mutual TLS (mTLS) for gRPC, both the client and server authenticate each other by presenting their respective TLS certificates. This provides mutual authentication and helps ensure that both parties can trust each other’s identities. In this setup, the client verifies the server’s certificate and the server verifies the client’s certificate, so that each party knows the identity of the other. This can be useful in scenarios where both the client and server need to authenticate each other, and where the server needs to know the identity of the client before processing any requests.

Here’s the full code setup for your reference. The project uses buf to managing proto dependencies and Makefile to simplify triggering tests.

Please also check out the Test_GRPC_MTLS_Root_CA_Knowledge and Test_GRPC_TLS_Root_CA_Knowledge tests, as those are closer to the production way of setting up your client and server TLS configuration. The main idea in these tests is to not require the client or server know about intermediate CAs and instead use the root CA to validate the TLS handshake. The benefit of this approach is that one can rotate client or server intermediate CAs without impacting the overall communication. Usually, as per PKI standards, intermediate CAs have shorter TTLs in comparison to the root TTL.

That’s it! So we have learned how to setup gRPC and variants of TLS versions. The TLS config structure exposes many other properties that you can tweak and test after as well.

Thanks for reading! If you found this article helpful, please consider buying me a coffee to support my work. Thanks again!

--

--

GS
Your Everyday Generalist

Senior Software Engineer - HashiCorp, Anime lover, OSS contributor, Go enthusiast, Sporadic writer!