diff --git a/cmd/flags.go b/cmd/flags.go index cd21c466bb..dd9fb74630 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -113,6 +113,10 @@ func CreateFlags(defaultPath string) []cli.Flag { Name: "dns.disable-cp", Usage: "By setting this flag to true, disables the need to await propagation of the TXT record to all authoritative name servers.", }, + &cli.DurationFlag{ + Name: "dns.propagation-wait", + Usage: "By setting this flag, disables all the propagation checks and uses a wait duration instead.", + }, &cli.StringSliceFlag{ Name: "dns.resolvers", Usage: "Set the resolvers to use for performing (recursive) CNAME resolving and apex domain determination." + diff --git a/cmd/setup_challenges.go b/cmd/setup_challenges.go index 719f8dd6cf..271779f9b9 100644 --- a/cmd/setup_challenges.go +++ b/cmd/setup_challenges.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "net" "strings" "time" @@ -38,7 +39,10 @@ func setupChallenges(ctx *cli.Context, client *lego.Client) { } if ctx.IsSet("dns") { - setupDNS(ctx, client) + err := setupDNS(ctx, client) + if err != nil { + log.Fatal(err) + } } } @@ -113,22 +117,40 @@ func setupTLSProvider(ctx *cli.Context) challenge.Provider { } } -func setupDNS(ctx *cli.Context, client *lego.Client) { +func setupDNS(ctx *cli.Context, client *lego.Client) error { + if ctx.IsSet("dns.disable-cp") && ctx.Bool("dns.disable-cp") && ctx.IsSet("dns.propagation-wait") { + return errors.New("'dns.disable-cp' and 'dns.propagation-wait' are mutually exclusive") + } + + wait := ctx.Duration("dns.propagation-wait") + if wait < 0 { + return errors.New("'dns.propagation-wait' cannot be negative") + } + provider, err := dns.NewDNSChallengeProviderByName(ctx.String("dns")) if err != nil { - log.Fatal(err) + return err } servers := ctx.StringSlice("dns.resolvers") + err = client.Challenge.SetDNS01Provider(provider, dns01.CondOption(len(servers) > 0, dns01.AddRecursiveNameservers(dns01.ParseNameservers(ctx.StringSlice("dns.resolvers")))), + dns01.CondOption(ctx.Bool("dns.disable-cp"), dns01.DisableCompletePropagationRequirement()), + + dns01.CondOption(ctx.IsSet("dns.propagation-wait"), dns01.WrapPreCheck( + func(domain, fqdn, value string, check dns01.PreCheckFunc) (bool, error) { + time.Sleep(wait) + return true, nil + }, + )), + dns01.CondOption(ctx.IsSet("dns-timeout"), dns01.AddDNSTimeout(time.Duration(ctx.Int("dns-timeout"))*time.Second)), ) - if err != nil { - log.Fatal(err) - } + + return err } diff --git a/docs/data/zz_cli_help.toml b/docs/data/zz_cli_help.toml index 7b88974db8..13f291bb75 100644 --- a/docs/data/zz_cli_help.toml +++ b/docs/data/zz_cli_help.toml @@ -40,6 +40,7 @@ GLOBAL OPTIONS: --tls.port value Set the port and interface to use for TLS-ALPN-01 based challenges to listen on. Supported: interface:port or :port. (default: ":443") --dns value Solve a DNS-01 challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage. --dns.disable-cp By setting this flag to true, disables the need to await propagation of the TXT record to all authoritative name servers. (default: false) + --dns.propagation-wait value By setting this flag, disables all the propagation checks and uses a wait duration instead. (default: 0s) --dns.resolvers value [ --dns.resolvers value ] Set the resolvers to use for performing (recursive) CNAME resolving and apex domain determination. For DNS-01 challenge verification, the authoritative DNS server is queried directly. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined. --http-timeout value Set the HTTP timeout value to a specific value in seconds. (default: 0) --dns-timeout value Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name server queries. (default: 10)