2
0
Эх сурвалжийг харах

Rebase to develop (#4)

* add nameserver in call to CreateUserSpaceConf

* fixed user deletion

* changed log

* go mod tidy and conver azure tenant to env/conf var

* added egress relayed addrs to relayed nodes

* added post commands for wg quick

* refactored ncutils x-platform

* log fix

* adding egress to relay

* fixing egress on relay

Co-authored-by: dcarns <[email protected]>
Co-authored-by: 0xdcarns <[email protected]>
Co-authored-by: afeiszli <[email protected]>
Matthew R Kasun 3 жил өмнө
parent
commit
b4deb65cfb

+ 1 - 0
.gitignore

@@ -15,3 +15,4 @@ netclient/netclient32
 netclient/netclient.exe
 config/dnsconfig/
 data/
+.vscode/

+ 1 - 2
auth/azure-ad.go

@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"io/ioutil"
 	"net/http"
-	"os"
 
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
@@ -36,7 +35,7 @@ func initAzureAD(redirectURL string, clientID string, clientSecret string) {
 		ClientID:     clientID,
 		ClientSecret: clientSecret,
 		Scopes:       []string{"User.Read"},
-		Endpoint:     microsoft.AzureADEndpoint(os.Getenv("AZURE_TENANT")),
+		Endpoint:     microsoft.AzureADEndpoint(servercfg.GetAzureTenant()),
 	}
 }
 

+ 8 - 7
config/config.go

@@ -12,7 +12,7 @@ import (
 	"gopkg.in/yaml.v3"
 )
 
