Prechádzať zdrojové kódy

get allowed IPs for overlapping networks

Abhishek Kondur 2 rokov pred
rodič
commit
4204dee156
4 zmenil súbory, kde vykonal 100 pridanie a 91 odobranie
  1. 66 36
      logic/peers.go
  2. 3 19
      logic/relay.go
  3. 1 1
      models/structs.go
  4. 30 35
      mq/publishers.go

+ 66 - 36
logic/peers.go

@@ -63,7 +63,7 @@ func NodePeersInfo(client *models.Client) (models.NodePeersInfo, error) {
 			peerConfig.Endpoint.IP = peer.LocalAddress.IP
 			peerConfig.Endpoint.Port = peerHost.ListenPort
 		}
-		allowedips := GetAllowedIPs(&models.Client{Host: *peerHost, Node: peer})
+		allowedips := GetNetworkAllowedIPs(&models.Client{Host: *peerHost, Node: peer})
 		if peer.IsIngressGateway {
 			for _, entry := range peer.IngressGatewayRange {
 				_, cidr, err := net.ParseCIDR(string(entry))
@@ -158,7 +158,7 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
 				PersistentKeepaliveInterval: &peer.PersistentKeepalive,
 				ReplaceAllowedIPs:           true,
 			}
-			if (node.IsRelayed && node.RelayedBy != peer.ID.String()) || shouldRemovePeer(node, peer) {
+			if (node.IsRelayed && node.RelayedBy != peer.ID.String()) || ShouldRemovePeer(node, peer) {
 				// if node is relayed and peer is not the relay, set remove to true
 				peerConfig.Remove = true
 				hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
@@ -187,7 +187,8 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
 				peerConfig.Endpoint.IP = peer.LocalAddress.IP
 				peerConfig.Endpoint.Port = peerHost.ListenPort
 			}
-			allowedips := GetAllowedIPs(&models.Client{Host: *peerHost, Node: peer})
+			peerConfig.AllowedIPs = GetNetworkAllowedIPs(&models.Client{Host: *peerHost, Node: peer})
+
 			if _, ok := peerIndexMap[peerHost.PublicKey.String()]; !ok {
 				hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
 				peerIndexMap[peerHost.PublicKey.String()] = len(hostPeerUpdate.Peers) - 1
@@ -196,7 +197,7 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
 				}
 			} else {
 				peerAllowedIPs := hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].AllowedIPs
-				peerAllowedIPs = append(peerAllowedIPs, allowedips...)
+				peerAllowedIPs = append(peerAllowedIPs, peerConfig.AllowedIPs...)
 				hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].Remove = false
 				hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].AllowedIPs = peerAllowedIPs
 			}
@@ -216,9 +217,10 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
 	return hostPeerUpdate, nil
 }
 
