From ea2b0d39594b33e2759e4bdc9f0bd8e82c60e9b0 Mon Sep 17 00:00:00 2001 From: Jacob Peddicord Date: Tue, 29 Dec 2020 11:01:32 -0800 Subject: [PATCH 1/5] Allow domain overrides for challenge delegation For more information, see https://github.com/libdns/duckdns/pull/1 This commit adds Caddyfile parsing for an `override_domain` directive. --- duckdns.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/duckdns.go b/duckdns.go index 5d62216..2ebaebe 100644 --- a/duckdns.go +++ b/duckdns.go @@ -25,6 +25,7 @@ func (Provider) CaddyModule() caddy.ModuleInfo { // // duckdns [] { // api_token +// override_domain // } // func (p *Provider) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { @@ -39,6 +40,9 @@ func (p *Provider) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for nesting := d.Nesting(); d.NextBlock(nesting); { switch d.Val() { case "api_token": + if !d.NextArg() { + return d.ArgErr() + } if p.Provider.APIToken != "" { return d.Err("API token already set") } @@ -46,6 +50,17 @@ func (p *Provider) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { if d.NextArg() { return d.ArgErr() } + case "override_domain": + if !d.NextArg() { + return d.ArgErr() + } + if p.Provider.OverrideDomain != "" { + return d.Err("Override domain already set") + } + p.Provider.OverrideDomain = repl.ReplaceAll(d.Val(), "") + if d.NextArg() { + return d.ArgErr() + } default: return d.Errf("unrecognized subdirective '%s'", d.Val()) } From 230385ea9bebbb8983071131d771c9e26a1a1987 Mon Sep 17 00:00:00 2001 From: Jacob Peddicord Date: Tue, 29 Dec 2020 11:18:15 -0800 Subject: [PATCH 2/5] Update README describing challenge delegation --- README.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ef0c0e0..971864b 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ dns.providers.duckdns To use this module for the ACME DNS challenge, [configure the ACME issuer in your Caddy JSON](https://caddyserver.com/docs/json/apps/tls/automation/policies/issuer/acme/) like so: -``` +```json { "module": "acme", "challenges": { @@ -31,7 +31,7 @@ or with the Caddyfile: ``` tls { - dns cloudflare {env.DUCKDNS_API_TOKEN} + dns duckdns {env.DUCKDNS_API_TOKEN} } ``` @@ -41,3 +41,29 @@ You can replace `{env.DUCKDNS_API_TOKEN}` with the actual auth token if you pref ## Authenticating See [the associated README in the libdns package](https://github.com/libdns/duckdns) for important information about credentials. Your token can be found at the top of the page when logged in at https://www.duckdns.org. + +## Challenge delegation + +To obtain a certificate using ACME DNS challenges, you'd use this module as described above. But, if you have a different domain (say, `my.example.com`) CNAME'd to your Duck DNS domain, you have two options: + +1. Not use this module: Use a module matching the DNS provider for `my.example.com`. +2. [Delegate the challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) to Duck DNS. + +Delegating the challenge is actually quite easy, and may be useful if the DNS provider for `my.example.com` is difficult to configure or slow: + +> Since Let’s Encrypt follows the DNS standards when looking up TXT records for DNS-01 validation, you can use CNAME records or NS records to delegate answering the challenge to other DNS zones. This can be used to delegate the _acme-challenge subdomain to a validation-specific server or zone. It can also be used if your DNS provider is slow to update, and you want to delegate to a quicker-updating server. + +Let's say you have `my.example.com` as a CNAME to `example.duckdns.org`. Following the above instructions, you'd want to add a CNAME from `_acme-challenge.my.example.com` to `example.duckdns.org`. Then, in your Caddyfile, instruct this module to override the domain used when communicating with Duck DNS' API: + +``` +my.example.com { + tls { + dns duckdns { + override_domain example.duckdns.org + } + } + ... +} +``` + +If you do not set `override_domain`, this module will attempt to ask Duck DNS to update `my.example.com`. Duck DNS will return an error, because it does not know about `my.example.com`. Setting this value fixes this up and allows Caddy to ask for a certificate matching `my.example.com`, but by performing DNS challenges on `example.duckdns.org` instead! \ No newline at end of file From 6598c7bd55223827f20c772a07a90346ad0ca93e Mon Sep 17 00:00:00 2001 From: Jacob Peddicord Date: Tue, 29 Dec 2020 11:32:37 -0800 Subject: [PATCH 3/5] Add full definition to README --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 971864b..5308109 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,18 @@ This package contains a DNS provider module for [Caddy](https://github.com/caddy dns.providers.duckdns ``` +## Caddyfile definition + +``` +duckdns [] { + api_token + override_domain +} +``` + +`api_token` may be specified as an argument to the `duckdns` directive, or in the body. +`override_domain` is optional; see "Challenge delegation" below. + ## Config examples To use this module for the ACME DNS challenge, [configure the ACME issuer in your Caddy JSON](https://caddyserver.com/docs/json/apps/tls/automation/policies/issuer/acme/) like so: @@ -20,7 +32,8 @@ To use this module for the ACME DNS challenge, [configure the ACME issuer in you "dns": { "provider": { "name": "duckdns", - "api_token": "YOUR_DUCKDNS_API_TOKEN" + "api_token": "YOUR_DUCKDNS_API_TOKEN", + "override_domain": "OPTIONAL_DUCKDNS_DOMAIN" } } } From 7cc1e7d42414f594e7ef4adbd426e9f4d02cdb6d Mon Sep 17 00:00:00 2001 From: Jacob Peddicord Date: Tue, 29 Dec 2020 11:36:58 -0800 Subject: [PATCH 4/5] Update README.md formatting Co-authored-by: Francis Lavoie --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5308109..3eb7c85 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ duckdns [] { } ``` -`api_token` may be specified as an argument to the `duckdns` directive, or in the body. -`override_domain` is optional; see "Challenge delegation" below. +- `api_token` may be specified as an argument to the `duckdns` directive, or in the body. +- `override_domain` is optional; see "Challenge delegation" below. ## Config examples @@ -79,4 +79,4 @@ my.example.com { } ``` -If you do not set `override_domain`, this module will attempt to ask Duck DNS to update `my.example.com`. Duck DNS will return an error, because it does not know about `my.example.com`. Setting this value fixes this up and allows Caddy to ask for a certificate matching `my.example.com`, but by performing DNS challenges on `example.duckdns.org` instead! \ No newline at end of file +If you do not set `override_domain`, this module will attempt to ask Duck DNS to update `my.example.com`. Duck DNS will return an error, because it does not know about `my.example.com`. Setting this value fixes this up and allows Caddy to ask for a certificate matching `my.example.com`, but by performing DNS challenges on `example.duckdns.org` instead! From 4d1050285df566bbbf6e2dc08115b0d72e46ff6c Mon Sep 17 00:00:00 2001 From: Jacob Peddicord Date: Tue, 29 Dec 2020 11:38:20 -0800 Subject: [PATCH 5/5] Update README.md formatting Co-authored-by: Francis Lavoie --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3eb7c85..f194aa6 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ duckdns [] { ``` - `api_token` may be specified as an argument to the `duckdns` directive, or in the body. -- `override_domain` is optional; see "Challenge delegation" below. +- `override_domain` is optional; see [Challenge delegation](#challenge-delegation) below. ## Config examples