If you’re using NameCheap for your DNS, you probably know already that NameCheap API is quite generous when it comes to access permissions. Generous not in a good way.
With Namecheap API you can:
- Sell domains, SSL certificates etc., on your website, at any price you choose
- Integrate domain registrations with billing applications such as Modernbill and Ubersmith
- Create applications to monitor domains and send alerts
- Build custom applications to manage your domains
- And more
which is way more than what you would need or want for a simple DNS-01 challenge to issue a TLS certificate.
On top of that, there are some limitations for those who would still want to go ahead and enable API for their NameCheap account. Your account needs to meet one of the following requirements:
- have at least 20 domains under your account;
- have at least $50 on your account balance;
- have at least $50 spent within the last 2 years.
If you meet all the requirements and decide to open the gates and enable their API, there are some Caddy DNS providers out there allowing you to provide your NameCheap API username and key and manage your DNS records.
However, if you do not meet the requirements to enable NameCheap API, or you’re like me and do not want to give your Caddy server keys to the entire “kingdom”, you can still issue certificates for your NameCheap hosted DNS zone by using ACME-DNS module for Caddy. And while the following instructions are written specifically for NameCheap, you can adjust them pretty much for any DNS hosting.
In the instructions, I’m using ACME-DNS.io
but if you have your own self-hosted ACME-DNS instance and want to use that one instead, please adjust the following steps accordingly by replacing any auth.acme-dns.io
URLs with the URL of your own instance.
The documentation for the ACME-DNS module for Caddy is really good, so I’m going to focus only on the situation when you want a wildcard TLS certificate (*.example.com
) for a DNS zone example.com
hosted by NameCheap.
First of all, you need to register an account on the ACME-DNS server by making a POST request to https://auth.acme-dns.io/register
:
curl -X POST https://auth.acme-dns.io/register
The response will be a compressed JSON with your new credentials, for example:
{"username":"cad4c17d-2df8-4cb7-81eb-e0628dadb07c","password":"Xt-w1Rutv8V87UW7s6gsQjz_HufY8zq2XTPRh3lA","fulldomain":"00fd7a4e-5a73-4143-8ce7-ea4b763cd573.auth.acme-dns.io","subdomain":"00fd7a4e-5a73-4143-8ce7-ea4b763cd573","allowfrom":[]}
which you want to expand (prettify) to a more readable form:
{
"username": "cad4c17d-2df8-4cb7-81eb-e0628dadb07c",
"password": "Xt-w1Rutv8V87UW7s6gsQjz_HufY8zq2XTPRh3lA",
"fulldomain": "00fd7a4e-5a73-4143-8ce7-ea4b763cd573.auth.acme-dns.io",
"subdomain": "00fd7a4e-5a73-4143-8ce7-ea4b763cd573",
"allowfrom": []
}
Save it to a file, for example, acmedns-example.com.json
, and add an extra server_url
line. Your file should look similar to this:
{
"username": "cad4c17d-2df8-4cb7-81eb-e0628dadb07c",
"password": "Xt-w1Rutv8V87UW7s6gsQjz_HufY8zq2XTPRh3lA",
"fulldomain": "00fd7a4e-5a73-4143-8ce7-ea4b763cd573.auth.acme-dns.io",
"subdomain": "00fd7a4e-5a73-4143-8ce7-ea4b763cd573",
"server_url": "https://auth.acme-dns.io",
"allowfrom": []
}
Please notice the commas at the end of the lines. Make a note of your fulldomain
value; we will need it to configure NameCheap now.
Go to your NameCheap account, and
- in the Domain List find your
example.com
domain and click the “Manage” button - click the “Advanced DNS” tab
- click the “ADD NEW RECORD” button
Select or enter the following values for the DNS record:
- Type: CNAME Record
- Host:
_acme-challenge
- Value:
00fd7a4e-5a73-4143-8ce7-ea4b763cd573.auth.acme-dns.io
- TTL: 1 min
Obviously, use your own fulldomain
value and save the changes. That will create the following DNS entry:
_acme-challenge.example.com. 60 IN CNAME 00fd7a4e-5a73-4143-8ce7-ea4b763cd573.auth.acme-dns.io.
In other words, NameCheap now says that if anyone wants to know or do anything about _acme-challenge.example.com
, they should go to 00fd7a4e-5a73-4143-8ce7-ea4b763cd573.auth.acme-dns.io
instead, which is where our ACME-DNS account is registered. And that’s where we need to point our Caddy server now.
Edit your Caddyfile
and point *.example.com
to the file with acme-dns credentials; in our case, we named that file acmedns-example.com.json
:
example.com, *.example.com {
tls {
dns acmedns /path/to/acmedns-example.com.json
}
...
}
And that’s it! We do not need NameCheap API access at all, because we delegate _acme-challenge
DNS entries to a non-NameCheap DNS server, for which we have a working Caddy dns-provider module.
To be able to use the Caddy acmedns
provider, you need to compile your Caddy with such module:
xcaddy build --with github.com/caddy-dns/acmedns
If you run Caddy as a Docker container, you can use the following Dockerfile
to build your own Docker image:
FROM caddy:builder AS builder
RUN xcaddy build \
--with github.com/caddy-dns/acmedns
FROM caddy:latest
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
or if you’d like to run some quick tests with Caddy, acme-dns provider and NameCheap, please feel free to use my caddy-dns-acmedns Docker image. I run daily automated builds, so the image should always be using the latest version of Caddy and acmedns provider.