chore: nameservers option

This commit is contained in:
Fernandez Ludovic 2026-02-10 18:35:11 +01:00
commit d36b132840
3 changed files with 83 additions and 22 deletions

View file

@ -56,12 +56,7 @@ func NewClient(opts *Options) *Client {
}
if len(opts.RecursiveNameservers) == 0 {
defaultNameservers := []string{
"google-public-dns-a.google.com:53",
"google-public-dns-b.google.com:53",
}
opts.RecursiveNameservers = getNameservers(defaultResolvConf, defaultNameservers)
opts.RecursiveNameservers = getNameservers(defaultResolvConf, opts.NetworkStack)
}
if opts.Timeout == 0 {
@ -69,7 +64,7 @@ func NewClient(opts *Options) *Client {
}
return &Client{
recursiveNameservers: opts.RecursiveNameservers,
recursiveNameservers: parseNameservers(opts.RecursiveNameservers),
authoritativeNSPort: "53",
tcpClient: &dns.Client{
Net: opts.NetworkStack.Network("tcp"),

View file

@ -6,6 +6,7 @@ import (
"net"
"strings"
"github.com/go-acme/lego/v5/challenge"
"github.com/miekg/dns"
)
@ -82,13 +83,33 @@ func (c *Client) lookupAuthoritativeNameservers(ctx context.Context, fqdn string
}
// getNameservers attempts to get systems nameservers before falling back to the defaults.
func getNameservers(path string, defaults []string) []string {
func getNameservers(path string, stack challenge.NetworkStack) []string {
config, err := dns.ClientConfigFromFile(path)
if err != nil || len(config.Servers) == 0 {
return defaults
if err == nil && len(config.Servers) > 0 {
return config.Servers
}
return parseNameservers(config.Servers)
switch stack {
case challenge.IPv4Only:
return []string{
"1.1.1.1:53",
"1.0.0.1:53",
}
case challenge.IPv6Only:
return []string{
"[2606:4700:4700::1111]:53",
"[2606:4700:4700::1001]:53",
}
default:
return []string{
"1.1.1.1:53",
"1.0.0.1:53",
"[2606:4700:4700::1111]:53",
"[2606:4700:4700::1001]:53",
}
}
}
func parseNameservers(servers []string) []string {

View file

@ -4,6 +4,7 @@ import (
"sort"
"testing"
"github.com/go-acme/lego/v5/challenge"
"github.com/go-acme/lego/v5/platform/tester/dnsmock"
"github.com/miekg/dns"
"github.com/stretchr/testify/assert"
@ -185,27 +186,42 @@ func TestClient_lookupAuthoritativeNameservers_error(t *testing.T) {
}
}
func Test_getNameservers_ResolveConfServers(t *testing.T) {
func Test_getNameservers(t *testing.T) {
testCases := []struct {
fixture string
desc string
path string
stack challenge.NetworkStack
expected []string
defaults []string
}{
{
fixture: "fixtures/resolv.conf.1",
defaults: []string{"127.0.0.1:53"},
expected: []string{"10.200.3.249:53", "10.200.3.250:5353", "[2001:4860:4860::8844]:53", "[10.0.0.1]:5353"},
desc: "with resolv.conf",
path: "fixtures/resolv.conf.1",
stack: challenge.DualStack,
expected: []string{"10.200.3.249", "10.200.3.250:5353", "2001:4860:4860::8844", "[10.0.0.1]:5353"},
},
{
fixture: "fixtures/resolv.conf.nonexistant",
defaults: []string{"127.0.0.1:53"},
expected: []string{"127.0.0.1:53"},
desc: "with nonexistent resolv.conf",
path: "fixtures/resolv.conf.nonexistant",
stack: challenge.DualStack,
expected: []string{"1.0.0.1:53", "1.1.1.1:53", "[2606:4700:4700::1001]:53", "[2606:4700:4700::1111]:53"},
},
{
desc: "default with IPv4Only",
path: "resolv.conf.nonexistant",
stack: challenge.IPv4Only,
expected: []string{"1.0.0.1:53", "1.1.1.1:53"},
},
{
desc: "default with IPv6Only",
path: "resolv.conf.nonexistant",
stack: challenge.IPv6Only,
expected: []string{"[2606:4700:4700::1001]:53", "[2606:4700:4700::1111]:53"},
},
}
for _, test := range testCases {
t.Run(test.fixture, func(t *testing.T) {
result := getNameservers(test.fixture, test.defaults)
t.Run(test.desc, func(t *testing.T) {
result := getNameservers(test.path, test.stack)
sort.Strings(result)
sort.Strings(test.expected)
@ -214,3 +230,32 @@ func Test_getNameservers_ResolveConfServers(t *testing.T) {
})
}
}
func Test_parseNameservers(t *testing.T) {
testCases := []struct {
desc string
servers []string
expected []string
}{
{
desc: "without explicit port",
servers: []string{"ns1.example.com", "2001:db8::1"},
expected: []string{"ns1.example.com:53", "[2001:db8::1]:53"},
},
{
desc: "with explicit port",
servers: []string{"ns1.example.com:53", "[2001:db8::1]:53"},
expected: []string{"ns1.example.com:53", "[2001:db8::1]:53"},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
result := parseNameservers(test.servers)
assert.Equal(t, test.expected, result)
})
}
}