We all need validation from time to time. TLS Certificates, the neediest of the modern webstack, need it every 7 to 90 days. At least, it does if you are using Let's Encrypt. That's great for security, but difficult to do manually.
Let's Encrypt, one of the modern wonders of the world, revolutionized certificate issuance. They managed to make certificate issuance fast and free by automating the validation process.
The Setup
While setting up hashnode.dev as my blog host, I learned about a new technique, well, new to me.
I wanted to host my blog at soberterrain.com, not at soberterrain.hashnode.dev. Of course, I wanted Hashnode to host it with a TLS certificate valid for soberterrain.com.
Previously, I've only seen service providers handle this by asking me to place a special TXT record in my DNS. Then the service provider asks a cert provider to generate a certificate for that domain. The cert provider verifies the service provider's "ownership" of the domain by looking for that TXT record.
However, Hashnode's instructions only requested that I make an A record entry for their IPv4 address (76.76.21.21). Dubious, I did as they asked. Navigating to soberterrain.com delivered my sweet, sweet content, but unfortunately, I got an "Invalid Cert" error. Sad trombone.
I double-checked Hashnode's documentation. They even specifically say that they handle SSL. During my frustrated clicking around, I navigated to soberterrain.com again. This time, voila, a valid certificate.
How could this be?!
First, why did I get an error the first time? I realized there is a short delay between the first time someone visits a new domain hosted at Hashnode and certificate issuance. That's why I got an error the first time and success later. Perhaps a documentation oversight, but nbd.
Second, how Hashnode created a cert without a TXT record? Examining the cert, the provider is Let's Encrypt. Their documentation describes the TLS-ALPN-01 challenge type.
What is TLS-ALPN-01? It's a challenge type that debuted in 2019. According to RFC 8737 "The [certificate provider] server validates control of the domain name by connecting to a TLS server at one of the addresses resolved for the domain name and verifying that a certificate with specific content is presented."
In my example, Hashnode sent a certificate signing request (CSR) to the certificate provider (Let's Encrypt). It basically says, "Hey Let's Encrypt. Can I get a cert for soberterrain.com?" Let's Encrypt looked up the domain (soberterrain.com) in DNS. My DNS host (AWS) used the A record I created to respond with the IP address for Hashnode's server. Let's Encrypt reached out to that Hashnode server and asked a few questions to validate the request. When satisfied, it issued the cert. soberterrain.com.
A Little More Detail
Since god knows I love details. When Let's Encrypt contacts Hashnode, how does Hashnode know which of its many blogs to validate? That is, Hashnode hosts many blogs from the 76.76.21.21. When Let's Encrypt comes knocking, who should answer the door? Well, the RFC specifies that the certificate provider must use Server Name Indication (SNI). Doing so, Let's Encrypt basically says, "Knock. Knock. Is soberterrain at home?" From that, Hashnode can look up the correct response.
So there you have it! An in-depth look at how Hashnode and Let's Encrypt work together to ensure your blog is not just easily accessible, but also secure. And all this magic happens without needing to manually add a TXT record to your DNS."