TLS certificates for internal services done right
This technical guide demonstrates a robust method for securing internal services with TLS certificates, circumventing the perennial pain of self-signed certificates and their trust issues. By combining split-horizon DNS, public Certificate Authorities like Let's Encrypt, and a Web Application Firewall, the author offers a practical, 'right way' solution that resonates with developers facing infrastructure challenges. It highlights how to leverage existing tools to achieve secure, internal-only access without compromise.
The Lowdown
Securing internal services with TLS certificates often devolves into the hassle of self-signed certificates or ignoring security warnings. This post proposes a 'right way' to implement TLS for internal-only applications, like Grafana, ensuring proper encryption and certificate validation without the typical pitfalls.
The author contrasts two main approaches:
- Using
.internalTLDs: This typically necessitates self-signed certificates, leading to trust issues across clients and requiring manual configuration on every machine or advising users to ignore security warnings. - Using a public apex domain with split-horizon DNS: This method involves configuring DNS so that internal clients (e.g., via VPN) resolve the domain to an internal IP, while external requests resolve to a public IP. This allows the use of public Certificate Authorities (CAs) like Let's Encrypt, solving the trust problem.
To implement the 'right way', the guide outlines using:
- NetBird: For VPN connectivity and its Custom Zones feature, which simplifies split-horizon DNS configuration.
- acme.sh: As an ACME client to obtain TLS certificates from Let's Encrypt using the
http-01challenge, showcasing the standalone mode. - Nginx: As a reverse proxy and Web Application Firewall (WAF). Nginx is configured to listen only on the VPN network interface, effectively acting as a WAF to reject external traffic, adding a crucial second layer of security.
The article also covers automated certificate renewal using a cron job that refreshes certificates via acme.sh and reloads Nginx. A bonus section explains how to manage multiple internal services with a single certificate using Subject Alternative Names (SANs) rather than wildcard certificates.
In essence, this approach provides a free, secure, and maintainable way to ensure internal services have valid TLS certificates, eliminating client-side trust configuration and simplifying security management with layered defenses.