httpcaddyfile: Add support for DNS challenge solvers

Configuration via the Caddyfile requires use of env variables, but
an upstream issue is currently blocking that:
https://github.com/go-acme/lego/issues/1054

Providers will need to be retrofitted upstream in order to support env
var configuration.
This commit is contained in:
Matthew Holt 2020-02-08 16:52:54 -07:00
parent 98bbc54fdc
commit 17d938fc54
No known key found for this signature in database
GPG Key ID: 2A349DD577D586A5
3 changed files with 37 additions and 9 deletions

View File

@ -98,6 +98,7 @@ func parseRoot(h Helper) ([]ConfigValue, error) {
// alpn <values...>
// load <paths...>
// ca <acme_ca_endpoint>
// dns <provider_name>
// }
//
func parseTLS(h Helper) ([]ConfigValue, error) {
@ -217,6 +218,21 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
}
mgr.CA = arg[0]
// DNS provider for ACME DNS challenge
case "dns":
if !h.Next() {
return nil, h.ArgErr()
}
provName := h.Val()
if mgr.Challenges == nil {
mgr.Challenges = new(caddytls.ChallengesConfig)
}
dnsProvModule, err := caddy.GetModule("tls.dns." + provName)
if err != nil {
return nil, h.Errf("getting DNS provider module named '%s': %v", provName, err)
}
mgr.Challenges.DNSRaw = caddyconfig.JSONModuleObject(dnsProvModule.New(), "provider", provName, h.warnings)
default:
return nil, h.Errf("unknown subdirective: %s", h.Val())
}

View File

@ -71,8 +71,8 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
val, err = parseOptExperimentalHTTP3(disp)
case "storage":
val, err = parseOptStorage(disp)
case "acme_ca":
val, err = parseOptACMECA(disp)
case "acme_ca", "acme_dns":
val, err = parseOptACME(disp)
case "email":
val, err = parseOptEmail(disp)
case "admin":
@ -222,11 +222,12 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
}
}
}
// if global ACME CA or email were set, append a catch-all automation
// if global ACME CA, DNS, or email were set, append a catch-all automation
// policy that ensures they will be used if no tls directive was used
acmeCA, hasACMECA := options["acme_ca"]
acmeDNS, hasACMEDNS := options["acme_dns"]
email, hasEmail := options["email"]
if hasACMECA || hasEmail {
if hasACMECA || hasACMEDNS || hasEmail {
if tlsApp.Automation == nil {
tlsApp.Automation = new(caddytls.AutomationConfig)
}
@ -236,11 +237,22 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
if !hasEmail {
email = ""
}
tlsApp.Automation.Policies = append(tlsApp.Automation.Policies, caddytls.AutomationPolicy{
ManagementRaw: caddyconfig.JSONModuleObject(caddytls.ACMEManagerMaker{
mgr := caddytls.ACMEManagerMaker{
CA: acmeCA.(string),
Email: email.(string),
}, "module", "acme", &warnings),
}
if hasACMEDNS {
provName := acmeDNS.(string)
dnsProvModule, err := caddy.GetModule("tls.dns." + provName)
if err != nil {
return nil, warnings, fmt.Errorf("getting DNS provider module named '%s': %v", provName, err)
}
mgr.Challenges = &caddytls.ChallengesConfig{
DNSRaw: caddyconfig.JSONModuleObject(dnsProvModule.New(), "provider", provName, &warnings),
}
}
tlsApp.Automation.Policies = append(tlsApp.Automation.Policies, caddytls.AutomationPolicy{
ManagementRaw: caddyconfig.JSONModuleObject(mgr, "module", "acme", &warnings),
})
}
if tlsApp.Automation != nil {

View File

@ -162,7 +162,7 @@ func parseOptStorage(d *caddyfile.Dispenser) (caddy.StorageConverter, error) {
return storage, nil
}
func parseOptACMECA(d *caddyfile.Dispenser) (string, error) {
func parseOptACME(d *caddyfile.Dispenser) (string, error) {
d.Next() // consume parameter name
if !d.Next() {
return "", d.ArgErr()