Browse Source

saving merge

afeiszli 3 years ago
parent
commit
c6b2e47a15

+ 1 - 0
controllers/node.go

@@ -609,6 +609,7 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
 
 func runUpdates(node *models.Node, nodeUpdate bool) error {
 	//don't publish to server node
+
 	if nodeUpdate && !isServer(node) {
 		if err := mq.NodeUpdate(node); err != nil {
 			logger.Log(1, "error publishing node update", err.Error())

+ 3 - 4
controllers/server_util.go

@@ -14,10 +14,9 @@ func runServerPeerUpdate(node *models.Node, ifaceDelta bool) error {
 	if err != nil {
 		logger.Log(3, "error occurred on timer,", err.Error())
 	}
-	if servercfg.IsMessageQueueBackend() {
-		if err := mq.PublishPeerUpdate(node); err != nil {
-			logger.Log(0, "failed to inform peers of new node ", err.Error())
-		}
+
+	if err := mq.PublishPeerUpdate(node); err != nil {
+		logger.Log(0, "failed to inform peers of new node ", err.Error())
 	}
 
 	if servercfg.IsClientMode() != "on" {

+ 8 - 4
logic/server.go

@@ -141,11 +141,11 @@ func ServerJoin(networkSettings *models.Network) (models.Node, error) {
 // ServerUpdate - updates the server
 // replaces legacy Checkin code
 func ServerUpdate(serverNode *models.Node, ifaceDelta bool) error {
-	var err = serverPull(serverNode, ifaceDelta)
+	var err = ServerPull(serverNode, ifaceDelta)
 	if isDeleteError(err) {
 		return DeleteNodeByID(serverNode, true)
 	} else if err != nil && !ifaceDelta {
-		err = serverPull(serverNode, true)
+		err = ServerPull(serverNode, true)
 		if err != nil {
 			return err
 		}
@@ -369,7 +369,11 @@ func checkNodeActions(node *models.Node) string {
 
 // == Private ==
 
-func serverPull(serverNode *models.Node, ifaceDelta bool) error {
+// ServerPull - performs a server pull
+func ServerPull(serverNode *models.Node, ifaceDelta bool) error {
+	if serverNode.IsServer != "yes" {
+		return fmt.Errorf("attempted pull from non-server node: %s - %s", serverNode.Name, serverNode.ID)
+	}
 
 	var err error
 	if serverNode.IPForwarding == "yes" {
@@ -400,7 +404,7 @@ func serverPull(serverNode *models.Node, ifaceDelta bool) error {
 	} else {
 		if err = setWGConfig(serverNode, true); err != nil {
 			if errors.Is(err, os.ErrNotExist) {
-				return serverPull(serverNode, true)
+				return ServerPull(serverNode, true)
 			} else {
 				return err
 			}

+ 3 - 1
mq/mq.go

@@ -99,7 +99,9 @@ var UpdateNode mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message)
 
 // PublishPeerUpdate --- deterines and publishes a peer update to all the peers of a node
 func PublishPeerUpdate(newNode *models.Node) error {
-
+	if !servercfg.IsMessageQueueBackend() {
+		return nil
+	}
 	networkNodes, err := logic.GetNetworkNodes(newNode.Network)
 	if err != nil {
 		logger.Log(1, "err getting Network Nodes", err.Error())

+ 1 - 1
netclient/functions/daemon.go

@@ -353,7 +353,7 @@ func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
 			return
 		}
 		//err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file)
-		err = wireguard.SetPeers(cfg.Node.Interface, cfg.Node.PersistentKeepalive, peerUpdate.Peers)
+		err = wireguard.SetPeers(cfg.Node.Interface, cfg.Node.Address, cfg.Node.PersistentKeepalive, peerUpdate.Peers)
 		if err != nil {
 			ncutils.Log("error syncing wg after peer update " + err.Error())
 			return

+ 21 - 5
netclient/local/routes.go

@@ -7,8 +7,10 @@ import (
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 
+// TODO handle ipv6 in future
+
 // SetPeerRoutes - sets/removes ip routes for each peer on a network
-func SetPeerRoutes(iface string, oldPeers map[string][]net.IPNet, newPeers []wgtypes.PeerConfig) {
+func SetPeerRoutes(iface, currentNodeAddr string, oldPeers map[string][]net.IPNet, newPeers []wgtypes.PeerConfig) {
 	// traverse through all recieved peers
 	for _, peer := range newPeers {
 		// if pubkey found in existing peers, check against existing peer
@@ -17,14 +19,14 @@ func SetPeerRoutes(iface string, oldPeers map[string][]net.IPNet, newPeers []wgt
 			// traverse IPs, check to see if old peer contains each IP
 			for _, allowedIP := range peer.AllowedIPs { // compare new ones (if any) to old ones
 				if !ncutils.IPNetSliceContains(currPeerAllowedIPs, allowedIP) {
-					if err := setRoute(iface, &allowedIP); err != nil {
+					if err := setRoute(iface, &allowedIP, allowedIP.IP.String()); err != nil {
 						ncutils.PrintLog(err.Error(), 1)
 					}
 				}
 			}
 			for _, allowedIP := range currPeerAllowedIPs { // compare old ones (if any) to new ones
 				if !ncutils.IPNetSliceContains(peer.AllowedIPs, allowedIP) {
-					if err := deleteRoute(iface, &allowedIP); err != nil {
+					if err := deleteRoute(iface, &allowedIP, allowedIP.IP.String()); err != nil {
 						ncutils.PrintLog(err.Error(), 1)
 					}
 				}
@@ -32,7 +34,7 @@ func SetPeerRoutes(iface string, oldPeers map[string][]net.IPNet, newPeers []wgt
 			delete(oldPeers, peer.PublicKey.String()) // remove peer as it was found and processed
 		} else {
 			for _, allowedIP := range peer.AllowedIPs { // add all routes as peer doesn't exist
-				if err := setRoute(iface, &allowedIP); err != nil {
+				if err := setRoute(iface, &allowedIP, allowedIP.String()); err != nil {
 					ncutils.PrintLog(err.Error(), 1)
 				}
 			}
@@ -42,7 +44,21 @@ func SetPeerRoutes(iface string, oldPeers map[string][]net.IPNet, newPeers []wgt
 	// traverse through all remaining existing peers
 	for _, allowedIPs := range oldPeers {
 		for _, allowedIP := range allowedIPs {
-			deleteRoute(iface, &allowedIP)
+			deleteRoute(iface, &allowedIP, allowedIP.IP.String())
 		}
 	}
 }
+
+// SetCurrentPeerRoutes - sets all the current peers
+func SetCurrentPeerRoutes(iface, currentAddr string, peers []wgtypes.Peer) {
+	for _, peer := range peers {
+		for _, allowedIP := range peer.AllowedIPs {
+			setRoute(iface, &allowedIP, currentAddr)
+		}
+	}
+}
+
+// SetCIDRRoute - sets the CIDR route, used on join and restarts
+func SetCIDRRoute(iface, currentAddr string, cidr *net.IPNet) {
+	setCidr(iface, currentAddr, cidr)
+}

+ 37 - 0
netclient/local/routes_darwin.go

@@ -0,0 +1,37 @@
+package local
+
+import (
+	"net"
+	"strings"
+
+	"github.com/gravitl/netmaker/netclient/ncutils"
+)
+
+// route -n add -net 10.0.0.0/8 192.168.0.254
+// networksetup -setadditionalroutes Ethernet 192.168.1.0 255.255.255.0 10.0.0.2 persistent
+func setRoute(iface string, addr *net.IPNet, address string) error {
+	var err error
+	var out string
+	var inetx = "inet"
+	if strings.Contains(addr.IP.String(), ":") {
+		inetx = "inet6"
+	}
+	out, err = ncutils.RunCmd("route -n get -"+inetx+" "+addr.IP.String(), true)
+	if err != nil {
+		return err
+	}
+	if !(strings.Contains(out, iface)) {
+		_, err = ncutils.RunCmd("route -q -n add -"+inetx+" "+addr.String()+" -interface "+iface, true)
+	}
+	return err
+}
+
+func deleteRoute(iface string, addr *net.IPNet, address string) error {
+	var err error
+	_, err = ncutils.RunCmd("route -q -n delete "+addr.String(), true)
+	return err
+}
+
+func setCidr(iface, address string, addr *net.IPNet) {
+	ncutils.RunCmd("route -q -n add -net "+addr.String()+" "+address, true)
+}

+ 23 - 0
netclient/local/routes_freebsd.go

@@ -0,0 +1,23 @@
+package local
+
+import (
+	"net"
+
+	"github.com/gravitl/netmaker/netclient/ncutils"
+)
+
+func setRoute(iface string, addr *net.IPNet, address string) error {
+	var err error
+	_, _ = ncutils.RunCmd("route add -net "+addr.String()+" -interface "+iface, true)
+	return err
+}
+
+func deleteRoute(iface string, addr *net.IPNet, address string) error {
+	var err error
+	_, err = ncutils.RunCmd("route delete -net "+addr.String()+" -interface "+iface, true)
+	return err
+}
+
+func setCidr(iface, address string, addr *net.IPNet) {
+	ncutils.RunCmd("route add -net "+addr.String()+" -interface "+iface, true)
+}

+ 6 - 5
netclient/local/routes_linux.go

@@ -1,6 +1,3 @@
-//go:build linux
-// +build linux
-
 package local
 
 import (
@@ -13,7 +10,7 @@ import (
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 
-func setRoute(iface string, addr *net.IPNet) error {
+func setRoute(iface string, addr *net.IPNet, address string) error {
 	out, err := ncutils.RunCmd(fmt.Sprintf("ip route get %s", addr.IP.String()), false)
 	if err != nil || !strings.Contains(out, iface) {
 		_, err = ncutils.RunCmd(fmt.Sprintf("ip route add %s dev %s", addr.String(), iface), true)
@@ -21,7 +18,7 @@ func setRoute(iface string, addr *net.IPNet) error {
 	return err
 }
 
-func deleteRoute(iface string, addr *net.IPNet) error {
+func deleteRoute(iface string, addr *net.IPNet, address string) error {
 	var err error
 	out, _ := ncutils.RunCmd(fmt.Sprintf("ip route get %s", addr.IP.String()), false)
 	if strings.Contains(out, iface) {
@@ -29,3 +26,7 @@ func deleteRoute(iface string, addr *net.IPNet) error {
 	}
 	return err
 }
+
+func setCidr(iface, address string, addr *net.IPNet) {
+	ncutils.RunCmd("ip -4 route add "+addr.String()+" dev "+iface, false)
+}

+ 28 - 0
netclient/local/routes_windows.go

@@ -0,0 +1,28 @@
+package local
+
+import (
+	"net"
+	"time"
+
+	"github.com/gravitl/netmaker/netclient/ncutils"
+)
+
+func setRoute(iface string, addr *net.IPNet, address string) error {
+	var err error
+	_, err = ncutils.RunCmd("route -p add "+addr.IP.String()+" mask "+addr.Mask.String()+" "+address, true)
+	time.Sleep(time.Second >> 2)
+	ncutils.RunCmd("route change "+addr.IP.String()+" mask "+addr.Mask.String()+" "+address, true)
+	return err
+}
+
+func deleteRoute(iface string, addr *net.IPNet, address string) error {
+	var err error
+	_, err = ncutils.RunCmd("route delete "+addr.IP.String()+" mask "+addr.Mask.String()+" "+address, true)
+	return err
+}
+
+func setCidr(iface, address string, addr *net.IPNet) {
+	ncutils.RunCmd("route -p add "+addr.IP.String()+" mask "+addr.Mask.String()+" "+address, true)
+	time.Sleep(time.Second >> 2)
+	ncutils.RunCmd("route change "+addr.IP.String()+" mask "+addr.Mask.String()+" "+address, true)
+}

+ 43 - 51
netclient/wireguard/common.go

@@ -1,7 +1,7 @@
 package wireguard
 
 import (
-	"errors"
+	"fmt"
 	"log"
 	"net"
 	"runtime"
@@ -25,7 +25,7 @@ const (
 )
 
 // SetPeers - sets peers on a given WireGuard interface
-func SetPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) error {
+func SetPeers(iface, currentNodeAddr string, keepalive int32, peers []wgtypes.PeerConfig) error {
 	var devicePeers []wgtypes.Peer
 	var oldPeerAllowedIps = make(map[string][]net.IPNet, len(peers))
 	var err error
@@ -107,7 +107,7 @@ func SetPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) error {
 		err = SetMacPeerRoutes(iface)
 		return err
 	} else if ncutils.IsLinux() {
-		local.SetPeerRoutes(iface, oldPeerAllowedIps, peers)
+		local.SetPeerRoutes(iface, currentNodeAddr, oldPeerAllowedIps, peers)
 	}
 
 	return nil
@@ -157,60 +157,52 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 
 	// spin up userspace / windows interface + apply the conf file
 	confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf"
-	var deviceiface string
-	if ncutils.IsMac() {
+	var deviceiface = ifacename
+	if ncutils.IsMac() { // if node is Mac (Darwin) get the tunnel name first
 		deviceiface, err = local.GetMacIface(node.Address)
 		if err != nil || deviceiface == "" {
 			deviceiface = ifacename
 		}
 	}
-	if syncconf {
+	// ensure you clear any existing interface first
+	d, _ := wgclient.Device(deviceiface)
+	for d != nil && d.Name == deviceiface {
+		RemoveConf(ifacename, false) // remove interface first
+		time.Sleep(time.Second >> 2)
+		d, _ = wgclient.Device(deviceiface)
+	}
+
+	ApplyConf(node, deviceiface, confPath) // Apply initially
+
+	ncutils.PrintLog("waiting for interface...", 1) // ensure interface is created
+	output, _ := ncutils.RunCmd("wg", false)
+	starttime := time.Now()
+	ifaceReady := false
+	for !strings.Contains(output, ifacename) && !(time.Now().After(starttime.Add(time.Second << 4))) {
+		output, _ = ncutils.RunCmd("wg", false)
+		err = ApplyConf(node, ifacename, confPath)
+		time.Sleep(time.Second)
+		ifaceReady = !strings.Contains(output, ifacename)
+	}
+	newDevice, devErr := wgclient.Device(deviceiface)
+	if !ifaceReady || devErr != nil {
+		return fmt.Errorf("could not reliably create interface, please check wg installation and retry")
+	}
+	ncutils.PrintLog("interface ready - netclient engage", 1)
+
+	if syncconf { // should never be called really.
 		err = SyncWGQuickConf(ifacename, confPath)
-	} else {
-		if !ncutils.IsMac() {
-			d, _ := wgclient.Device(deviceiface)
-			for d != nil && d.Name == deviceiface {
-				RemoveConf(ifacename, false) // remove interface first
-				time.Sleep(time.Second >> 2)
-				d, _ = wgclient.Device(deviceiface)
-			}
-		}
-		if !ncutils.IsWindows() {
-			err = ApplyConf(*node, ifacename, confPath)
-			if err != nil {
-				ncutils.PrintLog("failed to create wireguard interface", 1)
-				return err
-			}
+	}
+	currentPeers := newDevice.Peers
+	if len(currentPeers) == 0 { // if no peers currently, apply cidr
+		_, cidr, cidrErr := net.ParseCIDR(modcfg.NetworkSettings.AddressRange)
+		if cidrErr == nil {
+			local.SetCIDRRoute(ifacename, node.Address, cidr)
 		} else {
-			var output string
-			starttime := time.Now()
-			RemoveConf(ifacename, false)
-			time.Sleep(time.Second >> 2)
-			ncutils.PrintLog("waiting for interface...", 1)
-			for !strings.Contains(output, ifacename) && !(time.Now().After(starttime.Add(time.Duration(10) * time.Second))) {
-				output, _ = ncutils.RunCmd("wg", false)
-				err = ApplyConf(*node, ifacename, confPath)
-				time.Sleep(time.Second)
-			}
-			if !strings.Contains(output, ifacename) {
-				return errors.New("could not create wg interface for " + ifacename)
-			}
-			ip, mask, err := ncutils.GetNetworkIPMask(nodecfg.NetworkSettings.AddressRange)
-			if err != nil {
-				log.Println(err.Error())
-				return err
-			}
-			ncutils.RunCmd("route add "+ip+" mask "+mask+" "+node.Address, true)
-			time.Sleep(time.Second >> 2)
-			ncutils.RunCmd("route change "+ip+" mask "+mask+" "+node.Address, true)
+			ncutils.PrintLog("could not set cidr route properly: "+cidrErr.Error(), 1)
 		}
-	}
-
-	//extra network route setting
-	if ncutils.IsFreeBSD() {
-		_, _ = ncutils.RunCmd("route add -net "+nodecfg.NetworkSettings.AddressRange+" -interface "+ifacename, true)
-	} else if ncutils.IsLinux() {
-		_, _ = ncutils.RunCmd("ip -4 route add "+nodecfg.NetworkSettings.AddressRange+" dev "+ifacename, false)
+	} else { // if peers, apply each
+		local.SetCurrentPeerRoutes(ifacename, node.Address, currentPeers[:])
 	}
 
 	return err
@@ -243,7 +235,7 @@ func SetWGConfig(network string, peerupdate bool) error {
 				return err
 			}
 		}
-		err = SetPeers(iface, nodecfg.PersistentKeepalive, peers)
+		err = SetPeers(iface, nodecfg.Address, nodecfg.PersistentKeepalive, peers)
 	} else if peerupdate {
 		err = InitWireguard(&nodecfg, privkey, peers, hasGateway, gateways, true)
 	} else {
@@ -272,7 +264,7 @@ func RemoveConf(iface string, printlog bool) error {
 }
 
 // ApplyConf - applys a conf on disk to WireGuard interface
-func ApplyConf(node models.Node, ifacename string, confPath string) error {
+func ApplyConf(node *models.Node, ifacename string, confPath string) error {
 	os := runtime.GOOS
 	var err error
 	switch os {

+ 2 - 2
netclient/wireguard/mac.go

@@ -13,7 +13,7 @@ import (
 )
 
 // WgQuickDownMac - bring down mac interface, remove routes, and run post-down commands
-func WgQuickDownMac(node models.Node, iface string) error {
+func WgQuickDownMac(node *models.Node, iface string) error {
 	if err := RemoveConfMac(iface); err != nil {
 		return err
 	}
@@ -34,7 +34,7 @@ func RemoveConfMac(iface string) error {
 }
 
 // WgQuickUpMac - bring up mac interface and set routes
-func WgQuickUpMac(node models.Node, iface string, confPath string) error {
+func WgQuickUpMac(node *models.Node, iface string, confPath string) error {
 	var err error
 	var realIface string
 	realIface, err = getRealIface(iface)

+ 1 - 4
netclient/wireguard/unix.go

@@ -65,15 +65,12 @@ func ApplyWGQuickConf(confPath string, ifacename string) error {
 			ncutils.RunCmd("wg-quick down "+confPath, true)
 		}
 		_, err = ncutils.RunCmd("wg-quick up "+confPath, true)
-		// if err != nil {
-		// 	return err
-		// }
 		return err
 	}
 }
 
 // ApplyMacOSConf - applies system commands similar to wg-quick using golang for MacOS
-func ApplyMacOSConf(node models.Node, ifacename string, confPath string) error {
+func ApplyMacOSConf(node *models.Node, ifacename string, confPath string) error {
 	var err error
 	_ = WgQuickDownMac(node, ifacename)
 	err = WgQuickUpMac(node, ifacename, confPath)

+ 20 - 1
serverctl/serverctl.go

@@ -2,10 +2,12 @@ package serverctl
 
 import (
 	"errors"
+	"fmt"
 	"net"
 	"os"
 	"strings"
 
+	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/netclient/ncutils"
@@ -14,15 +16,32 @@ import (
 const NETMAKER_BINARY_NAME = "netmaker"
 
 // InitServerNetclient - intializes the server netclient
+// 1. Check if config directory exists, if not attempt to make
+// 2. Check current networks and run pull to get interface up to date in case of restart
 func InitServerNetclient() error {
 	netclientDir := ncutils.GetNetclientPath()
 	_, err := os.Stat(netclientDir + "/config")
 	if os.IsNotExist(err) {
-		os.MkdirAll(netclientDir+"/config", 0744)
+		os.MkdirAll(netclientDir+"/config", 0700)
 	} else if err != nil {
 		logger.Log(1, "could not find or create", netclientDir)
 		return err
 	}
+
+	var networks, netsErr = logic.GetNetworks()
+	if netsErr == nil || database.IsEmptyRecord(netsErr) {
+		for _, network := range networks {
+			var currentServerNode, nodeErr = logic.GetNetworkServerLocal(network.NetID)
+			if nodeErr == nil {
+				if err = logic.ServerPull(&currentServerNode, true); err != nil {
+					logger.Log(1, fmt.Sprintf("failed pull for network %s, on server node %s",
+						network.NetID,
+						currentServerNode.ID))
+				}
+			}
+		}
+	}
+
 	return nil
 }