Lego can solve multiple ACME challenge types out of the box, but sometimes you have custom requirements.
<!--more-->
For example, you may want to write a solver for the DNS-01 challenge that works with a different DNS provider (lego already supports CloudFlare, AWS, DigitalOcean, and others).
The DNS-01 challenge is advantageous when other challenge types are impossible.
For example, the HTTP-01 challenge doesn't work well behind a load balancer or CDN and the TLS-ALPN-01 challenge breaks behind TLS termination.
But even if using HTTP-01 or TLS-ALPN-01 challenges, you may have specific needs that lego does not consider by default.
First you present a token to the ACME server in a way defined by the challenge type you're solving for, then you "clean up" after the challenge finishes.
## Writing a challenge.Provider
Pretend we want to write our own DNS-01 challenge provider (other challenge types have different requirements but the same principles apply).
This will let us prove ownership of domain names parked at a new, imaginary DNS service called BestDNS without having to start our own HTTP server.
BestDNS has an API that, given an authentication token, allows us to manipulate DNS records.
This simplistic example has only one field to store the auth token, but in reality you may need to keep more state.
```go
type DNSProviderBestDNS struct {
apiAuthToken string
}
```
We should provide a constructor that returns a *pointer* to the `struct`.
This is important in case we need to maintain state in the `struct`.
To use your new challenge provider, call [`client.Challenge.SetDNS01Provider`](https://godoc.org/github.com/go-acme/lego/challenge/resolver#SolverManager.SetDNS01Provider) to tell lego, "For this challenge, use this provider".