-//setting dev by default
+// setting dev by default
 func getEnv() string {
 
 	env := os.Getenv("NETMAKER_ENV")
@@ -27,13 +27,13 @@ func getEnv() string {
 // Config : application config stored as global variable
 var Config *EnvironmentConfig
 
-// EnvironmentConfig :
+// EnvironmentConfig - environment conf struct
 type EnvironmentConfig struct {
 	Server ServerConfig `yaml:"server"`
 	SQL    SQLConfig    `yaml:"sql"`
 }
 
-// ServerConfig :
+// ServerConfig - server conf struct
 type ServerConfig struct {
 	CoreDNSAddr           string `yaml:"corednsaddr"`
 	APIConnString         string `yaml:"apiconn"`
@@ -58,8 +58,8 @@ type ServerConfig struct {
 	Version               string `yaml:"version"`
 	SQLConn               string `yaml:"sqlconn"`
 	Platform              string `yaml:"platform"`
-	Database              string `yaml:database`
-	CheckinInterval       string `yaml:checkininterval`
+	Database              string `yaml:"database"`
+	CheckinInterval       string `yaml:"checkininterval"`
 	DefaultNodeLimit      int32  `yaml:"defaultnodelimit"`
 	Verbosity             int32  `yaml:"verbosity"`
 	ServerCheckinInterval int64  `yaml:"servercheckininterval"`
@@ -68,9 +68,10 @@ type ServerConfig struct {
 	ClientSecret          string `yaml:"clientsecret"`
 	FrontendURL           string `yaml:"frontendurl"`
 	DisplayKeys           string `yaml:"displaykeys"`
+	AzureTenant           string `yaml:"azuretenant"`
 }
 
-// Generic SQL Config
+// SQLConfig - Generic SQL Config
 type SQLConfig struct {
 	Host     string `yaml:"host"`
 	Port     int32  `yaml:"port"`
@@ -80,7 +81,7 @@ type SQLConfig struct {
 	SSLMode  string `yaml:"sslmode"`
 }
 
-//reading in the env file
+// reading in the env file
 func readConfig() *EnvironmentConfig {
 	file := fmt.Sprintf("config/environments/%s.yaml", getEnv())
 	f, err := os.Open(file)

+ 1 - 1
controllers/user.go

@@ -23,7 +23,7 @@ func userHandlers(r *mux.Router) {
 	r.HandleFunc("/api/users/networks/{username}", securityCheck(true, http.HandlerFunc(updateUserNetworks))).Methods("PUT")
 	r.HandleFunc("/api/users/{username}/adm", securityCheck(true, http.HandlerFunc(updateUserAdm))).Methods("PUT")
 	r.HandleFunc("/api/users/{username}", securityCheck(true, http.HandlerFunc(createUser))).Methods("POST")
-	r.HandleFunc("/api/users/{username}", securityCheck(false, continueIfUserMatch(http.HandlerFunc(deleteUser)))).Methods("DELETE")
+	r.HandleFunc("/api/users/{username}", securityCheck(true, http.HandlerFunc(deleteUser))).Methods("DELETE")
 	r.HandleFunc("/api/users/{username}", securityCheck(false, continueIfUserMatch(http.HandlerFunc(getUser)))).Methods("GET")
 	r.HandleFunc("/api/users", securityCheck(true, http.HandlerFunc(getUsers))).Methods("GET")
 	r.HandleFunc("/api/oauth/login", auth.HandleAuthLogin).Methods("GET")

+ 57 - 14
logic/util.go

@@ -184,26 +184,18 @@ func GetNode(macaddress string, network string) (models.Node, error) {
 // GetNodePeers - fetches peers for a given node
 func GetNodePeers(networkName string, excludeRelayed bool) ([]models.Node, error) {
 	var peers []models.Node
-	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
+	var networkNodes, egressNetworkNodes, err = getNetworkEgressAndNodes(networkName)
 	if err != nil {
-		if database.IsEmptyRecord(err) {
-			return peers, nil
-		}
-		logger.Log(2, err.Error())
-		return nil, err
+		return peers, nil
 	}
+
 	udppeers, errN := database.GetPeers(networkName)
 	if errN != nil {
 		logger.Log(2, errN.Error())
 	}
-	for _, value := range collection {
-		var node = &models.Node{}
+
+	for _, node := range networkNodes {
 		var peer = models.Node{}
-		err := json.Unmarshal([]byte(value), node)
-		if err != nil {
-			logger.Log(2, err.Error())
-			continue
-		}
 		if node.IsEgressGateway == "yes" { // handle egress stuff
 			peer.EgressGatewayRanges = node.EgressGatewayRanges
 			peer.IsEgressGateway = node.IsEgressGateway
@@ -211,7 +203,7 @@ func GetNodePeers(networkName string, excludeRelayed bool) ([]models.Node, error
 		allow := node.IsRelayed != "yes" || !excludeRelayed
 
 		if node.Network == networkName && node.IsPending != "yes" && allow {
-			peer = setPeerInfo(node)
+			peer = setPeerInfo(&node)
 			if node.UDPHolePunch == "yes" && errN == nil && CheckEndpoint(udppeers[node.PublicKey]) {
 				endpointstring := udppeers[node.PublicKey]
 				endpointarr := strings.Split(endpointstring, ":")
@@ -230,6 +222,11 @@ func GetNodePeers(networkName string, excludeRelayed bool) ([]models.Node, error
 				} else {
 					peer.AllowedIPs = append(peer.AllowedIPs, node.RelayAddrs...)
 				}
+				for _, egressNode := range egressNetworkNodes {
+					if egressNode.IsRelayed == "yes" && StringSliceContains(node.RelayAddrs, egressNode.Address) {
+						peer.AllowedIPs = append(peer.AllowedIPs, egressNode.EgressGatewayRanges...)
+					}
+				}
 			}
 			peers = append(peers, peer)
 		}
@@ -252,6 +249,14 @@ func GetPeersList(networkName string, excludeRelayed bool, relayedNodeAddr strin
 			network, err := GetNetwork(networkName)
 			if err == nil {
 				peerNode.AllowedIPs = append(peerNode.AllowedIPs, network.AddressRange)
+				var _, egressNetworkNodes, err = getNetworkEgressAndNodes(networkName)
+				if err == nil {
+					for _, egress := range egressNetworkNodes {
+						if egress.Address != relayedNodeAddr {
+							peerNode.AllowedIPs = append(peerNode.AllowedIPs, egress.EgressGatewayRanges...)
+						}
+					}
+				}
 			} else {
 				peerNode.AllowedIPs = append(peerNode.AllowedIPs, peerNode.RelayAddrs...)
 			}
@@ -286,6 +291,34 @@ func RandomString(length int) string {
 
 // == Private Methods ==
 
+func getNetworkEgressAndNodes(networkName string) ([]models.Node, []models.Node, error) {
+	var networkNodes, egressNetworkNodes []models.Node
+	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
+	if err != nil {
+		if database.IsEmptyRecord(err) {
+			return networkNodes, egressNetworkNodes, nil
+		}
+		logger.Log(2, err.Error())
+		return nil, nil, err
+	}
+
+	for _, value := range collection {
+		var node = models.Node{}
+		err := json.Unmarshal([]byte(value), &node)
+		if err != nil {
+			logger.Log(2, err.Error())
+			continue
+		}
+		if node.Network == networkName {
+			networkNodes = append(networkNodes, node)
+			if node.IsEgressGateway == "yes" {
+				egressNetworkNodes = append(egressNetworkNodes, node)
+			}
+		}
+	}
+	return networkNodes, egressNetworkNodes, nil
+}
+
 func setPeerInfo(node *models.Node) models.Node {
 	var peer models.Node
 	peer.RelayAddrs = node.RelayAddrs
@@ -326,3 +359,13 @@ func setIPForwardingLinux() error {
 	}
 	return nil
 }
+
+// StringSliceContains - sees if a string slice contains a string element
+func StringSliceContains(slice []string, item string) bool {
+	for _, s := range slice {
+		if s == item {
+			return true
+		}
+	}
+	return false
+}

+ 2 - 1
logic/wireguard.go

@@ -87,7 +87,8 @@ func initWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 
 	if !ncutils.IsKernel() {
 		var newConf string
-		newConf, _ = ncutils.CreateWireGuardConf(node.Address, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), node.MTU, servercfg.GetCoreDNSAddr(), node.PersistentKeepalive, peers)
+		var nameserver string
+		newConf, _ = ncutils.CreateWireGuardConf(node.Address, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), node.MTU, nameserver, servercfg.GetCoreDNSAddr(), node.PersistentKeepalive, peers)
 		confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf"
 		logger.Log(1, "writing wg conf file to:", confPath)
 		err = ioutil.WriteFile(confPath, []byte(newConf), 0644)

+ 1 - 1
main.go

@@ -43,7 +43,7 @@ func initialize() { // Client Mode Prereq Check
 
 	var authProvider = auth.InitializeAuthProvider()
 	if authProvider != "" {
-		logger.Log(0, "OAuth provider, ", authProvider, ", initialized")
+		logger.Log(0, "OAuth provider,", authProvider+",", "initialized")
 	} else {
 		logger.Log(0, "no OAuth provider found or not configured, continuing without OAuth")
 	}

+ 2 - 1
netclient/command/commands.go

@@ -205,8 +205,9 @@ func List(cfg config.ClientConfig) error {
 
 // Uninstall - runs uninstall command from cli
 func Uninstall() error {
-	ncutils.PrintLog("uninstalling netclient", 0)
+	ncutils.PrintLog("uninstalling netclient...", 0)
 	err := functions.Uninstall()
+	ncutils.PrintLog("uninstalled netclient", 0)
 	return err
 }
 

+ 8 - 7
netclient/ncutils/netclientutils_darwin.go

@@ -7,6 +7,7 @@ import (
 	"strconv"
 	"strings"
 
+	"github.com/gravitl/netmaker/models"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 
@@ -33,12 +34,12 @@ func GetEmbedded() error {
 	return nil
 }
 
-// CreateUserSpaceConf - creates a user space WireGuard conf
-func CreateUserSpaceConf(address string, privatekey string, listenPort string, mtu int32, perskeepalive int32, peers []wgtypes.PeerConfig) (string, error) {
-	peersString, err := parsePeers(perskeepalive, peers)
+// CreateWireGuardConf - creates a WireGuard conf string
+func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, dns string, peers []wgtypes.PeerConfig) (string, error) {
+	peersString, err := parsePeers(node.PersistentKeepalive, peers)
 	var listenPortString string
-	if mtu <= 0 {
-		mtu = 1280
+	if node.MTU <= 0 {
+		node.MTU = 1280
 	}
 	if listenPort != "" {
 		listenPortString += "ListenPort = " + listenPort
@@ -55,9 +56,9 @@ MTU = %s
 %s
 
 `,
-		address+"/32",
+		node.Address+"/32",
 		privatekey,
-		strconv.Itoa(int(mtu)),
+		strconv.Itoa(int(node.MTU)),
 		listenPortString,
 		peersString)
 	return config, nil

+ 10 - 8
netclient/ncutils/netclientutils_freebsd.go

@@ -3,13 +3,15 @@ package ncutils
 import (
 	"context"
 	"fmt"
-	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 	"log"
 	"os/exec"
 	"strconv"
 	"strings"
 	"syscall"
 	"time"
+
+	"github.com/gravitl/netmaker/models"
+	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 
 // RunCmdFormatted - run a command formatted for freebsd
@@ -41,12 +43,12 @@ func RunCmd(command string, printerr bool) (string, error) {
 	return string(out), err
 }
 
-// CreateUserSpaceConf - creates a user space WireGuard conf
-func CreateUserSpaceConf(address string, privatekey string, listenPort string, mtu int32, perskeepalive int32, peers []wgtypes.PeerConfig) (string, error) {
-	peersString, err := parsePeers(perskeepalive, peers)
+// CreateWireGuardConf - creates a WireGuard conf string
+func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, dns string, peers []wgtypes.PeerConfig) (string, error) {
+	peersString, err := parsePeers(node.PersistentKeepalive, peers)
 	var listenPortString string
-	if mtu <= 0 {
-		mtu = 1280
+	if node.MTU <= 0 {
+		node.MTU = 1280
 	}
 	if listenPort != "" {
 		listenPortString += "ListenPort = " + listenPort
@@ -63,9 +65,9 @@ MTU = %s
 %s
 
 `,
-		address+"/32",
+		node.Address+"/32",
 		privatekey,
-		strconv.Itoa(int(mtu)),
+		strconv.Itoa(int(node.MTU)),
 		listenPortString,
 		peersString)
 	return config, nil

+ 21 - 8
netclient/ncutils/netclientutils_linux.go

@@ -6,6 +6,7 @@ import (
 	"strconv"
 	"strings"
 
+	"github.com/gravitl/netmaker/models"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 
@@ -33,15 +34,23 @@ func GetEmbedded() error {
 }
 
 // CreateWireGuardConf - creates a user space WireGuard conf
-func CreateWireGuardConf(address string, privatekey string, listenPort string, mtu int32, dns string, perskeepalive int32, peers []wgtypes.PeerConfig) (string, error) {
-	peersString, err := parsePeers(perskeepalive, peers)
-	var listenPortString string
-	if mtu <= 0 {
-		mtu = 1280
+func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, dns string, peers []wgtypes.PeerConfig) (string, error) {
+	peersString, err := parsePeers(node.PersistentKeepalive, peers)
+	var listenPortString, postDownString, postUpString string
+	if node.MTU <= 0 {
+		node.MTU = 1280
 	}
+	if node.PostDown != "" {
+		postDownString = fmt.Sprintf("PostDown = %s", node.PostDown)
+	}
+	if node.PostUp != "" {
+		postUpString = fmt.Sprintf("PostUp = %s", node.PostUp)
+	}
+
 	if listenPort != "" {
-		listenPortString += "ListenPort = " + listenPort
+		listenPortString = fmt.Sprintf("ListenPort = %s", listenPort)
 	}
+
 	if err != nil {
 		return "", err
 	}
@@ -51,14 +60,18 @@ DNS = %s
 PrivateKey = %s
 MTU = %s
 %s
+%s
+%s
 
 %s
 
 `,
-		address+"/32",
+		node.Address+"/32",
 		dns,
 		privatekey,
-		strconv.Itoa(int(mtu)),
+		strconv.Itoa(int(node.MTU)),
+		postDownString,
+		postUpString,
 		listenPortString,
 		peersString)
 	return config, nil

+ 8 - 7
netclient/ncutils/netclientutils_windows.go

@@ -10,6 +10,7 @@ import (
 	"strings"
 	"syscall"
 
+	"github.com/gravitl/netmaker/models"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 
@@ -47,12 +48,12 @@ func RunCmdFormatted(command string, printerr bool) (string, error) {
 	return string(out), err
 }
 
-// CreateUserSpaceConf - creates a user space WireGuard conf
-func CreateUserSpaceConf(address string, privatekey string, listenPort string, mtu int32, perskeepalive int32, peers []wgtypes.PeerConfig) (string, error) {
-	peersString, err := parsePeers(perskeepalive, peers)
+// CreateWireGuardConf - creates a WireGuard conf string
+func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, dns string, peers []wgtypes.PeerConfig) (string, error) {
+	peersString, err := parsePeers(node.PersistentKeepalive, peers)
 	var listenPortString string
-	if mtu <= 0 {
-		mtu = 1280
+	if node.MTU <= 0 {
+		node.MTU = 1280
 	}
 	if listenPort != "" {
 		listenPortString += "ListenPort = " + listenPort
@@ -69,9 +70,9 @@ MTU = %s
 %s
 
 `,
-		address+"/32",
+		node.Address+"/32",
 		privatekey,
-		strconv.Itoa(int(mtu)),
+		strconv.Itoa(int(node.MTU)),
 		listenPortString,
 		peersString)
 	return config, nil

+ 3 - 3
netclient/wireguard/common.go

@@ -149,9 +149,9 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 	}
 	var newConf string
 	if node.UDPHolePunch != "yes" {
-		newConf, _ = ncutils.CreateWireGuardConf(node.Address, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), node.MTU, nameserver, node.PersistentKeepalive, peers)
+		newConf, _ = ncutils.CreateWireGuardConf(node, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), nameserver, peers)
 	} else {
-		newConf, _ = ncutils.CreateWireGuardConf(node.Address, key.String(), "", node.MTU, nameserver, node.PersistentKeepalive, peers)
+		newConf, _ = ncutils.CreateWireGuardConf(node, key.String(), "", nameserver, peers)
 	}
 	confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf"
 	ncutils.PrintLog("writing wg conf file to: "+confPath, 1)
@@ -182,7 +182,7 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 	} else {
 		d, _ := wgclient.Device(deviceiface)
 		for d != nil && d.Name == deviceiface {
-			_ = RemoveConf(ifacename, false) // remove interface first
+			RemoveConf(ifacename, false) // remove interface first
 			time.Sleep(time.Second >> 2)
 			d, _ = wgclient.Device(deviceiface)
 		}

+ 2 - 1
netclient/wireguard/unix.go

@@ -1,6 +1,7 @@
 package wireguard
 
 import (
+	"fmt"
 	"io/ioutil"
 	"log"
 	"os"
@@ -86,7 +87,7 @@ func SyncWGQuickConf(iface string, confPath string) error {
 
 // RemoveWGQuickConf - calls wg-quick down
 func RemoveWGQuickConf(confPath string, printlog bool) error {
-	_, err := ncutils.RunCmd("wg-quick down "+confPath, printlog)
+	_, err := ncutils.RunCmd(fmt.Sprintf("wg-quick down %s", confPath), printlog)
 	return err
 }
 

+ 11 - 0
servercfg/serverconf.go

@@ -502,6 +502,17 @@ func GetAuthProviderInfo() []string {
 	return []string{"", "", ""}
 }
 
+// GetAzureTenant - retrieve the azure tenant ID from env variable or config file
+func GetAzureTenant() string {
+	var azureTenant = ""
+	if os.Getenv("AZURE_TENANT") != "" {
+		azureTenant = os.Getenv("AZURE_TENANT")
+	} else if config.Config.Server.AzureTenant != "" {
+		azureTenant = config.Config.Server.AzureTenant
+	}
+	return azureTenant
+}
+
 // GetMacAddr - get's mac address
 func getMacAddr() string {
 	ifas, err := net.Interfaces()