During the foray into fixing up the Let's Encrypt root certificate expiration bits for my affected bot host, while using the helpful SSL Server Test tool, I discovered the "new" (not really new) Certificate Authority Authorization (CAA) DNS record.
I won't go into detail about what CAA is (Let's Encrypt and Qualys already do a fine job with those details) beyond the basic premise: A DNS record to restrict (or ensure) only certain CA's can issue certificates for a given domain. This is another helpful step in tightening up security, but a non-compliant CA can still issue certificates so it's also one of a larger set of steps one might take to button-up your domain and host security.
Setting It Up
Since I exclusively use Let's Encrypt for my own stuff, this is an easy setup. But having never created a CAA record before, I needed a pointer. Fortunately there's a fun tool from SSLMate to do just that. Follow the prompts (I used Auto-Generate Policy) and enter a few details, and you'll get several examples of how your zone file should appear. In particular, the "Generic" output told me exactly what I needed to know:
Name Type Value
host.org. CAA 0 issue "letsencrypt.org"
0 iodef "mailto:firstname.lastname@example.org"
Heading over to my DNS manager, I can easily add the primary
Because I also want to see any reports for wonkiness, I also add the
DNS Record Verification
Since these are new records on an experimental host (hence the obfuscation to the fictitious
host.org), they will show up in DNS quickly since they're not already cached somewhere. Hopping over into WSL, I quickly run the
$ dig host.org CAA
; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> host.org CAA
;; QUESTION SECTION:
;host.org. IN CAA
;; ANSWER SECTION:
host.org. 3600 IN CAA 0 issue "letsencrypt.org"
host.org. 3600 IN CAA 0 iodef "mailto:email@example.com"
If you run another scan with the SSL Server Test tool, you'll also see that the DNS CAA section now contains the same information:
Does It Work?
The next step is to actually renew a certificate for a subdomain on the fictitious host.org domain, which I do with my standard Let's Encrypt/certbot process, the output of which is below:
Generating certificate for test.host.org...
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for test.host.org
Waiting for verification...
Cleaning up challenges
- Congratulations! Your certificate and chain have been saved at:
Your key file has been saved at:
Your cert will expire on 2022-01-24. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
Things show up just as I'd expect (and how they have in the past) given the host domain is allowed to obtain certificates from the Let's Encrypt CA. Woohoo!
The rest of the certificate installation process is unchanged, because it is unaffected by the presence of CAA.
My next steps are to roll this out to many/most/all of my other domains, specifically those exclusively using the Let's Encrypt CA. Since this test was super easy to implement, it seems a bit of a no-brainer to roll out more widely.
So, Why Bother Again?
Good question. CAA is not required, and a bad CA could still issue a certificate for the domain but having the records in place as noted would help identify bad actors or weird situations that need evaluation. It's just one piece of the larger system, and a common good. Bonus: it's not at all difficult to implement!