зеркало из https://github.com/microsoft/docker.git
Merge pull request #1577 from mrallen1/fix/1502
Prevent DNS server conflicts in CreateBridgeIface
This commit is contained in:
Коммит
c22ff0296e
31
network.go
31
network.go
|
@ -76,6 +76,21 @@ func checkRouteOverlaps(networks []*net.IPNet, dockerNetwork *net.IPNet) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func checkNameserverOverlaps(nameservers []string, dockerNetwork *net.IPNet) error {
|
||||
if len(nameservers) > 0 {
|
||||
for _, ns := range nameservers {
|
||||
_, nsNetwork, err := net.ParseCIDR(ns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if networkOverlaps(dockerNetwork, nsNetwork) {
|
||||
return fmt.Errorf("%s overlaps nameserver %s", dockerNetwork, nsNetwork)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateBridgeIface creates a network bridge interface on the host system with the name `ifaceName`,
|
||||
// and attempts to configure it with an address which doesn't conflict with any other interface on the host.
|
||||
// If it can't find an address which doesn't conflict, it will return an error.
|
||||
|
@ -100,6 +115,16 @@ func CreateBridgeIface(config *DaemonConfig) error {
|
|||
"192.168.44.1/24",
|
||||
}
|
||||
|
||||
nameservers := []string{}
|
||||
resolvConf, _ := utils.GetResolvConf()
|
||||
// we don't check for an error here, because we don't really care
|
||||
// if we can't read /etc/resolv.conf. So instead we skip the append
|
||||
// if resolvConf is nil. It either doesn't exist, or we can't read it
|
||||
// for some reason.
|
||||
if resolvConf != nil {
|
||||
nameservers = append(nameservers, utils.GetNameserversAsCIDR(resolvConf)...)
|
||||
}
|
||||
|
||||
var ifaceAddr string
|
||||
for _, addr := range addrs {
|
||||
_, dockerNetwork, err := net.ParseCIDR(addr)
|
||||
|
@ -111,8 +136,10 @@ func CreateBridgeIface(config *DaemonConfig) error {
|
|||
return err
|
||||
}
|
||||
if err := checkRouteOverlaps(routes, dockerNetwork); err == nil {
|
||||
ifaceAddr = addr
|
||||
break
|
||||
if err := checkNameserverOverlaps(nameservers, dockerNetwork); err == nil {
|
||||
ifaceAddr = addr
|
||||
break
|
||||
}
|
||||
} else {
|
||||
utils.Debugf("%s: %s", addr, err)
|
||||
}
|
||||
|
|
|
@ -295,3 +295,19 @@ func TestCheckRouteOverlaps(t *testing.T) {
|
|||
t.Fatalf("10.0.2.0/24 and 10.0.2.0 should overlap but it doesn't")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckNameserverOverlaps(t *testing.T) {
|
||||
nameservers := []string{"10.0.2.3/32", "192.168.102.1/32"}
|
||||
|
||||
_, netX, _ := net.ParseCIDR("10.0.2.3/32")
|
||||
|
||||
if err := checkNameserverOverlaps(nameservers, netX); err == nil {
|
||||
t.Fatalf("%s should overlap 10.0.2.3/32 but doesn't", netX)
|
||||
}
|
||||
|
||||
_, netX, _ = net.ParseCIDR("192.168.102.2/32")
|
||||
|
||||
if err := checkNameserverOverlaps(nameservers, netX); err != nil {
|
||||
t.Fatalf("%s should not overlap %v but it does", netX, nameservers)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -903,6 +904,23 @@ func StripComments(input []byte, commentMarker []byte) []byte {
|
|||
return output
|
||||
}
|
||||
|
||||
// GetNameserversAsCIDR returns nameservers (if any) listed in
|
||||
// /etc/resolv.conf as CIDR blocks (e.g., "1.2.3.4/32")
|
||||
// This function's output is intended for net.ParseCIDR
|
||||
func GetNameserversAsCIDR(resolvConf []byte) []string {
|
||||
var parsedResolvConf = StripComments(resolvConf, []byte("#"))
|
||||
nameservers := []string{}
|
||||
re := regexp.MustCompile(`^\s*nameserver\s*(([0-9]\.){3}([0-9]))\s*$`)
|
||||
for _, line := range bytes.Split(parsedResolvConf, []byte("\n")) {
|
||||
var ns = re.FindSubmatch(line)
|
||||
if len(ns) > 0 {
|
||||
nameservers = append(nameservers, string(ns[1])+"/32")
|
||||
}
|
||||
}
|
||||
|
||||
return nameservers
|
||||
}
|
||||
|
||||
func ParseHost(host string, port int, addr string) (string, error) {
|
||||
var proto string
|
||||
switch {
|
||||
|
|
|
@ -444,3 +444,41 @@ func TestParsePortMapping(t *testing.T) {
|
|||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNameserversAsCIDR(t *testing.T) {
|
||||
for resolv, result := range map[string][]string{`
|
||||
nameserver 1.2.3.4
|
||||
nameserver 4.3.2.1
|
||||
search example.com`: {"1.2.3.4/32", "4.3.2.1/32"},
|
||||
`search example.com`: {},
|
||||
`nameserver 1.2.3.4
|
||||
search example.com
|
||||
nameserver 4.3.2.1`: []string{"1.2.3.4/32", "4.3.2.1/32"},
|
||||
``: []string{},
|
||||
` nameserver 1.2.3.4 `: []string{"1.2.3.4/32"},
|
||||
`search example.com
|
||||
nameserver 1.2.3.4
|
||||
#nameserver 4.3.2.1`: []string{"1.2.3.4/32"},
|
||||
`search example.com
|
||||
nameserver 1.2.3.4 # not 4.3.2.1`: []string{"1.2.3.4/32"},
|
||||
} {
|
||||
test := GetNameserversAsCIDR([]byte(resolv))
|
||||
if !StrSlicesEqual(test, result) {
|
||||
t.Fatalf("Wrong nameserver string {%s} should be %v. Input: %s", test, result, resolv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func StrSlicesEqual(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче