Przeglądaj źródła

NM-116: Acl Fixes (#3652)

* handle all resources tag on gw

* add egress domain ranges to node acls

* simplify extclient egress alloweips, handle nil acl rule

* fix static node status check for gw acls

* skip ns ip if contains network cidr

* skip ns ip if contains network cidr

* skip ns ip if contains network cidr
Abhishek K 22 godzin temu
rodzic
commit
aa913d6870
6 zmienionych plików z 107 dodań i 28 usunięć
  1. 47 8
      logic/acls.go
  2. 19 0
      logic/dns.go
  3. 3 14
      logic/extpeers.go
  4. 5 4
      logic/peers.go
  5. 13 2
      migrate/migrate.go
  6. 20 0
      pro/logic/dns.go

+ 47 - 8
logic/acls.go

@@ -50,16 +50,31 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
 	if defaultDevicePolicy.Enabled {
 		return
 	}
+	defer func() {
+		if len(rules) == 0 && IsNodeAllowedToCommunicateWithAllRsrcs(node) {
+			if node.NetworkRange.IP != nil {
+				rules = append(rules, models.FwRule{
+					SrcIP: node.NetworkRange,
+					Allow: true,
+				})
+			}
+			if node.NetworkRange6.IP != nil {
+				rules = append(rules, models.FwRule{
+					SrcIP: node.NetworkRange6,
+					Allow: true,
+				})
+			}
+			return
+		}
+	}()
+
 	for _, nodeI := range nodes {
 		if !nodeI.IsStatic || nodeI.IsUserNode {
 			continue
 		}
-		if !node.StaticNode.Enabled {
+		if !nodeI.StaticNode.Enabled {
 			continue
 		}
-		// if nodeI.StaticNode.IngressGatewayID != node.ID.String() {
-		// 	continue
-		// }
 		if IsNodeAllowedToCommunicateWithAllRsrcs(nodeI) {
 			if nodeI.Address.IP != nil {
 				rules = append(rules, models.FwRule{
@@ -525,7 +540,18 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
 						continue
 					}
 					if _, ok := eI.Nodes[targetnode.ID.String()]; ok {
-						if eI.Range != "" {
+						if servercfg.IsPro && eI.Domain != "" && len(eI.DomainAns) > 0 {
+							for _, domainAnsI := range eI.DomainAns {
+								ip, cidr, err := net.ParseCIDR(domainAnsI)
+								if err == nil {
+									if ip.To4() != nil {
+										egressRanges4 = append(egressRanges4, *cidr)
+									} else {
+										egressRanges6 = append(egressRanges6, *cidr)
+									}
+								}
+							}
+						} else if eI.Range != "" {
 							_, cidr, err := net.ParseCIDR(eI.Range)
 							if err == nil {
 								if cidr.IP.To4() != nil {
@@ -535,6 +561,7 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
 								}
 							}
 						}
+						dstTags[targetnode.ID.String()] = struct{}{}
 					}
 				}
 				break
@@ -544,7 +571,18 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
 				err := e.Get(db.WithContext(context.TODO()))
 				if err == nil && e.Status && len(e.Nodes) > 0 {
 					if _, ok := e.Nodes[targetnode.ID.String()]; ok {
-						if e.Range != "" {
+						if servercfg.IsPro && e.Domain != "" && len(e.DomainAns) > 0 {
+							for _, domainAnsI := range e.DomainAns {
+								ip, cidr, err := net.ParseCIDR(domainAnsI)
+								if err == nil {
+									if ip.To4() != nil {
+										egressRanges4 = append(egressRanges4, *cidr)
+									} else {
+										egressRanges6 = append(egressRanges6, *cidr)
+									}
+								}
+							}
+						} else if e.Range != "" {
 							_, cidr, err := net.ParseCIDR(e.Range)
 							if err == nil {
 								if cidr.IP.To4() != nil {
@@ -554,6 +592,7 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
 								}
 							}
 						}
+						dstTags[targetnode.ID.String()] = struct{}{}
 					}
 
 				}
@@ -800,10 +839,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 						if node.ID == targetnode.ID {
 							continue
 						}
-						if node.Address.IP != nil {
+						if !node.IsStatic && node.Address.IP != nil {
 							aclRule.IPList = append(aclRule.IPList, node.AddressIPNet4())
 						}
-						if node.Address6.IP != nil {
+						if !node.IsStatic && node.Address6.IP != nil {
 							aclRule.IP6List = append(aclRule.IP6List, node.AddressIPNet6())
 						}
 						if node.IsStatic && node.StaticNode.Address != "" {

+ 19 - 0
logic/dns.go

@@ -434,6 +434,25 @@ func validateNameserverReq(ns schema.Nameserver) error {
 	if len(ns.Servers) == 0 {
 		return errors.New("atleast one nameserver should be specified")
 	}
+	network, err := GetNetwork(ns.NetworkID)
+	if err != nil {
+		return errors.New("invalid network id")
+	}
+	_, cidr, err4 := net.ParseCIDR(network.AddressRange)
+	_, cidr6, err6 := net.ParseCIDR(network.AddressRange6)
+	for _, nsIPStr := range ns.Servers {
+		nsIP := net.ParseIP(nsIPStr)
+		if nsIP == nil {
+			return errors.New("invalid nameserver " + nsIPStr)
+		}
+		if err4 == nil && nsIP.To4() != nil {
+			if cidr.Contains(nsIP) {
+				return errors.New("cannot use netmaker IP as nameserver")
+			}
+		} else if err6 == nil && cidr6.Contains(nsIP) {
+			return errors.New("cannot use netmaker IP as nameserver")
+		}
+	}
 	if !ns.MatchAll && len(ns.MatchDomains) == 0 {
 		return errors.New("atleast one match domain is required")
 	}

+ 3 - 14
logic/extpeers.go

@@ -70,23 +70,12 @@ func storeExtClientInCache(key string, extclient models.ExtClient) {
 func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) {
 
 	var result []string
-	networkNodes, err := GetNetworkNodes(client.Network)
-	if err != nil {
-		return []string{}, err
-	}
 	eli, _ := (&schema.Egress{Network: client.Network}).ListByNetwork(db.WithContext(context.TODO()))
-	acls, _ := ListAclsByNetwork(models.NetworkID(client.Network))
-	// clientNode := client.ConvertToStaticNode()
-	for _, currentNode := range networkNodes {
-		if currentNode.Network != client.Network {
+	for _, eI := range eli {
+		if !eI.Status || eI.Range == "" {
 			continue
 		}
-		GetNodeEgressInfo(&currentNode, eli, acls)
-		if currentNode.EgressDetails.IsEgressGateway { // add the egress gateway range(s) to the result
-			if len(currentNode.EgressDetails.EgressGatewayRanges) > 0 {
-				result = append(result, currentNode.EgressDetails.EgressGatewayRanges...)
-			}
-		}
+		result = append(result, eI.Range)
 	}
 	extclients, _ := GetNetworkExtClients(client.Network)
 	for _, extclient := range extclients {

+ 5 - 4
logic/peers.go

@@ -149,10 +149,11 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 	}
 	defer func() {
 		if !hostPeerUpdate.FwUpdate.AllowAll {
-
-			hostPeerUpdate.FwUpdate.EgressInfo["allowed-network-rules"] = models.EgressInfo{
-				EgressID:      "allowed-network-rules",
-				EgressFwRules: make(map[string]models.AclRule),
+			if len(hostPeerUpdate.FwUpdate.AllowedNetworks) > 0 {
+				hostPeerUpdate.FwUpdate.EgressInfo["allowed-network-rules"] = models.EgressInfo{
+					EgressID:      "allowed-network-rules",
+					EgressFwRules: make(map[string]models.AclRule),
+				}
 			}
 			for _, aclRule := range hostPeerUpdate.FwUpdate.AllowedNetworks {
 				hostPeerUpdate.FwUpdate.AclRules[aclRule.ID] = aclRule

+ 13 - 2
migrate/migrate.go

@@ -5,6 +5,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"log"
+	"net"
 	"os"
 	"time"
 
@@ -63,6 +64,10 @@ func migrateNameservers() {
 	}
 
 	for _, netI := range nets {
+		_, cidr, err := net.ParseCIDR(netI.AddressRange)
+		if err != nil {
+			continue
+		}
 		if len(netI.NameServers) > 0 {
 			ns := schema.Nameserver{
 				ID:           uuid.NewString(),
@@ -78,8 +83,14 @@ func migrateNameservers() {
 				Status:    true,
 				CreatedBy: user.UserName,
 			}
-			for _, ip := range netI.NameServers {
-				ns.Servers = append(ns.Servers, ip)
+
+			for _, nsIP := range netI.NameServers {
+				if net.ParseIP(nsIP) == nil {
+					continue
+				}
+				if !cidr.Contains(net.ParseIP(nsIP)) {
+					ns.Servers = append(ns.Servers, nsIP)
+				}
 			}
 			ns.Create(db.WithContext(context.TODO()))
 			netI.NameServers = []string{}

+ 20 - 0
pro/logic/dns.go

@@ -3,6 +3,7 @@ package logic
 import (
 	"context"
 	"errors"
+	"net"
 
 	"github.com/gravitl/netmaker/db"
 	"github.com/gravitl/netmaker/logic"
@@ -20,6 +21,25 @@ func ValidateNameserverReq(ns schema.Nameserver) error {
 	if len(ns.Servers) == 0 {
 		return errors.New("atleast one nameserver should be specified")
 	}
+	network, err := logic.GetNetwork(ns.NetworkID)
+	if err != nil {
+		return errors.New("invalid network id")
+	}
+	_, cidr, err4 := net.ParseCIDR(network.AddressRange)
+	_, cidr6, err6 := net.ParseCIDR(network.AddressRange6)
+	for _, nsIPStr := range ns.Servers {
+		nsIP := net.ParseIP(nsIPStr)
+		if nsIP == nil {
+			return errors.New("invalid nameserver " + nsIPStr)
+		}
+		if err4 == nil && nsIP.To4() != nil {
+			if cidr.Contains(nsIP) {
+				return errors.New("cannot use netmaker IP as nameserver")
+			}
+		} else if err6 == nil && cidr6.Contains(nsIP) {
+			return errors.New("cannot use netmaker IP as nameserver")
+		}
+	}
 	if !ns.MatchAll && len(ns.MatchDomains) == 0 {
 		return errors.New("atleast one match domain is required")
 	}