support detect conflict route device on macOS and linux

This commit is contained in:
wencaiwulue
2022-02-13 19:22:44 +08:00
parent bd2c2617ee
commit 7fe3c29265
9 changed files with 102 additions and 30 deletions

3
go.sum
View File

@@ -874,7 +874,6 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211111083644-e5c967477495 h1:cjxxlQm6d4kYbhpZ2ghvmI8xnq0AG+jXmzrhzfkyu5A=
golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
@@ -968,13 +967,11 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 h1:WecRHqgE09JBkh/584XIE6PMz5KKE/vER4izNUi30AQ=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=

View File

@@ -17,6 +17,7 @@ import (
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/polymorphichelpers"
"net"
"os"
"strings"
"time"
)
@@ -116,6 +117,7 @@ func (c *ConnectOptions) DoConnect() (err error) {
return err
}
c.deleteFirewallRuleAndSetupDNS(ctx)
c.detectConflictDevice()
return
}
@@ -212,6 +214,16 @@ func (c *ConnectOptions) deleteFirewallRuleAndSetupDNS(ctx context.Context) {
log.Info("dns service ok")
}
func (c *ConnectOptions) detectConflictDevice() {
tun := os.Getenv("tunName")
if len(tun) == 0 {
return
}
if err := DetectAndDisableConflictDevice(tun); err != nil {
log.Warnf("error occours while disable conflict devices, err: %v", err)
}
}
func (c *ConnectOptions) setupDNS() {
relovConf, err := dns.GetDNSServiceIPFromPod(c.clientset, c.restclient, c.config, util.TrafficManager, c.Namespace)
if err != nil {

View File

@@ -1,4 +1,4 @@
package util
package pkg
import (
"bytes"
@@ -6,7 +6,6 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
net2 "k8s.io/utils/net"
"net"
"os/exec"
"strings"
)
@@ -15,7 +14,7 @@ import (
// 2, detect conflict
// 3, disable device
func DetectAndDisableConflictDevice(origin string) error {
routeTable, err := getRouteTableByNetstat()
routeTable, err := getRouteTable()
if err != nil {
return err
}
@@ -27,17 +26,6 @@ func DetectAndDisableConflictDevice(origin string) error {
return err
}
// sudo ifconfig utun3 down
func disableDevice(conflict []string) error {
for _, dev := range conflict {
if err := exec.Command("sudo", "ifconfig", dev, "down").Run(); err != nil {
log.Errorf("can not disable interface: %s, err: %v", dev, err)
return err
}
}
return nil
}
func detectConflictDevice(origin string, routeTable map[string][]*net.IPNet) []string {
var conflict = sets.NewString()
vpnRoute := routeTable[origin]

View File

@@ -1,4 +1,4 @@
package util
package pkg
import (
"fmt"
@@ -84,7 +84,7 @@ func removeEmptyElement(message *route.RouteMessage) []route.Addr {
}
func TestGetRouteTableByNetstat(t *testing.T) {
routeTable, err := getRouteTableByNetstat()
routeTable, err := getRouteTable()
if err != nil {
return
}

View File

@@ -1,7 +1,7 @@
//go:build !amd64 && !arm64
// +build !amd64,!arm64
package util
package pkg
import (
"golang.org/x/net/route"

View File

@@ -1,13 +1,32 @@
package util
//go:build darwin
// +build darwin
package pkg
import (
log "github.com/sirupsen/logrus"
"net"
"os/exec"
"strconv"
"strings"
)
func getRouteTableByNetstat() (map[string][]*net.IPNet, error) {
// sudo ifconfig utun3 down
func disableDevice(conflict []string) error {
for _, dev := range conflict {
if err := exec.Command("sudo", "ifconfig", dev, "down").Run(); err != nil {
log.Errorf("can not disable interface: %s, err: %v", dev, err)
return err
} else {
rollbackFuncList = append(rollbackFuncList, func() {
_ = exec.Command("sudo", "ifconfig", dev, "up").Run()
})
}
}
return nil
}
func getRouteTable() (map[string][]*net.IPNet, error) {
output, err := exec.Command("netstat", "-anr").CombinedOutput()
if err != nil {
return nil, err

48
pkg/route_table_linux.go Normal file
View File

@@ -0,0 +1,48 @@
//go:build !windows || ignore || !darwin
// +build !windows ignore !darwin
package pkg
import (
"net"
"os/exec"
"strings"
)
func getRouteTable() (map[string][]*net.IPNet, error) {
output, err := exec.Command("route", "-n").CombinedOutput()
if err != nil {
return nil, err
}
split := strings.Split(string(output), "\n")
routeTable := make(map[string][]*net.IPNet)
for _, i := range split {
fields := strings.Fields(i)
if len(fields) >= 8 {
dst := net.ParseIP(fields[0])
mask := make(net.IPMask, net.IPv4len)
copy(mask, net.ParseIP(fields[2]))
eth := fields[7]
if v, ok := routeTable[eth]; ok {
routeTable[eth] = append(v, &net.IPNet{IP: dst, Mask: mask})
} else {
routeTable[eth] = []*net.IPNet{{IP: dst, Mask: mask}}
}
}
}
return routeTable, nil
}
func disableDevice(list []string) error {
for _, dev := range list {
if err := exec.Command("sudo", "ifconfig", dev, "down").Run(); err != nil {
return err
} else {
rollbackFuncList = append(rollbackFuncList, func() {
_ = exec.Command("sudo", "ifconfig", dev, "up").Run()
})
}
}
return nil
}

View File

@@ -0,0 +1,16 @@
//go:build windows
// +build windows
package pkg
import (
"net"
)
func getRouteTable() (map[string][]*net.IPNet, error) {
return make(map[string][]*net.IPNet), nil
}
func disableDevice(list []string) error {
return nil
}

View File

@@ -4,10 +4,8 @@ import (
"errors"
log "github.com/sirupsen/logrus"
"github.com/songgao/water"
"github.com/wencaiwulue/kubevpn/util"
"net"
"os"
"runtime"
"time"
)
@@ -39,12 +37,6 @@ func Listener(config Config) (net.Listener, error) {
if err != nil {
return nil, err
}
// todo optimize it
if runtime.GOOS == "darwin" {
if err = util.DetectAndDisableConflictDevice(ifce.Name); err != nil {
log.Warnf("error occours while disable conflict devices, err: %v", err)
}
}
ln.addr = conn.LocalAddr()