mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Retain V6 DNS server in resolv.conf; use only V4 servers for fallback
Signed-off-by: Santhosh Manohar <santhosh@docker.com>
This commit is contained in:
parent
a02c73c352
commit
30ef9bcf4a
6 changed files with 47 additions and 14 deletions
|
@ -1706,7 +1706,7 @@ func TestEnableIPv6(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpResolvConf := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\nnameserver 2001:4860:4860::8888\n")
|
tmpResolvConf := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\nnameserver 2001:4860:4860::8888\n")
|
||||||
expectedResolvConf := []byte("search pommesfrites.fr\nnameserver 127.0.0.11\noptions ndots:0\n")
|
expectedResolvConf := []byte("search pommesfrites.fr\nnameserver 127.0.0.11\nnameserver 2001:4860:4860::8888\noptions ndots:0\n")
|
||||||
//take a copy of resolv.conf for restoring after test completes
|
//take a copy of resolv.conf for restoring after test completes
|
||||||
resolvConfSystem, err := ioutil.ReadFile("/etc/resolv.conf")
|
resolvConfSystem, err := ioutil.ReadFile("/etc/resolv.conf")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -14,6 +14,13 @@ import (
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// constants for the IP address type
|
||||||
|
const (
|
||||||
|
IP = iota // IPv4 and IPv6
|
||||||
|
IPv4
|
||||||
|
IPv6
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrNetworkOverlapsWithNameservers preformatted error
|
// ErrNetworkOverlapsWithNameservers preformatted error
|
||||||
ErrNetworkOverlapsWithNameservers = errors.New("requested network overlaps with nameserver")
|
ErrNetworkOverlapsWithNameservers = errors.New("requested network overlaps with nameserver")
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
|
"github.com/docker/libnetwork/netutils"
|
||||||
"github.com/docker/libnetwork/resolvconf/dns"
|
"github.com/docker/libnetwork/resolvconf/dns"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,6 +30,8 @@ var (
|
||||||
localhostNSRegexp = regexp.MustCompile(`(?m)^nameserver\s+` + dns.IPLocalhost + `\s*\n*`)
|
localhostNSRegexp = regexp.MustCompile(`(?m)^nameserver\s+` + dns.IPLocalhost + `\s*\n*`)
|
||||||
nsIPv6Regexp = regexp.MustCompile(`(?m)^nameserver\s+` + ipv6Address + `\s*\n*`)
|
nsIPv6Regexp = regexp.MustCompile(`(?m)^nameserver\s+` + ipv6Address + `\s*\n*`)
|
||||||
nsRegexp = regexp.MustCompile(`^\s*nameserver\s*((` + ipv4Address + `)|(` + ipv6Address + `))\s*$`)
|
nsRegexp = regexp.MustCompile(`^\s*nameserver\s*((` + ipv4Address + `)|(` + ipv6Address + `))\s*$`)
|
||||||
|
nsIPv6Regexpmatch = regexp.MustCompile(`^\s*nameserver\s*((` + ipv6Address + `))\s*$`)
|
||||||
|
nsIPv4Regexpmatch = regexp.MustCompile(`^\s*nameserver\s*((` + ipv4Address + `))\s*$`)
|
||||||
searchRegexp = regexp.MustCompile(`^\s*search\s*(([^\s]+\s*)*)$`)
|
searchRegexp = regexp.MustCompile(`^\s*search\s*(([^\s]+\s*)*)$`)
|
||||||
optionsRegexp = regexp.MustCompile(`^\s*options\s*(([^\s]+\s*)*)$`)
|
optionsRegexp = regexp.MustCompile(`^\s*options\s*(([^\s]+\s*)*)$`)
|
||||||
)
|
)
|
||||||
|
@ -119,7 +122,7 @@ func FilterResolvDNS(resolvConf []byte, ipv6Enabled bool) (*File, error) {
|
||||||
}
|
}
|
||||||
// if the resulting resolvConf has no more nameservers defined, add appropriate
|
// if the resulting resolvConf has no more nameservers defined, add appropriate
|
||||||
// default DNS servers for IPv4 and (optionally) IPv6
|
// default DNS servers for IPv4 and (optionally) IPv6
|
||||||
if len(GetNameservers(cleanedResolvConf)) == 0 {
|
if len(GetNameservers(cleanedResolvConf, netutils.IP)) == 0 {
|
||||||
logrus.Infof("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers : %v", defaultIPv4Dns)
|
logrus.Infof("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers : %v", defaultIPv4Dns)
|
||||||
dns := defaultIPv4Dns
|
dns := defaultIPv4Dns
|
||||||
if ipv6Enabled {
|
if ipv6Enabled {
|
||||||
|
@ -151,10 +154,17 @@ func getLines(input []byte, commentMarker []byte) [][]byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNameservers returns nameservers (if any) listed in /etc/resolv.conf
|
// GetNameservers returns nameservers (if any) listed in /etc/resolv.conf
|
||||||
func GetNameservers(resolvConf []byte) []string {
|
func GetNameservers(resolvConf []byte, kind int) []string {
|
||||||
nameservers := []string{}
|
nameservers := []string{}
|
||||||
for _, line := range getLines(resolvConf, []byte("#")) {
|
for _, line := range getLines(resolvConf, []byte("#")) {
|
||||||
var ns = nsRegexp.FindSubmatch(line)
|
var ns [][]byte
|
||||||
|
if kind == netutils.IP {
|
||||||
|
ns = nsRegexp.FindSubmatch(line)
|
||||||
|
} else if kind == netutils.IPv4 {
|
||||||
|
ns = nsIPv4Regexpmatch.FindSubmatch(line)
|
||||||
|
} else if kind == netutils.IPv6 {
|
||||||
|
ns = nsIPv6Regexpmatch.FindSubmatch(line)
|
||||||
|
}
|
||||||
if len(ns) > 0 {
|
if len(ns) > 0 {
|
||||||
nameservers = append(nameservers, string(ns[1]))
|
nameservers = append(nameservers, string(ns[1]))
|
||||||
}
|
}
|
||||||
|
@ -167,7 +177,7 @@ func GetNameservers(resolvConf []byte) []string {
|
||||||
// This function's output is intended for net.ParseCIDR
|
// This function's output is intended for net.ParseCIDR
|
||||||
func GetNameserversAsCIDR(resolvConf []byte) []string {
|
func GetNameserversAsCIDR(resolvConf []byte) []string {
|
||||||
nameservers := []string{}
|
nameservers := []string{}
|
||||||
for _, nameserver := range GetNameservers(resolvConf) {
|
for _, nameserver := range GetNameservers(resolvConf, netutils.IP) {
|
||||||
nameservers = append(nameservers, nameserver+"/32")
|
nameservers = append(nameservers, nameserver+"/32")
|
||||||
}
|
}
|
||||||
return nameservers
|
return nameservers
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
|
"github.com/docker/libnetwork/netutils"
|
||||||
_ "github.com/docker/libnetwork/testutils"
|
_ "github.com/docker/libnetwork/testutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ nameserver 1.2.3.4
|
||||||
`search example.com
|
`search example.com
|
||||||
nameserver 1.2.3.4 # not 4.3.2.1`: {"1.2.3.4"},
|
nameserver 1.2.3.4 # not 4.3.2.1`: {"1.2.3.4"},
|
||||||
} {
|
} {
|
||||||
test := GetNameservers([]byte(resolv))
|
test := GetNameservers([]byte(resolv), netutils.IP)
|
||||||
if !strSlicesEqual(test, result) {
|
if !strSlicesEqual(test, result) {
|
||||||
t.Fatalf("Wrong nameserver string {%s} should be %v. Input: %s", test, result, resolv)
|
t.Fatalf("Wrong nameserver string {%s} should be %v. Input: %s", test, result, resolv)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ const (
|
||||||
ptrIPv4domain = ".in-addr.arpa."
|
ptrIPv4domain = ".in-addr.arpa."
|
||||||
ptrIPv6domain = ".ip6.arpa."
|
ptrIPv6domain = ".ip6.arpa."
|
||||||
respTTL = 1800
|
respTTL = 1800
|
||||||
|
maxExtDNS = 3 //max number of external servers to try
|
||||||
)
|
)
|
||||||
|
|
||||||
// resolver implements the Resolver interface
|
// resolver implements the Resolver interface
|
||||||
|
@ -188,15 +189,24 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
|
||||||
if len(r.extDNS) == 0 {
|
if len(r.extDNS) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("Querying ext dns %s for %s[%d]", r.extDNS[0], name, query.Question[0].Qtype)
|
|
||||||
|
|
||||||
c := &dns.Client{Net: "udp"}
|
num := maxExtDNS
|
||||||
addr := fmt.Sprintf("%s:%d", r.extDNS[0], 53)
|
if len(r.extDNS) < maxExtDNS {
|
||||||
|
num = len(r.extDNS)
|
||||||
|
}
|
||||||
|
for i := 0; i < num; i++ {
|
||||||
|
log.Debugf("Querying ext dns %s for %s[%d]", r.extDNS[i], name, query.Question[0].Qtype)
|
||||||
|
|
||||||
// TODO: iterate over avilable servers in case of error
|
c := &dns.Client{Net: "udp"}
|
||||||
resp, _, err = c.Exchange(query, addr)
|
addr := fmt.Sprintf("%s:%d", r.extDNS[i], 53)
|
||||||
if err != nil {
|
|
||||||
|
resp, _, err = c.Exchange(query, addr)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
log.Errorf("external resolution failed, %s", err)
|
log.Errorf("external resolution failed, %s", err)
|
||||||
|
}
|
||||||
|
if resp == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/libnetwork/etchosts"
|
"github.com/docker/libnetwork/etchosts"
|
||||||
|
"github.com/docker/libnetwork/netutils"
|
||||||
"github.com/docker/libnetwork/osl"
|
"github.com/docker/libnetwork/osl"
|
||||||
"github.com/docker/libnetwork/resolvconf"
|
"github.com/docker/libnetwork/resolvconf"
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
|
@ -827,7 +828,7 @@ func (sb *sandbox) setupDNS() error {
|
||||||
if len(sb.config.dnsList) > 0 || len(sb.config.dnsSearchList) > 0 || len(sb.config.dnsOptionsList) > 0 {
|
if len(sb.config.dnsList) > 0 || len(sb.config.dnsSearchList) > 0 || len(sb.config.dnsOptionsList) > 0 {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
dnsList = resolvconf.GetNameservers(currRC.Content)
|
dnsList = resolvconf.GetNameservers(currRC.Content, netutils.IP)
|
||||||
dnsSearchList = resolvconf.GetSearchDomains(currRC.Content)
|
dnsSearchList = resolvconf.GetSearchDomains(currRC.Content)
|
||||||
dnsOptionsList = resolvconf.GetOptions(currRC.Content)
|
dnsOptionsList = resolvconf.GetOptions(currRC.Content)
|
||||||
)
|
)
|
||||||
|
@ -935,7 +936,8 @@ func (sb *sandbox) rebuildDNS() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// localhost entries have already been filtered out from the list
|
// localhost entries have already been filtered out from the list
|
||||||
sb.extDNS = resolvconf.GetNameservers(currRC.Content)
|
// retain only the v4 servers in sb for forwarding the DNS queries
|
||||||
|
sb.extDNS = resolvconf.GetNameservers(currRC.Content, netutils.IPv4)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
dnsList = []string{sb.resolver.NameServer()}
|
dnsList = []string{sb.resolver.NameServer()}
|
||||||
|
@ -943,6 +945,9 @@ func (sb *sandbox) rebuildDNS() error {
|
||||||
dnsSearchList = resolvconf.GetSearchDomains(currRC.Content)
|
dnsSearchList = resolvconf.GetSearchDomains(currRC.Content)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// external v6 DNS servers has to be listed in resolv.conf
|
||||||
|
dnsList = append(dnsList, resolvconf.GetNameservers(currRC.Content, netutils.IPv6)...)
|
||||||
|
|
||||||
// Resolver returns the options in the format resolv.conf expects
|
// Resolver returns the options in the format resolv.conf expects
|
||||||
dnsOptionsList = append(dnsOptionsList, sb.resolver.ResolverOptions()...)
|
dnsOptionsList = append(dnsOptionsList, sb.resolver.ResolverOptions()...)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue