Writing new DNS provider modules for Caddy

Caddy 2 uses a new set of interfaces for its DNS provider APIs. While there is a shim to use all the existing old ones for now, the new APIs offer better performance, leaner builds, and more capabilities. We want all providers to be ported over to the new APIs as soon as possible.

Since I do not have accounts with all DNS providers in the world, it’s up to the community to migrate to the new APIs and to maintain their implementations. This post will show you how! :mortar_board:

For what it’s worth, I was able to implement the Cloudflare package using only the Go standard library in just about a day. It shouldn’t take you too long! :smiley:


The new interfaces/APIs are called libdns. You should at least skim over its README.

Writing a new dns.providers module

Writing a new DNS provider module for Caddy has two main steps:

  1. Create a libdns package that implements the DNS provider using the libdns APIs. There are instructions and tips in that repository’s wiki. This is the code that actually manipulates DNS records with your DNS provider, but this code does not know about (import) Caddy or any ACME libraries whatsoever. Here is a libdns template repository you can start with.

  2. Create a caddy-dns package that turns your libdns package into a Caddy module. This consists of a very simple Go module that has 20 lines (but for full support including Caddyfile, it’s a bit longer). Here is a caddy-dns template repository you can start with.

Once you confirm it works with Caddy, let’s get it added to the caddy-dns organization so others can use it.

The libdns APIs are ideal for Caddy because they result in better performance, significantly less bloat, more capacity for growth, and more flexibility (they can be used for more than just solving ACME challenges; for example, a dynamic DNS app can use them to update A/AAAA records).

Thanks for contributing to the project!


What if the DNS provider is not a full-fledged DNS provider like Route53? We’re using acme-dns and the API only allows one thing: to add/update the _acme-challenge record. IMO it doesn’t make much sense to implement a libdns provider for this, a caddy-dns package would be enough, right?

Looking through the code I saw that libdns.RecordAppender and libdns.RecordDeleter are the only interfaces required to implement this.

Those are the only two methods used by the DNS challenge solver currently; so I would recommend to just implement those methods the best you can, and return an error if your implementation does not support something the caller is trying to do.

So, it looks like I have to know how to write something in Go to create a libdns provider. Is that true?

Yes, it has to be written in Go. :slight_smile:

How hard would it be for someone who’s never used Go?

Probably not too hard. Go is a relatively easy language to learn. Start here! A Tour of Go - the Go tour is the quickest way to pick up the basics of Go. Then you can use existing provider implementations as a template.

1 Like

Thanks :slightly_smiling_face:

My code:GitHub - lscgzwd/caddy-dnspod
I want to push to : caddy-dns/dnspod

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.