56 lines
No EOL
3.8 KiB
Markdown
56 lines
No EOL
3.8 KiB
Markdown
+++
|
|
title = "Certbot DNS-01 hook for Namecheap"
|
|
summary = "A manual authorization hook for EFF Certbot, allowing DNS-01 challenge verification with Namecheap domains. Written in Python."
|
|
authors = ["a"]
|
|
date = 2019-10-30
|
|
tags = ["namecheap", "certbot", "dns-01", "python", "letsencrypt"]
|
|
categories = ["Code"]
|
|
aliases = [
|
|
"/code/namecheap",
|
|
]
|
|
+++
|
|
|
|
## The problem
|
|
|
|
I want to obtain Let's Encrypt certificates with wildcard subdomains, but to do so, one must prove that they own the entire domain and not just a particular subdomain. This means that the standard HTTP challenges are not enough.
|
|
|
|
I was tired of manually doing DNS-01 challenges through Namecheap's dashboard, which involved a laborious process of logging in, navigating to the domain I wanted to obtain certificates for, copying and pasting a special challenge code into a TXT record, waiting for the change to propagate, and repeating this for every single domain I owned, every three months.
|
|
|
|
## The research
|
|
|
|
Certbot plugins are available for some DNS providers, but Namecheap is not one of those. I was faced with two options: one, move to a different supported provider and transfer all of my domains. Or, two: write a script that could run as a validation hook and thus automate the whole thing.
|
|
|
|
> Certbot allows for the specification of pre and post validation hooks when run in manual mode. The flags to specify these scripts are --manual-auth-hook and --manual-cleanup-hook respectively and can be used as follows [...]
|
|
> This will run the authenticator.sh script, attempt the validation, and then run the cleanup.sh script. Additionally certbot will pass relevant environment variables to these scripts [...]
|
|
>
|
|
> -- https://certbot.eff.org/docs/using.html#pre-and-post-validation-hooks
|
|
|
|
Namecheap also [provides an API](https://www.namecheap.com/support/api/intro/) to anyone who has spent at least $50 within the last 2 years, [among other alternative requirements](https://www.namecheap.com/support/knowledgebase/article.aspx/9739/63/api--faq/#c).
|
|
|
|
## The solution
|
|
|
|
I wrote the manual auth hook found here: https://github.com/trwnh/namecheap
|
|
|
|
The hook I wrote uses Python, Requests, and BeautifulSoup. Since I just wanted the hook to work, I didn't bother over-engineering this -- this script has some limitations:
|
|
|
|
- Namecheap's API uses SLD and TLD instead of a singular domain variable. My script uses an extremely naive approach and simply splits the domain at the dot. I think this might not matter, but I haven't tested further because I don't own any domains with multipart TLDs.
|
|
- None of the API calls are paginated. This means the script only works on accounts with up to 20 domains. I own less than 20 domains, so this is not an issue for me. Also, the methods that require pagination are currently unused in the main function.
|
|
- No error checking or handling was implemented. Theoretically, the script could fail if the domain is expired or locked, but I trust myself to keep all my domains valid and registered.
|
|
- API username, key, etc. are hardcoded instead of being read from some external file. This script was written for my personal use, so I didn't bother going further.
|
|
|
|
### Logic
|
|
|
|
The pseudocode for this script is as follows:
|
|
|
|
1. Get CERTBOT_DOMAIN from Certbot.
|
|
2. Get the host records for this domain.
|
|
3. Get the CERTBOT_VALIDATION code.
|
|
4. Create a TXT host record using this challenge code.
|
|
5. Add this host record to the existing host records.
|
|
6. Upload the host records back to Namecheap.
|
|
|
|
The source code can be examined at https://github.com/trwnh/namecheap/blob/master/auth -- I made sure to leave docstrings and use clear function names, so hopefully this is good, readable code.
|
|
|
|
## The result
|
|
|
|
It works! Now, I can automate my certificate renewals instead of doing it all manually every three months. Maybe one day, I'll even write a cleanup script to delete the TXT challenge records... :) |