-func shouldRemovePeer(node, peer models.Node) (remove bool) {
+func ShouldRemovePeer(node, peer models.Node) (remove bool) {
 	if peer.Action == models.NODE_DELETE || peer.PendingDelete || !peer.Connected ||
-		!nodeacls.AreNodesAllowed(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), nodeacls.NodeID(peer.ID.String())) {
+		!nodeacls.AreNodesAllowed(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), nodeacls.NodeID(peer.ID.String())) ||
+		(node.IsRelayed && node.RelayedBy != peer.ID.String()) {
 		remove = true
 	}
 	return
@@ -436,8 +438,65 @@ func GetExtPeers(node *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, e
 
 }
 
+func getNodeByNetworkFromHost(h *models.Host, network string) *models.Node {
+	for _, nodeID := range h.Nodes {
+		node, err := GetNodeByID(nodeID)
+		if err == nil && node.Network == network {
+			return &node
+		}
+	}
+	return nil
+}
+
 // GetAllowedIPs - calculates the wireguard allowedip field for a peer of a node based on the peer and node settings
-func GetAllowedIPs(peer *models.Client) []net.IPNet {
+func GetAllowedIPs(client, peer *models.Client) []net.IPNet {
+	var allowedips []net.IPNet
+	for _, nodeID := range peer.Host.Nodes {
+		node, err := GetNodeByID(nodeID)
+		if err != nil {
+			continue
+		}
+		clientNode := getNodeByNetworkFromHost(&client.Host, node.Network)
+		if clientNode == nil {
+			continue
+		}
+
+		peer.Node = node
+		if ShouldRemovePeer(*clientNode, peer.Node) {
+			continue
+		}
+		if peer.Node.Address.IP != nil {
+			allowed := net.IPNet{
+				IP:   peer.Node.Address.IP,
+				Mask: net.CIDRMask(32, 32),
+			}
+			allowedips = append(allowedips, allowed)
+		}
+		if peer.Node.Address6.IP != nil {
+			allowed := net.IPNet{
+				IP:   peer.Node.Address6.IP,
+				Mask: net.CIDRMask(128, 128),
+			}
+			allowedips = append(allowedips, allowed)
+		}
+		// handle egress gateway peers
+		if peer.Node.IsEgressGateway {
+			allowedips = append(allowedips, getEgressIPs(peer)...)
+		}
+		if peer.Node.IsRelay {
+			allowedips = append(allowedips, getRelayAllowedIPs(peer)...)
+		}
+		// handle ingress gateway peers
+		if peer.Node.IsIngressGateway {
+			allowedips = append(allowedips, getIngressIPs(peer)...)
+		}
+	}
+
+	return allowedips
+}
+
+// GetNetworkAllowedIPs - calculates the wireguard allowedip field for a peer of a node based on the peer and node settings
+func GetNetworkAllowedIPs(peer *models.Client) []net.IPNet {
 	var allowedips []net.IPNet
 	if peer.Node.Address.IP != nil {
 		allowed := net.IPNet{
@@ -546,35 +605,6 @@ func filterNodeMapForClientACLs(publicKey, network string, nodePeerMap map[strin
 	return nodePeerMap
 }
 
-func AddHostAllowedIPs(h *models.Host) []net.IPNet {
-	allowedIPs := []net.IPNet{}
-	for _, hNodeID := range h.Nodes {
-		node, err := GetNodeByID(hNodeID)
-		if err != nil {
-			continue
-		}
-		if node.Address.IP != nil {
-			node.Address.Mask = net.CIDRMask(32, 32)
-			allowedIPs = append(allowedIPs, node.Address)
-		}
-		if node.Address6.IP != nil {
-			node.Address6.Mask = net.CIDRMask(128, 128)
-			allowedIPs = append(allowedIPs, node.Address6)
-		}
-		if node.IsEgressGateway {
-			allowedIPs = append(allowedIPs, getEgressIPs(&models.Client{Host: *h, Node: node})...)
-		}
-		if node.IsIngressGateway {
-			allowedIPs = append(allowedIPs, getIngressIPs(&models.Client{Host: *h, Node: node})...)
-		}
-		if node.IsRelay {
-			allowedIPs = append(allowedIPs, getRelayAllowedIPs(&models.Client{Host: *h, Node: node})...)
-		}
-	}
-	return allowedIPs
-
-}
-
 // getRelayAllowedIPs returns the list of allowedips for a peer that is a relay
 func getRelayAllowedIPs(peer *models.Client) []net.IPNet {
 	var relayIPs []net.IPNet

+ 3 - 19
logic/relay.go

@@ -8,7 +8,6 @@ import (
 
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/logger"
-	"github.com/gravitl/netmaker/logic/acls/nodeacls"
 	"github.com/gravitl/netmaker/models"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
@@ -155,32 +154,17 @@ func GetPeerConfForRelayed(relayed, relay *models.Client) wgtypes.PeerConfig {
 		},
 		PersistentKeepaliveInterval: &relay.Node.PersistentKeepalive,
 	}
-	if relay.Node.Address.IP != nil {
-		relay.Node.Address.Mask = net.CIDRMask(32, 32)
-		update.AllowedIPs = append(update.AllowedIPs, relay.Node.Address)
-	}
-	if relay.Node.Address6.IP != nil {
-		relay.Node.Address6.Mask = net.CIDRMask(128, 128)
-		update.AllowedIPs = append(update.AllowedIPs, relay.Node.Address6)
-	}
-	if relay.Node.IsEgressGateway {
-		update.AllowedIPs = append(update.AllowedIPs, getEgressIPs(relay)...)
-	}
-	if relay.Node.IsIngressGateway {
-		update.AllowedIPs = append(update.AllowedIPs, getIngressIPs(relay)...)
-	}
+
 	peers, err := GetNetworkClients(relay.Node.Network)
 	if err != nil {
 		logger.Log(0, "error getting network clients", err.Error())
 		return update
 	}
 	for _, peer := range peers {
-		if peer.Host.ID == relayed.Host.ID || peer.Host.ID == relay.Host.ID {
+		if peer.Host.ID == relayed.Host.ID {
 			continue
 		}
-		if nodeacls.AreNodesAllowed(nodeacls.NetworkID(relayed.Node.Network), nodeacls.NodeID(relayed.Node.ID.String()), nodeacls.NodeID(peer.Node.ID.String())) {
-			update.AllowedIPs = append(update.AllowedIPs, GetAllowedIPs(&peer)...)
-		}
+		update.AllowedIPs = append(update.AllowedIPs, GetAllowedIPs(relayed, &peer)...)
 	}
 	return update
 }

+ 1 - 1
models/structs.go

@@ -155,7 +155,7 @@ type EgressGatewayRequest struct {
 type RelayRequest struct {
 	NodeID       string   `json:"nodeid"`
 	NetID        string   `json:"netid"`
-	RelayedNodes []string `json:"relayednodes"`
+	RelayedNodes []string `json:"relayaddrs"`
 }
 
 // HostRelayRequest - struct for host relay creation

+ 30 - 35
mq/publishers.go

@@ -9,7 +9,6 @@ import (
 
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
-	"github.com/gravitl/netmaker/logic/acls/nodeacls"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/servercfg"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
@@ -49,24 +48,7 @@ func FlushNetworkPeersToHost(client *models.Client, networkClients []models.Clie
 			// skip self
 			continue
 		}
-		if clientI.Node.IsRelayed && (clientI.Node.RelayedBy != client.Node.ID.String()) {
-			// remove this peer, will be added to relay node's allowed ips
-			rmPeerAction.Peers = append(rmPeerAction.Peers, wgtypes.PeerConfig{
-				PublicKey: clientI.Host.PublicKey,
-				Remove:    true,
-			})
-			continue
-		}
-
-		if !nodeacls.AreNodesAllowed(nodeacls.NetworkID(clientI.Node.Network), nodeacls.NodeID(client.Node.ID.String()), nodeacls.NodeID(clientI.Node.ID.String())) ||
-			client.Node.Action == models.NODE_DELETE || client.Node.PendingDelete || !client.Node.Connected || (client.Node.IsRelayed && client.Node.RelayedBy != clientI.Node.ID.String()) {
-			// remove peer if not allowed
-			rmPeerAction.Peers = append(rmPeerAction.Peers, wgtypes.PeerConfig{
-				PublicKey: clientI.Host.PublicKey,
-				Remove:    true,
-			})
-			continue
-		}
+		allowedIPs := logic.GetAllowedIPs(client, &clientI)
 		peerCfg := wgtypes.PeerConfig{
 			PublicKey: clientI.Host.PublicKey,
 			Endpoint: &net.UDPAddr{
@@ -75,8 +57,18 @@ func FlushNetworkPeersToHost(client *models.Client, networkClients []models.Clie
 			},
 			PersistentKeepaliveInterval: &clientI.Node.PersistentKeepalive,
 			ReplaceAllowedIPs:           true,
-			AllowedIPs:                  logic.GetAllowedIPs(&clientI),
+			AllowedIPs:                  allowedIPs,
+		}
+
+		if len(peerCfg.AllowedIPs) == 0 || (client.Node.IsRelayed && (client.Node.RelayedBy != clientI.Node.ID.String())) {
+			// remove peer if not allowed
+			rmPeerAction.Peers = append(rmPeerAction.Peers, wgtypes.PeerConfig{
+				PublicKey: clientI.Host.PublicKey,
+				Remove:    true,
+			})
+			continue
 		}
+
 		addPeerAction.Peers = append(addPeerAction.Peers, peerCfg)
 	}
 	if client.Node.IsRelayed {
@@ -97,12 +89,6 @@ func FlushNetworkPeersToHost(client *models.Client, networkClients []models.Clie
 		relayPeerCfg := logic.GetPeerConfForRelayed(relayedClient, relayClient)
 		addPeerAction.Peers = append(addPeerAction.Peers, relayPeerCfg)
 	}
-	if client.Node.IsIngressGateway {
-		extPeers, _, err := logic.GetExtPeers(&client.Node)
-		if err == nil {
-			addPeerAction.Peers = append(addPeerAction.Peers, extPeers...)
-		}
-	}
 	if len(rmPeerAction.Peers) > 0 {
 		data, err := json.Marshal(rmPeerAction)
 		if err != nil {
@@ -136,7 +122,13 @@ func BroadcastDelPeer(host *models.Host, networkClients []models.Client) error {
 		Peers: []wgtypes.PeerConfig{
 			{
 				PublicKey: host.PublicKey,
-				Remove:    true,
+				Endpoint: &net.UDPAddr{
+					IP:   host.EndpointIP,
+					Port: logic.GetPeerListenPort(host),
+				},
+				ReplaceAllowedIPs: true,
+				UpdateOnly:        true,
+				Remove:            true,
 			},
 		},
 	}
@@ -149,6 +141,12 @@ func BroadcastDelPeer(host *models.Host, networkClients []models.Client) error {
 			// skip self...
 			continue
 		}
+		allowedIPs := logic.GetAllowedIPs(&clientI, &models.Client{Host: *host})
+		if len(allowedIPs) != 0 {
+			p.Peers[0].Remove = false
+			p.Peers[0].AllowedIPs = allowedIPs
+
+		}
 		publish(&clientI.Host, fmt.Sprintf("peer/host/%s/%s", clientI.Host.ID.String(), servercfg.GetServer()), data)
 		if clientI.Node.IsIngressGateway || clientI.Node.IsEgressGateway {
 			go func(peerHost models.Host) {
@@ -188,16 +186,13 @@ func BroadcastHostUpdate(host *models.Host, remove bool) error {
 					IP:   host.EndpointIP,
 					Port: logic.GetPeerListenPort(host),
 				},
-				ReplaceAllowedIPs: true,
-				Remove:            remove,
+				UpdateOnly: true,
+				Remove:     remove,
 			},
 		},
 	}
 	if remove {
 		p.Action = models.RemovePeer
-	} else {
-		p.Peers[0].AllowedIPs = logic.AddHostAllowedIPs(host)
-		fmt.Println(0, "Allowed IPs: ", p.Peers[0].AllowedIPs)
 	}
 	peerHosts := logic.GetRelatedHosts(host.ID.String())
 	data, err := json.Marshal(p)
@@ -242,12 +237,12 @@ func BroadcastAddOrUpdateNetworkPeer(client *models.Client, update bool) error {
 			continue
 		}
 		// update allowed ips, according to the peer node
-		p.Peers[0].AllowedIPs = logic.GetAllowedIPs(&models.Client{Host: client.Host, Node: client.Node})
-		if update && (!nodeacls.AreNodesAllowed(nodeacls.NetworkID(client.Node.Network), nodeacls.NodeID(client.Node.ID.String()), nodeacls.NodeID(clientI.Node.ID.String())) ||
-			client.Node.Action == models.NODE_DELETE || client.Node.PendingDelete || !client.Node.Connected) {
+		p.Peers[0].AllowedIPs = logic.GetAllowedIPs(&clientI, &models.Client{Host: client.Host, Node: client.Node})
+		if update && len(p.Peers[0].AllowedIPs) == 0 {
 			// remove peer
 			p.Action = models.RemovePeer
 			p.Peers[0].Remove = true
+
 		}
 		peerHost, err := logic.GetHost(clientI.Host.ID.String())
 		if err != nil {