Skip to content

Commit 4e8d9a4

Browse files
committed
Add IPv6 nameserver to the internal DNS's upstreams.
When configuring the internal DNS resolver - rather than keep IPv6 nameservers read from the host's resolv.conf in the container's resolv.conf, treat them like IPv4 addresses and use them as upstream resolvers. For IPv6 nameservers, if there's a zone identifier in the address or the container itself doesn't have IPv6 support, mark the upstream addresses for use in the host's network namespace. Signed-off-by: Rob Murray <[email protected]>
1 parent 137a9d6 commit 4e8d9a4

11 files changed

Lines changed: 75 additions & 80 deletions

libnetwork/internal/resolvconf/resolvconf.go

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ func (rc *ResolvConf) TransformForLegacyNw(ipv6 bool) {
237237
// use in a network sandbox that has an internal DNS resolver.
238238
// - Add internalNS as a nameserver.
239239
// - Remove other nameservers, stashing them as ExtNameServers for the
240-
// internal resolver to use. (Apart from IPv6 nameservers, if keepIPv6.)
240+
// internal resolver to use.
241241
// - Mark ExtNameServers that must be used in the host namespace.
242242
// - If no ExtNameServer addresses are found, use the defaults.
243243
// - Return an error if an "ndots" option inherited from the host's config, or
@@ -246,7 +246,7 @@ func (rc *ResolvConf) TransformForLegacyNw(ipv6 bool) {
246246
// option includes a ':', and an option with a matching prefix exists, it
247247
// is not modified.
248248
func (rc *ResolvConf) TransformForIntNS(
249-
keepIPv6 bool,
249+
ipv6 bool,
250250
internalNS netip.Addr,
251251
reqdOptions []string,
252252
) ([]ExtDNSEntry, error) {
@@ -256,38 +256,24 @@ func (rc *ResolvConf) TransformForIntNS(
256256
// internal nameserver.
257257
rc.md.ExtNameServers = nil
258258
for _, addr := range rc.nameServers {
259-
// The internal resolver only uses IPv4 addresses so, keep IPv6 nameservers in
260-
// the container's file if keepIPv6, else drop them.
261-
if addr.Is6() {
262-
if keepIPv6 {
263-
newNSs = append(newNSs, addr)
264-
}
265-
} else {
266-
// Extract this NS. Mark loopback addresses that did not come from an override as
267-
// 'HostLoopback'. Upstream requests for these servers will be made in the host's
268-
// network namespace. (So, '--dns 127.0.0.53' means use a nameserver listening on
269-
// the container's loopback interface. But, if the host's resolv.conf contains
270-
// 'nameserver 127.0.0.53', the host's resolver will be used.)
271-
//
272-
// TODO(robmry) - why only loopback addresses?
273-
// Addresses from the host's resolv.conf must be usable in the host's namespace,
274-
// and a lookup from the container's namespace is more expensive? And, for
275-
// example, if the host has a nameserver with an IPv6 LL address with a zone-id,
276-
// it won't work from the container's namespace (now, while the address is left in
277-
// the container's resolv.conf, or in future for the internal resolver).
278-
rc.md.ExtNameServers = append(rc.md.ExtNameServers, ExtDNSEntry{
279-
Addr: addr,
280-
HostLoopback: addr.IsLoopback() && !rc.md.NSOverride,
281-
})
282-
}
259+
// Extract this NS. Mark addresses that did not come from an override, but will
260+
// definitely not work in the container's namespace as 'HostLoopback'. Upstream
261+
// requests for these servers will be made in the host's network namespace. (So,
262+
// '--dns 127.0.0.53' means use a nameserver listening on the container's
263+
// loopback interface. But, if the host's resolv.conf contains 'nameserver
264+
// 127.0.0.53', the host's resolver will be used.)
265+
rc.md.ExtNameServers = append(rc.md.ExtNameServers, ExtDNSEntry{
266+
Addr: addr,
267+
HostLoopback: !rc.md.NSOverride && (addr.IsLoopback() || (addr.Is6() && !ipv6) || addr.Zone() != ""),
268+
})
283269
}
284270
rc.nameServers = newNSs
285271

286272
// If there are no external nameservers, and the only nameserver left is the
287273
// internal resolver, use the defaults as ext nameservers.
288274
if len(rc.md.ExtNameServers) == 0 && len(rc.nameServers) == 1 {
289275
log.G(context.TODO()).Info("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers")
290-
for _, addr := range defaultNSAddrs(keepIPv6) {
276+
for _, addr := range defaultNSAddrs(ipv6) {
291277
rc.md.ExtNameServers = append(rc.md.ExtNameServers, ExtDNSEntry{Addr: addr})
292278
}
293279
rc.md.UsedDefaultNS = true

libnetwork/internal/resolvconf/resolvconf_test.go

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -351,16 +351,22 @@ func TestRCTransformForIntNS(t *testing.T) {
351351
expExtServers: []ExtDNSEntry{mke("10.0.0.1", false)},
352352
},
353353
{
354-
name: "IPv4 and IPv6, ipv6 enabled",
355-
input: "nameserver 10.0.0.1\nnameserver fdb6:b8fe:b528::1",
356-
ipv6: true,
357-
expExtServers: []ExtDNSEntry{mke("10.0.0.1", false)},
354+
name: "IPv4 and IPv6, ipv6 enabled",
355+
input: "nameserver 10.0.0.1\nnameserver fdb6:b8fe:b528::1",
356+
ipv6: true,
357+
expExtServers: []ExtDNSEntry{
358+
mke("10.0.0.1", false),
359+
mke("fdb6:b8fe:b528::1", false),
360+
},
358361
},
359362
{
360-
name: "IPv4 and IPv6, ipv6 disabled",
361-
input: "nameserver 10.0.0.1\nnameserver fdb6:b8fe:b528::1",
362-
ipv6: false,
363-
expExtServers: []ExtDNSEntry{mke("10.0.0.1", false)},
363+
name: "IPv4 and IPv6, ipv6 disabled",
364+
input: "nameserver 10.0.0.1\nnameserver fdb6:b8fe:b528::1",
365+
ipv6: false,
366+
expExtServers: []ExtDNSEntry{
367+
mke("10.0.0.1", false),
368+
mke("fdb6:b8fe:b528::1", true),
369+
},
364370
},
365371
{
366372
name: "IPv4 localhost",
@@ -384,37 +390,46 @@ func TestRCTransformForIntNS(t *testing.T) {
384390
expExtServers: []ExtDNSEntry{mke("127.0.0.53", true)},
385391
},
386392
{
387-
name: "IPv6 addr, IPv6 enabled",
388-
input: "nameserver fd14:6e0e:f855::1",
389-
ipv6: true,
390-
// Note that there are no ext servers in this case, the internal resolver
391-
// will only look up container names. The default nameservers aren't added
392-
// because the host's IPv6 nameserver remains in the container's resolv.conf,
393-
// (because only IPv4 ext servers are currently allowed).
393+
name: "IPv6 addr, IPv6 enabled",
394+
input: "nameserver fd14:6e0e:f855::1",
395+
ipv6: true,
396+
expExtServers: []ExtDNSEntry{mke("fd14:6e0e:f855::1", false)},
394397
},
395398
{
396-
name: "IPv4 and IPv6 localhost, IPv6 disabled",
397-
input: "nameserver 127.0.0.53\nnameserver ::1",
398-
ipv6: false,
399-
expExtServers: []ExtDNSEntry{mke("127.0.0.53", true)},
399+
name: "IPv4 and IPv6 localhost, IPv6 disabled",
400+
input: "nameserver 127.0.0.53\nnameserver ::1",
401+
ipv6: false,
402+
expExtServers: []ExtDNSEntry{
403+
mke("127.0.0.53", true),
404+
mke("::1", true),
405+
},
400406
},
401407
{
402-
name: "IPv4 and IPv6 localhost, ipv6 enabled",
403-
input: "nameserver 127.0.0.53\nnameserver ::1",
404-
ipv6: true,
405-
expExtServers: []ExtDNSEntry{mke("127.0.0.53", true)},
408+
name: "IPv4 and IPv6 localhost, ipv6 enabled",
409+
input: "nameserver 127.0.0.53\nnameserver ::1",
410+
ipv6: true,
411+
expExtServers: []ExtDNSEntry{
412+
mke("127.0.0.53", true),
413+
mke("::1", true),
414+
},
406415
},
407416
{
408-
name: "IPv4 localhost, IPv6 private, IPv6 enabled",
409-
input: "nameserver 127.0.0.53\nnameserver fd3e:2d1a:1f5a::1",
410-
ipv6: true,
411-
expExtServers: []ExtDNSEntry{mke("127.0.0.53", true)},
417+
name: "IPv4 localhost, IPv6 private, IPv6 enabled",
418+
input: "nameserver 127.0.0.53\nnameserver fd3e:2d1a:1f5a::1",
419+
ipv6: true,
420+
expExtServers: []ExtDNSEntry{
421+
mke("127.0.0.53", true),
422+
mke("fd3e:2d1a:1f5a::1", false),
423+
},
412424
},
413425
{
414-
name: "IPv4 localhost, IPv6 private, IPv6 disabled",
415-
input: "nameserver 127.0.0.53\nnameserver fd3e:2d1a:1f5a::1",
416-
ipv6: false,
417-
expExtServers: []ExtDNSEntry{mke("127.0.0.53", true)},
426+
name: "IPv4 localhost, IPv6 private, IPv6 disabled",
427+
input: "nameserver 127.0.0.53\nnameserver fd3e:2d1a:1f5a::1",
428+
ipv6: false,
429+
expExtServers: []ExtDNSEntry{
430+
mke("127.0.0.53", true),
431+
mke("fd3e:2d1a:1f5a::1", true),
432+
},
418433
},
419434
{
420435
name: "No host nameserver, no iv6",
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
nameserver 127.0.0.11
22

33
# Based on host file: '/etc/resolv.conf' (internal resolver)
4-
# ExtServers: [10.0.0.1]
4+
# ExtServers: [10.0.0.1 host(fdb6:b8fe:b528::1)]
55
# Overrides: []
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
nameserver 127.0.0.11
2-
nameserver fdb6:b8fe:b528::1
32

43
# Based on host file: '/etc/resolv.conf' (internal resolver)
5-
# ExtServers: [10.0.0.1]
4+
# ExtServers: [10.0.0.1 fdb6:b8fe:b528::1]
65
# Overrides: []
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
nameserver 127.0.0.11
22

33
# Based on host file: '/etc/resolv.conf' (internal resolver)
4-
# ExtServers: [host(127.0.0.53)]
4+
# ExtServers: [host(127.0.0.53) host(::1)]
55
# Overrides: []
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
nameserver 127.0.0.11
2-
nameserver ::1
32

43
# Based on host file: '/etc/resolv.conf' (internal resolver)
5-
# ExtServers: [host(127.0.0.53)]
4+
# ExtServers: [host(127.0.0.53) host(::1)]
65
# Overrides: []
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
nameserver 127.0.0.11
22

33
# Based on host file: '/etc/resolv.conf' (internal resolver)
4-
# ExtServers: [host(127.0.0.53)]
4+
# ExtServers: [host(127.0.0.53) host(fd3e:2d1a:1f5a::1)]
55
# Overrides: []
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
nameserver 127.0.0.11
2-
nameserver fd3e:2d1a:1f5a::1
32

43
# Based on host file: '/etc/resolv.conf' (internal resolver)
5-
# ExtServers: [host(127.0.0.53)]
4+
# ExtServers: [host(127.0.0.53) fd3e:2d1a:1f5a::1]
65
# Overrides: []
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
nameserver 127.0.0.11
2-
nameserver fd14:6e0e:f855::1
32

43
# Based on host file: '/etc/resolv.conf' (internal resolver)
4+
# ExtServers: [fd14:6e0e:f855::1]
55
# Overrides: []

libnetwork/libnetwork_linux_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1838,7 +1838,7 @@ func TestResolvConf(t *testing.T) {
18381838
makeNet: makeTestIPv6Network,
18391839
delNet: true,
18401840
originResolvConf: "search pommesfrites.fr\nnameserver 12.34.56.78\nnameserver 2001:4860:4860::8888\n",
1841-
expResolvConf: "nameserver 127.0.0.11\nnameserver 2001:4860:4860::8888\nsearch pommesfrites.fr\noptions ndots:0",
1841+
expResolvConf: "nameserver 127.0.0.11\nsearch pommesfrites.fr\noptions ndots:0",
18421842
},
18431843
{
18441844
name: "host network",

0 commit comments

Comments
 (0)