Live data from Hacker News

TLS certificates for internal services done right

tuxnet.dev

71–80 of 177 posts

Re: TLS certificates for internal services done right

#71

The relative proximity of the words "done right" and "split-horizon DNS" makes my insides hurt a little bit. Use DNS validation to allow these internal services to pull ACME certs. There's so much less headache, long-term. Split-horizon DNS (and the tedious make-work it can create when you start needing to mirror public-accessibly records in the private DNS) has always been something to aspire to move away from in my…

Another big problem with split-horizon is you can get clients that cache the dns result before connecting to the vpn, then after connecting, can't actually use the service, because it is using the public ip instead of the private one.

Re: TLS certificates for internal services done right

#72

Or... - Don't use split DNS. Don't use any special internal or dev domain. Leave it to your infrastructure to route/NAT those public IPs to your internal network. - Don't use the HTTP-01 challenge. Use DNS-01. - Don't run your own internal CA. Use Let's Encrypt. If you care about name leakage (CT Logs), use wildcard certs. Use a central reverse proxy/load balancer for termination.

Using wildcard certs and/or a central reverse proxy defeats the purpose of internal TLS.

Split-horizon DNS for a publicly usable domain is almost always a bad idea, but running your own ACME server is pretty easy (maybe 10 lines of Caddy config) and using an internal domain (an actual one, not a randomly picked TLD you don't think exists yet) solves the problem pretty easily. You'll want a safe backup for your root certificate private key, of course, but that's pretty much all you need to really worry about.

Re: TLS certificates for internal services done right

#73

Hmm. I don't really care enough about leaking home network host names because they are all super generic names like 'router', 'laptop', 'tv', 'nas'. So I use my public zone on cloudflare. I just use internal ip addresses (eg: nas.example.com = 10.1.2.3) on the public zone and DNS01 challenge for let's encrypt. Anyone can resolve the ip for any of my hosts, but obviously you'd need to be on the wireguard vpn to hit th…

I don't think this is any less right than using split horizon. IMHO, there is no "right" way to do it. Every approach has downsides and tradeoffs.

Re: TLS certificates for internal services done right

#74
post #34
post #32

I don’t know much in this space, but I find myself wishing there was a dead simple self hosted CA solution and also that trust on first use (à la ssh) was A Thing for self-managed root certs in client implementations. TOFU is such an elegant, good-enough solution for these use cases. Fixed deployment is always still an option, but in this day and age it feels so much like we are unnecessarily still dealing with solve…

On k8s, there's cert-manager but also you need k8s... Most browsers support trust on first use for leaf certs

That support is limited. Browsers refuse to support passkeys when you TOFU untrusted certs, and for good reason.

Re: TLS certificates for internal services done right

#75

The real answer here is that configuring HTTPS clients to trust a self-signed cert (or signed by an internal CA) shouldn't be as difficult as it is. I find it extremely annoying that every programming language has it's own idea of where certificates should live instead of just checking the os trust store.

Is there a commonly used language other than Java that doesn’t just defer to the OS trusted CAs by default?

Node and (probably by extension) Electron infuriate me with their custom requirements.

Several Rust libraries also tend to default to a predefined set of certificates (which makes sense for libraries supposed to run on bare metal as there are no system certificates there, but that's not really a problem on most Linux installs). I make it a point to always use the native OS roots in the code I write, but unfortunately that's not universal.

Having to bind-mount certificates inside of docker containers is also always an annoyance I forget about until I see the first TLS errors in the logs, but that's by design and probably a good thing.

Re: TLS certificates for internal services done right

#77

The relative proximity of the words "done right" and "split-horizon DNS" makes my insides hurt a little bit. Use DNS validation to allow these internal services to pull ACME certs. There's so much less headache, long-term. Split-horizon DNS (and the tedious make-work it can create when you start needing to mirror public-accessibly records in the private DNS) has always been something to aspire to move away from in my…

Once dns-persist-01 becomes available/usable[1], it should make dns validation even easier. [1]: https://letsencrypt.org/2026/02/18/dns-persist-01

I never understood the issue with DNS-01. if you have a process that you trust to maintain a zone's TLS identity what is the big deal about letting it control a record in that zone?

Re: TLS certificates for internal services done right

#78
My setup is having a wildcard DNS record and a wildcard certificate for my 'home' domain. It has a fixed IP from my ISP, so you always end up on haproxy, which then forwards to individual ports/ip's in the internal network. I can do filtering based on source-ip from there, so traffic from myself/internal will be allowed, and outside traffic (not from some allowlisted ip's) will get blocked. ACME validation is done via DNS, so nothing needs to be accessable for that to issue certificates. Internally I will usually also use the public IP for services, so no need for a split-dns.

Re: TLS certificates for internal services done right

#79
post #77

Earlier quoted context omitted.

Once dns-persist-01 becomes available/usable[1], it should make dns validation even easier. [1]: https://letsencrypt.org/2026/02/18/dns-persist-01

I never understood the issue with DNS-01. if you have a process that you trust to maintain a zone's TLS identity what is the big deal about letting it control a record in that zone?

You can even put it in a seperate zone (which I do) by using a CNAME for _acme-challenge.domain.tld. I have it to a seperate subdomain, which is served by a seperate desec.io account, which is only used for this specific subdomain.
Post reply on HN