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 <75687250+0xdcarns@users.noreply.github.com>
Co-authored-by: 0xdcarns <dillon.carns@gmail.com>
Co-authored-by: afeiszli <alex.feiszli@gmail.com>
This commit is contained in:
Matthew R Kasun 2022-01-04 17:24:50 -05:00 committed by GitHub
parent 5e5d97627d
commit b4deb65cfb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 136 additions and 61 deletions

1
.gitignore vendored
View file

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

View file

@ -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()),
}
}

View file

@ -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"`

View file

@ -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")

View file

@ -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
}
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
}

View file

@ -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)

View file

@ -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")
}

View file

@ -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
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)
}

View file

@ -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
}

View file

@ -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()