NameCheap with ACME-DNS Provider

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.

6 Likes

Very interesting. So if you transfer Namecheap DNS elsewhere like AWS I assume this problem you mentioned goes away? Am I correct?

My apologies, @AllenSR, for such a long delay in my response. For some reason I missed the notification. Sorry about that.

If you transfer your DNS zone from NameCheap to AWS, you’ll be looking at the limitations that AWS might have. But I’m willing to say that AWS most likely has a way better API for DNS updates than NameCheap. So, on AWS, you could just use Caddy directly with its AWS module.

Regardless the DNS hosting though, I really like to use ACME-DNS, which is specifically created just for the purpose of DNS-01 challenge. You can delegate just that one single _acme-challenge DNS entry of your DNS zone to ACME-DNS, without exposing your entire DNS zone. So, whatever my DNS hosting is going to be, I think I’ll stick with ACME-DNS for DNS-01 challenge for TLS certificate issuance.

2 Likes

I accidentally went the NameCheap route before realizing how much of a hassle it’d be to set up ACME challenge negotiation, so as an alternative: I already have a DigitalOcean account, so if you do too you can use their DNS functionality with their extremely sensible API key scoping.

  • On the NameCheap side, log in and update the DNS entries for your domains to use “custom DNS” as nameserver option, and add ns1.digitalocean.com, ns2.digitalocean.com, and ns3.digitalocean.com to the list.
  • On the DigitalOcean side, log in, then go the “networking” page, open the “domains” tab, and add your NameCheap domains, pointing to whatever IP they need to point at (they don’t need to be droplet or DO-managed IPs, if you’ve got a bare IP VPS somewhere else, that’ll work just fine too).
  • Then go to the “API” page and generate an API token with “domains” scope and nothing else.

Congrats, you can now use https://github.com/caddy-dns/digitalocean with the key you just generated.

1 Like

That however completely changes the entire DNS hosting, which is not the point here. In the same fashion, you could pretty much point your entire zone to any DNS hosting, not just Digital Ocean.

I do however prefer to use NameCheap as my DNS hosting, I do not want to move the entire zone somewhere else. I only delegate _acme-challenge record. I can use the same approach with pretty much any DNS hosting and instead of giving a server access to my entire zone, with ACME challenge I only delegate that one single DNS record, which is a more secure way.

I know, but this was literally the only post about NameCheap that I ran into while trying to make things work, so other folks may want to know they have options, too. If you want to stick with NameCheap, your post is super useful. But if someone does’t mind handing nameserver control to another service you’re already paying for, like DO, this reply might help unblock them too. Especially with namecheap’s own caddy-dns module no longer being compatible with current versions of caddy.

FWIW, the _acme-challenge CNAME method does not seem to work with Cloudflare zones - there seems to be hidden internal _acme-challenge records as part of Cloudflare issuing its own certificates that conflict with the CNAME.

You should be able to turn that off by disabling Edge Certificates in SSL/TLS settings.

Unless you need edge certificates, of course.