mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-06 05:04:27 +08:00
refactor proxy updates
This commit is contained in:
parent
acae6c3aed
commit
a7c0abe2fc
14 changed files with 192 additions and 300 deletions
|
@ -3,7 +3,6 @@ package controller
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
|
@ -15,10 +14,8 @@ import (
|
|||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/models/promodels"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
"github.com/gravitl/netmaker/nm-proxy/manager"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
func nodeHandlers(r *mux.Router) {
|
||||
|
@ -1015,25 +1012,6 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
|
|||
if servercfg.IsDNSMode() {
|
||||
logic.SetDNS()
|
||||
}
|
||||
wgPubKey, wgErr := wgtypes.ParseKey(newNode.PublicKey)
|
||||
nodeEndpoint, udpErr := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", newNode.Endpoint, newNode.LocalListenPort))
|
||||
if wgErr == nil && udpErr == nil {
|
||||
logic.ProxyMgmChan <- &manager.ManagerAction{
|
||||
Action: manager.UpdatePeer,
|
||||
Payload: manager.ManagerPayload{
|
||||
InterfaceName: newNode.Interface,
|
||||
Peers: []wgtypes.PeerConfig{
|
||||
{
|
||||
PublicKey: wgPubKey,
|
||||
Endpoint: nodeEndpoint,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
} else {
|
||||
logger.Log(1, fmt.Sprintf("failed to send node update to proxy, wgErr: %v, udpErr: %v", wgErr, udpErr))
|
||||
}
|
||||
|
||||
logger.Log(1, r.Header.Get("user"), "updated node", node.ID, "on network", node.Network)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(newNode)
|
||||
|
@ -1121,20 +1099,6 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
|
|||
logger.Log(0, "failed to reset failover lists during node delete for node", node.Name, node.Network)
|
||||
}
|
||||
}
|
||||
wgKey, _ := wgtypes.ParseKey(node.PublicKey)
|
||||
endpoint, _ := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", node.Endpoint, node.LocalListenPort))
|
||||
logic.ProxyMgmChan <- &manager.ManagerAction{
|
||||
Action: manager.DeletePeer,
|
||||
Payload: manager.ManagerPayload{
|
||||
InterfaceName: node.Interface,
|
||||
Peers: []wgtypes.PeerConfig{
|
||||
{
|
||||
PublicKey: wgKey,
|
||||
Endpoint: endpoint,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
logic.ReturnSuccessResponse(w, r, nodeid+" deleted.")
|
||||
logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
|
||||
runUpdates(&node, false)
|
||||
|
@ -1151,6 +1115,7 @@ func runUpdates(node *models.Node, ifaceDelta bool) {
|
|||
if err := runServerUpdate(node, ifaceDelta); err != nil {
|
||||
logger.Log(1, "error running server update", err.Error())
|
||||
}
|
||||
|
||||
}()
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@ import (
|
|||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
"github.com/gravitl/netmaker/nm-proxy/manager"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
// swagger:route POST /api/nodes/{network}/{nodeid}/createrelay nodes createRelay
|
||||
|
@ -45,49 +43,15 @@ func createRelay(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
relayPeersMap := make(map[string][]wgtypes.PeerConfig)
|
||||
logger.Log(1, r.Header.Get("user"), "created relay on node", relay.NodeID, "on network", relay.NetID)
|
||||
for _, relayedNode := range updatenodes {
|
||||
peers, err := logic.GetPeersForProxy(&relayedNode)
|
||||
if err == nil {
|
||||
relayPeersMap[relayedNode.PublicKey] = peers
|
||||
}
|
||||
|
||||
// relayEndpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", node.Endpoint, node.LocalListenPort))
|
||||
// if err != nil {
|
||||
// logger.Log(1, "failed to resolve relay node endpoint: ", err.Error())
|
||||
// }
|
||||
|
||||
// err = mq.ProxyUpdate(&manager.ManagerAction{
|
||||
// Action: manager.AddInterface,
|
||||
// Payload: manager.ManagerPayload{
|
||||
// InterfaceName: relayedNode.Interface,
|
||||
// IsRelayed: true,
|
||||
// Peers: peers,
|
||||
// RelayedTo: relayEndpoint,
|
||||
// },
|
||||
// }, &node)
|
||||
// if err != nil {
|
||||
// logger.Log(1, "failed to send proxy update for relayed node: ", err.Error())
|
||||
// }
|
||||
|
||||
err = mq.NodeUpdate(&relayedNode)
|
||||
if err != nil {
|
||||
logger.Log(1, "error sending update to relayed node ", relayedNode.Name, "on network", relay.NetID, ": ", err.Error())
|
||||
}
|
||||
}
|
||||
// send proxy update for node that is relaying traffic
|
||||
logger.Log(0, "--------> sending relay update to proxy")
|
||||
err = mq.ProxyUpdate(&manager.ManagerAction{
|
||||
Action: manager.RelayPeers,
|
||||
Payload: manager.ManagerPayload{
|
||||
IsRelay: true,
|
||||
RelayedPeers: relayPeersMap,
|
||||
},
|
||||
}, &node)
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to send proxy update: ", err.Error())
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(node)
|
||||
runUpdates(&node, true)
|
||||
|
|
|
@ -3,7 +3,6 @@ package logic
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -14,24 +13,56 @@ import (
|
|||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic/acls/nodeacls"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/nm-proxy/manager"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
func GetPeersForProxy(node *models.Node) ([]wgtypes.PeerConfig, error) {
|
||||
func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ManagerPayload, error) {
|
||||
proxyPayload := manager.ManagerPayload{}
|
||||
var peers []wgtypes.PeerConfig
|
||||
peerConfMap := make(map[string]manager.PeerConf)
|
||||
var err error
|
||||
currentPeers, err := GetNetworkNodes(node.Network)
|
||||
if err != nil {
|
||||
return peers, err
|
||||
return proxyPayload, err
|
||||
}
|
||||
if !onlyPeers {
|
||||
if node.IsRelayed == "yes" {
|
||||
relayNode := FindRelay(node)
|
||||
relayEndpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayNode.Endpoint, relayNode.LocalListenPort))
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to resolve relay node endpoint: ", err.Error())
|
||||
}
|
||||
proxyPayload.IsRelayed = true
|
||||
proxyPayload.RelayedTo = relayEndpoint
|
||||
|
||||
}
|
||||
if node.IsRelay == "yes" {
|
||||
relayedNodes, err := GetRelayedNodes(node)
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to relayed nodes: ", node.Name, err.Error())
|
||||
proxyPayload.IsRelay = false
|
||||
} else {
|
||||
relayPeersMap := make(map[string][]wgtypes.PeerConfig)
|
||||
for _, relayedNode := range relayedNodes {
|
||||
payload, err := GetPeersForProxy(&relayedNode, true)
|
||||
if err == nil {
|
||||
relayPeersMap[relayedNode.PublicKey] = payload.Peers
|
||||
}
|
||||
}
|
||||
proxyPayload.IsRelay = true
|
||||
proxyPayload.RelayedPeers = relayPeersMap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, peer := range currentPeers {
|
||||
if peer.ID == node.ID {
|
||||
//skip yourself
|
||||
continue
|
||||
}
|
||||
log.Printf("----------> PEER: %s, Endpoint: %s, LocalPort: %d", peer.ID, peer.Endpoint, peer.LocalListenPort)
|
||||
pubkey, err := wgtypes.ParseKey(peer.PublicKey)
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to parse node pub key: ", peer.ID)
|
||||
|
@ -48,7 +79,6 @@ func GetPeersForProxy(node *models.Node) ([]wgtypes.PeerConfig, error) {
|
|||
// set_keepalive
|
||||
keepalive, _ = time.ParseDuration(strconv.FormatInt(int64(node.PersistentKeepalive), 10) + "s")
|
||||
}
|
||||
log.Printf("---------->##### PEER: %s, Endpoint: %s, LocalPort: %d", peer.ID, endpoint, peer.LocalListenPort)
|
||||
peers = append(peers, wgtypes.PeerConfig{
|
||||
PublicKey: pubkey,
|
||||
Endpoint: endpoint,
|
||||
|
@ -56,8 +86,25 @@ func GetPeersForProxy(node *models.Node) ([]wgtypes.PeerConfig, error) {
|
|||
PersistentKeepaliveInterval: &keepalive,
|
||||
ReplaceAllowedIPs: true,
|
||||
})
|
||||
if !onlyPeers && peer.IsRelayed == "yes" {
|
||||
relayNode := FindRelay(&peer)
|
||||
if relayNode != nil {
|
||||
relayTo, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", peer.Endpoint, peer.LocalListenPort))
|
||||
if err == nil {
|
||||
peerConfMap[peer.PublicKey] = manager.PeerConf{
|
||||
IsRelayed: true,
|
||||
RelayedTo: relayTo,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return peers, nil
|
||||
proxyPayload.Peers = peers
|
||||
proxyPayload.PeerMap = peerConfMap
|
||||
proxyPayload.InterfaceName = node.Interface
|
||||
return proxyPayload, nil
|
||||
}
|
||||
|
||||
// GetPeerUpdate - gets a wireguard peer config for each peer of a node
|
||||
|
@ -237,16 +284,6 @@ func GetPeerUpdate(node *models.Node) (models.PeerUpdate, error) {
|
|||
peerUpdate.ServerAddrs = serverNodeAddresses
|
||||
peerUpdate.DNS = getPeerDNS(node.Network)
|
||||
peerUpdate.PeerIDs = peerMap
|
||||
if node.IsRelayed == "yes" {
|
||||
relayNode := FindRelay(node)
|
||||
relayEndpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayNode.Endpoint, relayNode.LocalListenPort))
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to resolve relay node endpoint: ", err.Error())
|
||||
}
|
||||
peerUpdate.IsRelayed = true
|
||||
peerUpdate.RelayTo = relayEndpoint
|
||||
|
||||
}
|
||||
return peerUpdate, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -175,38 +175,12 @@ func ServerJoin(networkSettings *models.Network) (models.Node, error) {
|
|||
if err != nil {
|
||||
return returnNode, err
|
||||
}
|
||||
logger.Log(0, "--------> Hereeeeeee23333")
|
||||
proxyPayload := manager.ManagerPayload{
|
||||
IsRelay: node.IsRelay == "yes",
|
||||
InterfaceName: node.Interface,
|
||||
Peers: peers.Peers,
|
||||
proxyPayload, err := GetPeersForProxy(node, false)
|
||||
if err != nil && !ncutils.IsEmptyRecord(err) {
|
||||
logger.Log(1, "failed to retrieve peers")
|
||||
return returnNode, err
|
||||
}
|
||||
// if proxyPayload.IsRelayed {
|
||||
// relayNode := FindRelay(node)
|
||||
// relayEndpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayNode.Endpoint, relayNode.LocalListenPort))
|
||||
// if err != nil {
|
||||
// logger.Log(1, "failed to resolve relay node endpoint: ", err.Error())
|
||||
// proxyPayload.IsRelayed = false
|
||||
// }
|
||||
// proxyPayload.RelayedTo = relayEndpoint
|
||||
|
||||
// }
|
||||
if proxyPayload.IsRelay {
|
||||
relayedNodes, err := GetRelayedNodes(node)
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to relayed nodes: ", node.Name, err.Error())
|
||||
proxyPayload.IsRelay = false
|
||||
} else {
|
||||
relayPeersMap := make(map[string][]wgtypes.PeerConfig)
|
||||
for _, relayedNode := range relayedNodes {
|
||||
peers, err := GetPeersForProxy(&relayedNode)
|
||||
if err == nil {
|
||||
relayPeersMap[relayedNode.PublicKey] = peers
|
||||
}
|
||||
}
|
||||
proxyPayload.RelayedPeers = relayPeersMap
|
||||
}
|
||||
}
|
||||
ProxyMgmChan <- &manager.ManagerAction{
|
||||
Action: manager.AddInterface,
|
||||
Payload: proxyPayload,
|
||||
|
|
|
@ -161,31 +161,11 @@ func setWGConfig(node *models.Node, peerupdate bool) error {
|
|||
|
||||
}
|
||||
logger.Log(0, "--------> ADD/Update INTERFACE TO PROXY.....")
|
||||
peersP, err := GetPeersForProxy(node)
|
||||
proxyPayload, err := GetPeersForProxy(node, false)
|
||||
if err != nil {
|
||||
logger.Log(0, "failed to get peers for proxy: ", err.Error())
|
||||
} else {
|
||||
proxyPayload := manager.ManagerPayload{
|
||||
IsRelay: node.IsRelay == "yes",
|
||||
InterfaceName: node.Interface,
|
||||
Peers: peersP,
|
||||
}
|
||||
if proxyPayload.IsRelay {
|
||||
relayedNodes, err := GetRelayedNodes(node)
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to relayed nodes: ", node.Name, err.Error())
|
||||
proxyPayload.IsRelay = false
|
||||
} else {
|
||||
relayPeersMap := make(map[string][]wgtypes.PeerConfig)
|
||||
for _, relayedNode := range relayedNodes {
|
||||
peers, err := GetPeersForProxy(&relayedNode)
|
||||
if err == nil {
|
||||
relayPeersMap[relayedNode.PublicKey] = peers
|
||||
}
|
||||
}
|
||||
proxyPayload.RelayedPeers = relayPeersMap
|
||||
}
|
||||
}
|
||||
|
||||
ProxyMgmChan <- &manager.ManagerAction{
|
||||
Action: manager.AddInterface,
|
||||
Payload: proxyPayload,
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/gravitl/netmaker/nm-proxy/manager"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
// PeerUpdate - struct
|
||||
type PeerUpdate struct {
|
||||
Network string `json:"network" bson:"network" yaml:"network"`
|
||||
ServerVersion string `json:"serverversion" bson:"serverversion" yaml:"serverversion"`
|
||||
ServerAddrs []ServerAddr `json:"serveraddrs" bson:"serveraddrs" yaml:"serveraddrs"`
|
||||
Peers []wgtypes.PeerConfig `json:"peers" bson:"peers" yaml:"peers"`
|
||||
DNS string `json:"dns" bson:"dns" yaml:"dns"`
|
||||
PeerIDs PeerMap `json:"peerids" bson:"peerids" yaml:"peerids"`
|
||||
IsRelayed bool `json:"is_relayed" bson:"is_relayed" yaml:"is_relayed"`
|
||||
RelayTo *net.UDPAddr `json:"relay_to" bson:"relay_to" yaml:"relay_to"`
|
||||
Network string `json:"network" bson:"network" yaml:"network"`
|
||||
ServerVersion string `json:"serverversion" bson:"serverversion" yaml:"serverversion"`
|
||||
ServerAddrs []ServerAddr `json:"serveraddrs" bson:"serveraddrs" yaml:"serveraddrs"`
|
||||
Peers []wgtypes.PeerConfig `json:"peers" bson:"peers" yaml:"peers"`
|
||||
DNS string `json:"dns" bson:"dns" yaml:"dns"`
|
||||
PeerIDs PeerMap `json:"peerids" bson:"peerids" yaml:"peerids"`
|
||||
ProxyUpdate manager.ManagerAction `josn:"proxy_update"`
|
||||
}
|
||||
|
||||
// KeyUpdate - key update struct
|
||||
|
|
|
@ -3,7 +3,6 @@ package mq
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
|
@ -12,9 +11,7 @@ import (
|
|||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/nm-proxy/manager"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
// DefaultHandler default message queue handler -- NOT USED
|
||||
|
@ -104,22 +101,6 @@ func UpdateNode(client mqtt.Client, msg mqtt.Message) {
|
|||
if err = PublishPeerUpdate(¤tNode, true); err != nil {
|
||||
logger.Log(0, "error updating peers when node", currentNode.Name, currentNode.ID, "informed the server of an interface change", err.Error())
|
||||
}
|
||||
pubKey, wgErr := wgtypes.ParseKey(newNode.PublicKey)
|
||||
endpoint, udpErr := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", newNode.Endpoint, newNode.LocalListenPort))
|
||||
if wgErr == nil && udpErr == nil {
|
||||
logic.ProxyMgmChan <- &manager.ManagerAction{
|
||||
Action: manager.UpdatePeer,
|
||||
Payload: manager.ManagerPayload{
|
||||
InterfaceName: newNode.Interface,
|
||||
Peers: []wgtypes.PeerConfig{
|
||||
{
|
||||
PublicKey: pubKey,
|
||||
Endpoint: endpoint,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.Log(1, "updated node", id, newNode.Name)
|
||||
|
|
|
@ -26,7 +26,10 @@ func PublishPeerUpdate(newNode *models.Node, publishToSelf bool) error {
|
|||
return err
|
||||
}
|
||||
for _, node := range networkNodes {
|
||||
|
||||
// err := PublishProxyUpdate(manager.AddInterface, &node)
|
||||
// if err != nil {
|
||||
// logger.Log(1, "failed to publish proxy update to node", node.Name, "on network", node.Network, ":", err.Error())
|
||||
// }
|
||||
if node.IsServer == "yes" {
|
||||
continue
|
||||
}
|
||||
|
@ -38,16 +41,40 @@ func PublishPeerUpdate(newNode *models.Node, publishToSelf bool) error {
|
|||
if err != nil {
|
||||
logger.Log(1, "failed to publish peer update to node", node.Name, "on network", node.Network, ":", err.Error())
|
||||
}
|
||||
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func PublishProxyUpdate(action manager.ProxyAction, node *models.Node) error {
|
||||
peerUpdates, err := logic.GetPeersForProxy(node, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ProxyUpdate(&manager.ManagerAction{
|
||||
Action: action,
|
||||
Payload: peerUpdates}, node)
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to send proxy update: ", err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PublishSinglePeerUpdate --- determines and publishes a peer update to one node
|
||||
func PublishSinglePeerUpdate(node *models.Node) error {
|
||||
peerUpdate, err := logic.GetPeerUpdate(node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proxyUpdate, err := logic.GetPeersForProxy(node, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
peerUpdate.ProxyUpdate = manager.ManagerAction{
|
||||
Action: manager.AddInterface,
|
||||
Payload: proxyUpdate,
|
||||
}
|
||||
data, err := json.Marshal(&peerUpdate)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -104,10 +131,14 @@ func NodeUpdate(node *models.Node) error {
|
|||
logger.Log(2, "error publishing node update to peer ", node.ID, err.Error())
|
||||
return err
|
||||
}
|
||||
err = PublishProxyUpdate(manager.AddInterface, node)
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to publish proxy update to node", node.Name, "on network", node.Network, ":", err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//ProxyUpdate -- publishes updates related to proxy
|
||||
//ProxyUpdate -- publishes updates to peers related to proxy
|
||||
func ProxyUpdate(proxyPayload *manager.ManagerAction, node *models.Node) error {
|
||||
if !servercfg.IsMessageQueueBackend() {
|
||||
return nil
|
||||
|
@ -122,7 +153,7 @@ func ProxyUpdate(proxyPayload *manager.ManagerAction, node *models.Node) error {
|
|||
logger.Log(2, "error marshalling node update ", err.Error())
|
||||
return err
|
||||
}
|
||||
if err = publish(node, fmt.Sprintf("update/proxy/%s/%s", node.Network, node.ID), data); err != nil {
|
||||
if err = publish(node, fmt.Sprintf("proxy/%s/%s", node.Network, node.ID), data); err != nil {
|
||||
logger.Log(2, "error publishing node update to peer ", node.ID, err.Error())
|
||||
return err
|
||||
}
|
||||
|
@ -188,6 +219,7 @@ func sendPeers() {
|
|||
if errN != nil {
|
||||
logger.Log(1, errN.Error())
|
||||
}
|
||||
serverctl.SyncServerNetworkWithProxy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ import (
|
|||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/netclient/wireguard"
|
||||
|
||||
nmproxy "github.com/gravitl/netmaker/nm-proxy"
|
||||
"github.com/gravitl/netmaker/nm-proxy/common"
|
||||
"github.com/gravitl/netmaker/nm-proxy/manager"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
@ -158,12 +158,12 @@ func startGoRoutines(wg *sync.WaitGroup) context.CancelFunc {
|
|||
}
|
||||
func GetNodeInfo(cfg *config.ClientConfig) (models.NodeGet, error) {
|
||||
var nodeGET models.NodeGet
|
||||
token, err := common.Authenticate(cfg)
|
||||
token, err := Authenticate(cfg)
|
||||
if err != nil {
|
||||
return nodeGET, err
|
||||
}
|
||||
url := fmt.Sprintf("https://%s/api/nodes/%s/%s", cfg.Server.API, cfg.Network, cfg.Node.ID)
|
||||
response, err := common.API("", http.MethodGet, url, token)
|
||||
response, err := API("", http.MethodGet, url, token)
|
||||
if err != nil {
|
||||
return nodeGET, err
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ func setSubscriptions(client mqtt.Client, nodeCfg *config.ClientConfig) {
|
|||
}
|
||||
return
|
||||
}
|
||||
if token := client.Subscribe(fmt.Sprintf("update/proxy/%s/%s", nodeCfg.Node.Network, nodeCfg.Node.ID), 0, mqtt.MessageHandler(ProxyUpdate)); token.WaitTimeout(mq.MQ_TIMEOUT*time.Second) && token.Error() != nil {
|
||||
if token := client.Subscribe(fmt.Sprintf("proxy/%s/%s", nodeCfg.Node.Network, nodeCfg.Node.ID), 0, mqtt.MessageHandler(ProxyUpdate)); token.WaitTimeout(mq.MQ_TIMEOUT*time.Second) && token.Error() != nil {
|
||||
if token.Error() == nil {
|
||||
logger.Log(0, "network:", nodeCfg.Node.Network, "connection timeout")
|
||||
} else {
|
||||
|
|
|
@ -34,7 +34,7 @@ var All mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
|
|||
func ProxyUpdate(client mqtt.Client, msg mqtt.Message) {
|
||||
var nodeCfg config.ClientConfig
|
||||
var proxyUpdate manager.ManagerAction
|
||||
var network = strings.Split(msg.Topic(), "/")[2]
|
||||
var network = parseNetworkFromTopic(msg.Topic())
|
||||
nodeCfg.Network = network
|
||||
nodeCfg.ReadConfig()
|
||||
|
||||
|
@ -165,12 +165,7 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
|
|||
// }
|
||||
// }
|
||||
// }
|
||||
ProxyMgmChan <- &manager.ManagerAction{
|
||||
Action: manager.AddInterface,
|
||||
Payload: manager.ManagerPayload{
|
||||
IsRelayed: newNode.IsRelay == "yes",
|
||||
},
|
||||
}
|
||||
|
||||
if ifaceDelta { // if a change caused an ifacedelta we need to notify the server to update the peers
|
||||
doneErr := publishSignal(&nodeCfg, ncutils.DONE)
|
||||
if doneErr != nil {
|
||||
|
@ -273,15 +268,7 @@ func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
|
|||
logger.Log(0, "error syncing wg after peer update: "+err.Error())
|
||||
return
|
||||
}
|
||||
ProxyMgmChan <- &manager.ManagerAction{
|
||||
Action: manager.AddInterface,
|
||||
Payload: manager.ManagerPayload{
|
||||
InterfaceName: cfg.Node.Interface,
|
||||
Peers: peerUpdate.Peers,
|
||||
IsRelayed: peerUpdate.IsRelayed,
|
||||
RelayedTo: peerUpdate.RelayTo,
|
||||
},
|
||||
}
|
||||
ProxyMgmChan <- &peerUpdate.ProxyUpdate
|
||||
logger.Log(0, "network:", cfg.Node.Network, "received peer update for node "+cfg.Node.Name+" "+cfg.Node.Network)
|
||||
if cfg.Node.DNSOn == "yes" {
|
||||
if err := setHostDNS(peerUpdate.DNS, cfg.Node.Interface, ncutils.IsWindows()); err != nil {
|
||||
|
@ -294,6 +281,7 @@ func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
_ = UpdateLocalListenPort(&cfg)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,11 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
|
||||
"github.com/gravitl/netmaker/nm-proxy/wg"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
|
@ -94,63 +83,3 @@ func RunCmd(command string, printerr bool) (string, error) {
|
|||
}
|
||||
return string(out), err
|
||||
}
|
||||
|
||||
// API function to interact with netmaker api endpoints. response from endpoint is returned
|
||||
func API(data interface{}, method, url, authorization string) (*http.Response, error) {
|
||||
var request *http.Request
|
||||
var err error
|
||||
if data != "" {
|
||||
payload, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error encoding data %w", err)
|
||||
}
|
||||
request, err = http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating http request %w", err)
|
||||
}
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
} else {
|
||||
request, err = http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating http request %w", err)
|
||||
}
|
||||
}
|
||||
if authorization != "" {
|
||||
request.Header.Set("authorization", "Bearer "+authorization)
|
||||
}
|
||||
request.Header.Set("requestfrom", "node")
|
||||
var httpClient http.Client
|
||||
httpClient.Timeout = time.Minute
|
||||
return httpClient.Do(request)
|
||||
}
|
||||
|
||||
// Authenticate authenticates with api to permit subsequent interactions with the api
|
||||
func Authenticate(cfg *config.ClientConfig) (string, error) {
|
||||
|
||||
pass, err := os.ReadFile(ncutils.GetNetclientPathSpecific() + "secret-" + cfg.Network)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not read secrets file %w", err)
|
||||
}
|
||||
data := models.AuthParams{
|
||||
MacAddress: cfg.Node.MacAddress,
|
||||
ID: cfg.Node.ID,
|
||||
Password: string(pass),
|
||||
}
|
||||
url := "https://" + cfg.Server.API + "/api/nodes/adm/" + cfg.Network + "/authenticate"
|
||||
response, err := API(data, http.MethodPost, url, "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
if response.StatusCode != http.StatusOK {
|
||||
bodybytes, _ := io.ReadAll(response.Body)
|
||||
return "", fmt.Errorf("failed to authenticate %s %s", response.Status, string(bodybytes))
|
||||
}
|
||||
resp := models.SuccessResponse{}
|
||||
if err := json.NewDecoder(response.Body).Decode(&resp); err != nil {
|
||||
return "", fmt.Errorf("error decoding respone %w", err)
|
||||
}
|
||||
tokenData := resp.Response.(map[string]interface{})
|
||||
token := tokenData["AuthToken"]
|
||||
return token.(string), nil
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"net"
|
||||
"runtime"
|
||||
|
||||
"github.com/gravitl/netmaker/netclient/wireguard"
|
||||
"github.com/gravitl/netmaker/nm-proxy/common"
|
||||
peerpkg "github.com/gravitl/netmaker/nm-proxy/peer"
|
||||
"github.com/gravitl/netmaker/nm-proxy/wg"
|
||||
|
@ -18,12 +17,17 @@ import (
|
|||
type ProxyAction string
|
||||
|
||||
type ManagerPayload struct {
|
||||
InterfaceName string
|
||||
Peers []wgtypes.PeerConfig
|
||||
IsRelayed bool
|
||||
RelayedTo *net.UDPAddr
|
||||
IsRelay bool
|
||||
RelayedPeers map[string][]wgtypes.PeerConfig
|
||||
InterfaceName string `json:"interface_name"`
|
||||
Peers []wgtypes.PeerConfig `json:"peers"`
|
||||
PeerMap map[string]PeerConf `json:"peer_map"`
|
||||
IsRelayed bool `json:"is_relayed"`
|
||||
RelayedTo *net.UDPAddr `json:"relayed_to"`
|
||||
IsRelay bool `json:"is_relay"`
|
||||
RelayedPeers map[string][]wgtypes.PeerConfig `json:"relayed_peers"`
|
||||
}
|
||||
type PeerConf struct {
|
||||
IsRelayed bool `json:"is_relayed"`
|
||||
RelayedTo *net.UDPAddr `json:"relayed_to"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -48,6 +52,10 @@ func StartProxyManager(manageChan chan *ManagerAction) {
|
|||
log.Printf("-------> PROXY-MANAGER: %+v\n", mI)
|
||||
switch mI.Action {
|
||||
case AddInterface:
|
||||
common.IsRelay = mI.Payload.IsRelay
|
||||
if mI.Payload.IsRelay {
|
||||
mI.RelayPeers()
|
||||
}
|
||||
err := mI.AddInterfaceToProxy()
|
||||
if err != nil {
|
||||
log.Printf("failed to add interface: [%s] to proxy: %v\n ", mI.Payload.InterfaceName, err)
|
||||
|
@ -161,7 +169,7 @@ func (m *ManagerAction) AddInterfaceToProxy() error {
|
|||
ifaceName := m.Payload.InterfaceName
|
||||
log.Println("--------> IFACE: ", ifaceName)
|
||||
if runtime.GOOS == "darwin" {
|
||||
ifaceName, err = wireguard.GetRealIface(ifaceName)
|
||||
ifaceName, err = wg.GetRealIface(ifaceName)
|
||||
if err != nil {
|
||||
log.Println("failed to get real iface: ", err)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package wg
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -14,7 +18,7 @@ import (
|
|||
const (
|
||||
DefaultMTU = 1280
|
||||
DefaultWgPort = 51820
|
||||
DefaultWgKeepAlive = 25 * time.Second
|
||||
DefaultWgKeepAlive = 20 * time.Second
|
||||
)
|
||||
|
||||
// WGIface represents a interface instance
|
||||
|
@ -103,7 +107,6 @@ func parseAddress(address string) (WGAddress, error) {
|
|||
}
|
||||
|
||||
// UpdatePeer updates existing Wireguard Peer or creates a new one if doesn't exist
|
||||
// Endpoint is optional
|
||||
func (w *WGIface) UpdatePeer(peerKey string, allowedIps []net.IPNet, keepAlive time.Duration, endpoint *net.UDPAddr, preSharedKey *wgtypes.Key) error {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
|
@ -121,9 +124,9 @@ func (w *WGIface) UpdatePeer(peerKey string, allowedIps []net.IPNet, keepAlive t
|
|||
return err
|
||||
}
|
||||
peer := wgtypes.PeerConfig{
|
||||
PublicKey: peerKeyParsed,
|
||||
ReplaceAllowedIPs: true,
|
||||
AllowedIPs: allowedIps,
|
||||
PublicKey: peerKeyParsed,
|
||||
// ReplaceAllowedIPs: true,
|
||||
// AllowedIPs: allowedIps,
|
||||
PersistentKeepaliveInterval: &keepAlive,
|
||||
PresharedKey: preSharedKey,
|
||||
Endpoint: endpoint,
|
||||
|
@ -176,3 +179,58 @@ func (w *WGIface) GetListenPort() (*int, error) {
|
|||
|
||||
return &d.ListenPort, nil
|
||||
}
|
||||
|
||||
// GetRealIface - retrieves tun iface based on reference iface name from config file
|
||||
func GetRealIface(iface string) (string, error) {
|
||||
RunCmd("wg show interfaces", false)
|
||||
ifacePath := "/var/run/wireguard/" + iface + ".name"
|
||||
if !(FileExists(ifacePath)) {
|
||||
return "", errors.New(ifacePath + " does not exist")
|
||||
}
|
||||
realIfaceName, err := GetFileAsString(ifacePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
realIfaceName = strings.TrimSpace(realIfaceName)
|
||||
if !(FileExists(fmt.Sprintf("/var/run/wireguard/%s.sock", realIfaceName))) {
|
||||
return "", errors.New("interface file does not exist")
|
||||
}
|
||||
return realIfaceName, nil
|
||||
}
|
||||
|
||||
// FileExists - checks if file exists locally
|
||||
func FileExists(f string) bool {
|
||||
info, err := os.Stat(f)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
if err != nil && strings.Contains(err.Error(), "not a directory") {
|
||||
return false
|
||||
}
|
||||
if err != nil {
|
||||
log.Println(0, "error reading file: "+f+", "+err.Error())
|
||||
}
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
// GetFileAsString - returns the string contents of a given file
|
||||
func GetFileAsString(path string) (string, error) {
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(content), err
|
||||
}
|
||||
|
||||
// RunCmd - runs a local command
|
||||
func RunCmd(command string, printerr bool) (string, error) {
|
||||
args := strings.Fields(command)
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
cmd.Wait()
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil && printerr {
|
||||
log.Println("error running command: ", command)
|
||||
log.Println(strings.TrimSuffix(string(out), "\n"))
|
||||
}
|
||||
return string(out), err
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/nm-proxy/manager"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -83,33 +82,12 @@ func SyncServerNetworkWithProxy() error {
|
|||
logger.Log(1, "failed to retrieve local server node: ", serverNode.ID)
|
||||
continue
|
||||
}
|
||||
peers, err := logic.GetPeersForProxy(&serverNode)
|
||||
proxyPayload, err := logic.GetPeersForProxy(&serverNode, false)
|
||||
if err != nil && !ncutils.IsEmptyRecord(err) {
|
||||
logger.Log(1, "failed to retrieve peers for server node: ", serverNode.ID)
|
||||
continue
|
||||
}
|
||||
logger.Log(0, "----> HEREEEEEEEE1")
|
||||
proxyPayload := manager.ManagerPayload{
|
||||
IsRelay: serverNode.IsRelay == "yes",
|
||||
InterfaceName: serverNode.Interface,
|
||||
Peers: peers,
|
||||
}
|
||||
if proxyPayload.IsRelay {
|
||||
relayedNodes, err := logic.GetRelayedNodes(&serverNode)
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to relayed nodes: ", serverNode.Name, err.Error())
|
||||
proxyPayload.IsRelay = false
|
||||
} else {
|
||||
relayPeersMap := make(map[string][]wgtypes.PeerConfig)
|
||||
for _, relayedNode := range relayedNodes {
|
||||
peers, err := logic.GetPeersForProxy(&relayedNode)
|
||||
if err == nil {
|
||||
relayPeersMap[relayedNode.PublicKey] = peers
|
||||
}
|
||||
}
|
||||
proxyPayload.RelayedPeers = relayPeersMap
|
||||
}
|
||||
}
|
||||
logic.ProxyMgmChan <- &manager.ManagerAction{
|
||||
Action: manager.AddInterface,
|
||||
Payload: proxyPayload,
|
||||
|
|
Loading…
Add table
Reference in a new issue