From c05320a3233475d038f0aab346f8b141e089c054 Mon Sep 17 00:00:00 2001 From: 0xdcarns Date: Fri, 19 Aug 2022 12:08:31 -0400 Subject: [PATCH] initial logic added --- logic/nodes.go | 1 + logic/wireguard.go | 1 + models/node.go | 15 +++++++ netclient/ncutils/iface.go | 1 + netclient/wireguard/common.go | 14 +++---- netclient/wireguard/noquick.go | 18 +++++++-- netclient/wireguard/unix.go | 72 ++++++++++++++++++---------------- netclient/wireguard/windows.go | 5 ++- 8 files changed, 81 insertions(+), 46 deletions(-) diff --git a/logic/nodes.go b/logic/nodes.go index 73377f81..a93c2677 100644 --- a/logic/nodes.go +++ b/logic/nodes.go @@ -433,6 +433,7 @@ func SetNodeDefaults(node *models.Node) { node.SetDefaultIsDocker() node.SetDefaultIsK8S() node.SetDefaultIsHub() + node.SetDefaultConnected() } // GetRecordKey - get record key diff --git a/logic/wireguard.go b/logic/wireguard.go index 7bf640ef..22f5167b 100644 --- a/logic/wireguard.go +++ b/logic/wireguard.go @@ -58,6 +58,7 @@ func IfaceDelta(currentNode *models.Node, newNode *models.Node) bool { newNode.MTU != currentNode.MTU || newNode.PersistentKeepalive != currentNode.PersistentKeepalive || newNode.DNSOn != currentNode.DNSOn || + newNode.Connected != currentNode.Connected || len(newNode.AllowedIPs) != len(currentNode.AllowedIPs) { return true } diff --git a/models/node.go b/models/node.go index 94459e43..9241116e 100644 --- a/models/node.go +++ b/models/node.go @@ -93,6 +93,7 @@ type Node struct { TrafficKeys TrafficKeys `json:"traffickeys" bson:"traffickeys" yaml:"traffickeys"` FirewallInUse string `json:"firewallinuse" bson:"firewallinuse" yaml:"firewallinuse"` InternetGateway string `json:"internetgateway" bson:"internetgateway" yaml:"internetgateway"` + Connected string `json:"connected" bson:"connected" yaml:"connected" validate:"checkyesorno"` } // NodesArray - used for node sorting @@ -121,6 +122,16 @@ func (node *Node) PrimaryAddress() string { return node.Address6 } +// Node.SetDefaultConnected +func (node *Node) SetDefaultConnected() { + if node.Connected == "" { + node.Connected = "yes" + } + if node.IsServer == "yes" { + node.Connected = "yes" + } +} + // Node.SetDefaultMTU - sets default MTU of a node func (node *Node) SetDefaultMTU() { if node.MTU == 0 { @@ -382,6 +393,7 @@ func (newNode *Node) Fill(currentNode *Node) { // TODO add new field for nftable } if newNode.IsServer == "yes" { newNode.IsStatic = "yes" + newNode.Connected = "yes" } if newNode.MTU == 0 { newNode.MTU = currentNode.MTU @@ -413,6 +425,9 @@ func (newNode *Node) Fill(currentNode *Node) { // TODO add new field for nftable if newNode.Server == "" { newNode.Server = currentNode.Server } + if newNode.Connected == "" { + newNode.Connected = currentNode.Connected + } newNode.TrafficKeys = currentNode.TrafficKeys } diff --git a/netclient/ncutils/iface.go b/netclient/ncutils/iface.go index 6ea08c15..ff17caa3 100644 --- a/netclient/ncutils/iface.go +++ b/netclient/ncutils/iface.go @@ -22,6 +22,7 @@ func IfaceDelta(currentNode *models.Node, newNode *models.Node) bool { newNode.IsPending != currentNode.IsPending || newNode.PersistentKeepalive != currentNode.PersistentKeepalive || newNode.DNSOn != currentNode.DNSOn || + newNode.Connected != currentNode.Connected || len(newNode.AllowedIPs) != len(currentNode.AllowedIPs) { return true } diff --git a/netclient/wireguard/common.go b/netclient/wireguard/common.go index a61d817b..3bd2fddd 100644 --- a/netclient/wireguard/common.go +++ b/netclient/wireguard/common.go @@ -191,10 +191,7 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig } } logger.Log(1, "interface ready - netclient.. ENGAGE") - if syncconf { // should never be called really. - fmt.Println("why here") - err = SyncWGQuickConf(ifacename, confPath) - } + if !ncutils.HasWgQuick() && ncutils.IsLinux() { err = SetPeers(ifacename, node, peers) if err != nil { @@ -284,16 +281,17 @@ func ApplyConf(node *models.Node, ifacename string, confPath string) error { if ncutils.IsLinux() && !ncutils.HasWgQuick() { os = "nowgquick" } + var isConnected = node.Connected != "no" var err error switch os { case "windows": - ApplyWindowsConf(confPath) + ApplyWindowsConf(confPath, isConnected) case "darwin": - ApplyMacOSConf(node, ifacename, confPath) + ApplyMacOSConf(node, ifacename, confPath, isConnected) case "nowgquick": - ApplyWithoutWGQuick(node, ifacename, confPath) + ApplyWithoutWGQuick(node, ifacename, confPath, isConnected) default: - ApplyWGQuickConf(confPath, ifacename) + ApplyWGQuickConf(confPath, ifacename, isConnected) } var nodeCfg config.ClientConfig diff --git a/netclient/wireguard/noquick.go b/netclient/wireguard/noquick.go index 8e1e80d7..c1f4a24f 100644 --- a/netclient/wireguard/noquick.go +++ b/netclient/wireguard/noquick.go @@ -2,6 +2,7 @@ package wireguard import ( "errors" + "fmt" "os" "os/exec" "strconv" @@ -15,8 +16,10 @@ import ( "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) +const disconnect_error = "node disconnected" + // ApplyWithoutWGQuick - Function for running the equivalent of "wg-quick up" for linux if wg-quick is missing -func ApplyWithoutWGQuick(node *models.Node, ifacename string, confPath string) error { +func ApplyWithoutWGQuick(node *models.Node, ifacename, confPath string, isConnected bool) error { ipExec, err := exec.LookPath("ip") if err != nil { @@ -72,7 +75,12 @@ func ApplyWithoutWGQuick(node *models.Node, ifacename string, confPath string) e mask6 = netmask address6 = node.Address6 } - setKernelDevice(ifacename, address4, mask4, address6, mask6) + err = setKernelDevice(ifacename, address4, mask4, address6, mask6, isConnected) + if err != nil { + if err.Error() == disconnect_error { + return nil + } + } _, err = wgclient.Device(ifacename) if err != nil { @@ -140,7 +148,7 @@ func RemoveWithoutWGQuick(ifacename string) error { return err } -func setKernelDevice(ifacename, address4, mask4, address6, mask6 string) error { +func setKernelDevice(ifacename, address4, mask4, address6, mask6 string, isConnected bool) error { ipExec, err := exec.LookPath("ip") if err != nil { return err @@ -148,6 +156,10 @@ func setKernelDevice(ifacename, address4, mask4, address6, mask6 string) error { // == best effort == ncutils.RunCmd("ip link delete dev "+ifacename, false) + if !isConnected { + return fmt.Errorf("node disconnected") + } + ncutils.RunCmd(ipExec+" link add dev "+ifacename+" type wireguard", true) if address4 != "" { ncutils.RunCmd(ipExec+" address add dev "+ifacename+" "+address4+"/"+mask4, true) diff --git a/netclient/wireguard/unix.go b/netclient/wireguard/unix.go index d0167e57..cf66e3f6 100644 --- a/netclient/wireguard/unix.go +++ b/netclient/wireguard/unix.go @@ -2,9 +2,7 @@ package wireguard import ( "fmt" - "log" "os" - "regexp" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" @@ -12,9 +10,9 @@ import ( ) // ApplyWGQuickConf - applies wg-quick commands if os supports -func ApplyWGQuickConf(confPath string, ifacename string) error { +func ApplyWGQuickConf(confPath, ifacename string, isConnected bool) error { if ncutils.IsWindows() { - return ApplyWindowsConf(confPath) + return ApplyWindowsConf(confPath, isConnected) } else { _, err := os.Stat(confPath) if err != nil { @@ -24,6 +22,9 @@ func ApplyWGQuickConf(confPath string, ifacename string) error { if ncutils.IfaceExists(ifacename) { ncutils.RunCmd("wg-quick down "+confPath, true) } + if !isConnected { + return nil + } _, err = ncutils.RunCmd("wg-quick up "+confPath, true) return err @@ -31,42 +32,45 @@ func ApplyWGQuickConf(confPath string, ifacename string) error { } // 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, confPath string, isConnected bool) error { var err error _ = WgQuickDownMac(node, ifacename) + if !isConnected { + return nil + } err = WgQuickUpMac(node, ifacename, confPath) return err } -// SyncWGQuickConf - formats config file and runs sync command -func SyncWGQuickConf(iface string, confPath string) error { - var tmpConf = confPath + ".sync.tmp" - var confCmd = "wg-quick strip " - if ncutils.IsMac() { - confCmd = "grep -v -e Address -e MTU -e PostUp -e PostDown " - } - confRaw, err := ncutils.RunCmd(confCmd+confPath, false) - if err != nil { - return err - } - regex := regexp.MustCompile(".*Warning.*\n") - conf := regex.ReplaceAllString(confRaw, "") - err = os.WriteFile(tmpConf, []byte(conf), 0600) - if err != nil { - return err - } - _, err = ncutils.RunCmd("wg syncconf "+iface+" "+tmpConf, true) - if err != nil { - log.Println(err.Error()) - logger.Log(0, "error syncing conf, resetting") - err = ApplyWGQuickConf(confPath, iface) - } - errN := os.Remove(tmpConf) - if errN != nil { - logger.Log(0, errN.Error()) - } - return err -} +// SyncWGQuickConf - formats config file and runs sync command - DEPRECATED +// func SyncWGQuickConf(iface string, confPath string) error { +// var tmpConf = confPath + ".sync.tmp" +// var confCmd = "wg-quick strip " +// if ncutils.IsMac() { +// confCmd = "grep -v -e Address -e MTU -e PostUp -e PostDown " +// } +// confRaw, err := ncutils.RunCmd(confCmd+confPath, false) +// if err != nil { +// return err +// } +// regex := regexp.MustCompile(".*Warning.*\n") +// conf := regex.ReplaceAllString(confRaw, "") +// err = os.WriteFile(tmpConf, []byte(conf), 0600) +// if err != nil { +// return err +// } +// _, err = ncutils.RunCmd("wg syncconf "+iface+" "+tmpConf, true) +// if err != nil { +// log.Println(err.Error()) +// logger.Log(0, "error syncing conf, resetting") +// err = ApplyWGQuickConf(confPath, iface) +// } +// errN := os.Remove(tmpConf) +// if errN != nil { +// logger.Log(0, errN.Error()) +// } +// return err +// } // RemoveWGQuickConf - calls wg-quick down func RemoveWGQuickConf(confPath string, printlog bool) error { diff --git a/netclient/wireguard/windows.go b/netclient/wireguard/windows.go index 6dcd8960..85170a0c 100644 --- a/netclient/wireguard/windows.go +++ b/netclient/wireguard/windows.go @@ -8,7 +8,10 @@ import ( ) // ApplyWindowsConf - applies the WireGuard configuration file on Windows -func ApplyWindowsConf(confPath string) error { +func ApplyWindowsConf(confPath string, isConnected bool) error { + if !isConnected { + return nil + } var commandLine = fmt.Sprintf(`wireguard.exe /installtunnelservice "%s"`, confPath) if _, err := ncutils.RunCmdFormatted(commandLine, false); err != nil { return err