From 65cd5da42b11033010703ab7c262c7275d76b210 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Sun, 25 Jan 2026 00:54:45 +0100 Subject: [PATCH] feat: choose a network stack for challenges --- challenge/network.go | 10 +++++----- cmd/cmd_renew.go | 2 +- cmd/cmd_run.go | 10 +++++++++- cmd/flags.go | 22 ++++++++++++++++++++++ cmd/setup_challenges.go | 21 +++++++++++++++++---- 5 files changed, 54 insertions(+), 11 deletions(-) diff --git a/challenge/network.go b/challenge/network.go index 7556267e5..035d92d4f 100644 --- a/challenge/network.go +++ b/challenge/network.go @@ -3,16 +3,16 @@ package challenge type NetworkStack int const ( - dualStack NetworkStack = iota - ipv4only - ipv6only + DualStack NetworkStack = iota + IPv4Only + IPv6Only ) func (s NetworkStack) Network(proto string) string { switch s { - case ipv4only: + case IPv4Only: return proto + "4" - case ipv6only: + case IPv6Only: return proto + "6" default: return proto diff --git a/cmd/cmd_renew.go b/cmd/cmd_renew.go index 5b6650696..568559540 100644 --- a/cmd/cmd_renew.go +++ b/cmd/cmd_renew.go @@ -47,7 +47,7 @@ func createRenew() *cli.Command { log.Fatal(fmt.Sprintf("--%s only works with --%s/-d, --%s/-c doesn't support this option.", flgForceCertDomains, flgDomains, flgCSR)) } - return ctx, nil + return ctx, validateNetworkStack(cmd) }, Flags: createRenewFlags(), } diff --git a/cmd/cmd_run.go b/cmd/cmd_run.go index 5b60a1211..8583fc0d0 100644 --- a/cmd/cmd_run.go +++ b/cmd/cmd_run.go @@ -31,7 +31,7 @@ func createRun() *cli.Command { log.Fatal("Please specify --domains/-d (or --csr/-c if you already have a CSR)") } - return ctx, nil + return ctx, validateNetworkStack(cmd) }, Action: run, Flags: createRunFlags(), @@ -172,3 +172,11 @@ func newObtainForCSRRequest(cmd *cli.Command, csr *x509.CertificateRequest) cert AlwaysDeactivateAuthorizations: cmd.Bool(flgAlwaysDeactivateAuthorizations), } } + +func validateNetworkStack(cmd *cli.Command) error { + if cmd.Bool(flgIPv4Only) && cmd.Bool(flgIPv6Only) { + return fmt.Errorf("cannot specify both --%s and --%s", flgIPv4Only, flgIPv6Only) + } + + return nil +} diff --git a/cmd/flags.go b/cmd/flags.go index 13a081d36..ccf19ff3a 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -57,6 +57,12 @@ const ( flgUserAgent = "user-agent" ) +// Flag names related to the network stack. +const ( + flgIPv4Only = "ipv4only" + flgIPv6Only = "ipv6only" +) + // Flag names related to HTTP-01 challenge. const ( flgHTTP = "http" @@ -184,10 +190,26 @@ func CreateChallengesFlags() []cli.Flag { flags = append(flags, CreateHTTPChallengeFlags()...) flags = append(flags, CreateTLSChallengeFlags()...) flags = append(flags, CreateDNSChallengeFlags()...) + flags = append(flags, CreateNetworkStackFlags()...) return flags } +func CreateNetworkStackFlags() []cli.Flag { + return []cli.Flag{ + &cli.BoolFlag{ + Name: flgIPv4Only, + Aliases: []string{"4"}, + Usage: "Use IPv4 only.", + }, + &cli.BoolFlag{ + Name: flgIPv6Only, + Aliases: []string{"6"}, + Usage: "Use IPv6 only.", + }, + } +} + func CreateHTTPChallengeFlags() []cli.Flag { return []cli.Flag{ &cli.BoolFlag{ diff --git a/cmd/setup_challenges.go b/cmd/setup_challenges.go index ea0fe7c69..e804e0e2e 100644 --- a/cmd/setup_challenges.go +++ b/cmd/setup_challenges.go @@ -103,8 +103,7 @@ func setupHTTPProvider(cmd *cli.Command) challenge.Provider { } srv := http01.NewProviderServerWithOptions(http01.Options{ - // TODO(ldez): set network stack - Network: "tcp", + Network: getNetworkStack(cmd).Network("tcp"), Address: net.JoinHostPort(host, port), }) @@ -116,8 +115,7 @@ func setupHTTPProvider(cmd *cli.Command) challenge.Provider { case cmd.Bool(flgHTTP): srv := http01.NewProviderServerWithOptions(http01.Options{ - // TODO(ldez): set network stack - Network: "tcp", + Network: getNetworkStack(cmd).Network("tcp"), Address: net.JoinHostPort("", ":80"), }) @@ -187,6 +185,8 @@ func setupDNS(cmd *cli.Command, client *lego.Client) error { opts.Timeout = time.Duration(cmd.Int(flgDNSTimeout)) * time.Second } + opts.NetworkStack = getNetworkStack(cmd) + dns01.SetDefaultClient(dns01.NewClient(opts)) err = client.Challenge.SetDNS01Provider(provider, @@ -224,3 +224,16 @@ func checkPropagationExclusiveOptions(cmd *cli.Command) error { func isSetBool(cmd *cli.Command, name string) bool { return cmd.IsSet(name) && cmd.Bool(name) } + +func getNetworkStack(cmd *cli.Command) challenge.NetworkStack { + switch { + case cmd.Bool(flgIPv4Only): + return challenge.IPv4Only + + case cmd.Bool(flgIPv6Only): + return challenge.IPv6Only + + default: + return challenge.DualStack + } +}