Explorar o código

apply egress policies for devices

abhishek9686 hai 6 meses
pai
achega
70210907c8
Modificáronse 4 ficheiros con 113 adicións e 54 borrados
  1. 107 24
      logic/acls.go
  2. 3 0
      logic/nodes.go
  3. 3 28
      logic/peers.go
  4. 0 2
      models/mqtt.go

+ 107 - 24
logic/acls.go

@@ -1289,6 +1289,93 @@ func RemoveDeviceTagFromAclPolicies(tagID models.TagID, netID models.NetworkID)
 	return nil
 }
 
+func getEgressUserRulesForNode(targetnode *models.Node,
+	rules map[string]models.AclRule) map[string]models.AclRule {
+	userNodes := GetStaticUserNodesByNetwork(models.NetworkID(targetnode.Network))
+	userGrpMap := GetUserGrpMap()
+	allowedUsers := make(map[string][]models.Acl)
+	acls := listUserPolicies(models.NetworkID(targetnode.Network))
+	var targetNodeTags = make(map[models.TagID]struct{})
+	targetNodeTags["*"] = struct{}{}
+	for _, rangeI := range targetnode.EgressGatewayRanges {
+		targetNodeTags[models.TagID(rangeI)] = struct{}{}
+	}
+	for _, acl := range acls {
+		if !acl.Enabled {
+			continue
+		}
+		dstTags := convAclTagToValueMap(acl.Dst)
+		_, all := dstTags["*"]
+		addUsers := false
+		if !all {
+			for nodeTag := range targetNodeTags {
+				if _, ok := dstTags[nodeTag.String()]; !ok {
+					if _, ok = dstTags[targetnode.ID.String()]; !ok {
+						break
+					}
+				}
+			}
+		} else {
+			addUsers = true
+		}
+
+		if addUsers {
+			// get all src tags
+			for _, srcAcl := range acl.Src {
+				if srcAcl.ID == models.UserAclID {
+					allowedUsers[srcAcl.Value] = append(allowedUsers[srcAcl.Value], acl)
+				} else if srcAcl.ID == models.UserGroupAclID {
+					// fetch all users in the group
+					if usersMap, ok := userGrpMap[models.UserGroupID(srcAcl.Value)]; ok {
+						for userName := range usersMap {
+							allowedUsers[userName] = append(allowedUsers[userName], acl)
+						}
+					}
+				}
+			}
+		}
+
+	}
+
+	for _, userNode := range userNodes {
+		if !userNode.StaticNode.Enabled {
+			continue
+		}
+		acls, ok := allowedUsers[userNode.StaticNode.OwnerID]
+		if !ok {
+			continue
+		}
+		for _, acl := range acls {
+
+			if !acl.Enabled {
+				continue
+			}
+			r := models.AclRule{
+				ID:              acl.ID,
+				AllowedProtocol: acl.Proto,
+				AllowedPorts:    acl.Port,
+				Direction:       acl.AllowedDirection,
+				Allowed:         true,
+			}
+			// Get peers in the tags and add allowed rules
+			if userNode.StaticNode.Address != "" {
+				r.IPList = append(r.IPList, userNode.StaticNode.AddressIPNet4())
+			}
+			if userNode.StaticNode.Address6 != "" {
+				r.IP6List = append(r.IP6List, userNode.StaticNode.AddressIPNet6())
+			}
+			if aclRule, ok := rules[acl.ID]; ok {
+				aclRule.IPList = append(aclRule.IPList, r.IPList...)
+				aclRule.IP6List = append(aclRule.IP6List, r.IP6List...)
+				rules[acl.ID] = aclRule
+			} else {
+				rules[acl.ID] = r
+			}
+		}
+	}
+	return rules
+}
+
 func getUserAclRulesForNode(targetnode *models.Node,
 	rules map[string]models.AclRule) map[string]models.AclRule {
 	userNodes := GetStaticUserNodesByNetwork(models.NetworkID(targetnode.Network))
@@ -1398,6 +1485,9 @@ func checkIfAnyPolicyisUniDirectional(targetNode models.Node) bool {
 		if acl.AllowedDirection == models.TrafficDirectionBi {
 			continue
 		}
+		if acl.Proto != models.ALL || acl.ServiceType != models.Any {
+			return true
+		}
 		srcTags := convAclTagToValueMap(acl.Src)
 		dstTags := convAclTagToValueMap(acl.Dst)
 		for nodeTag := range targetNodeTags {
@@ -1424,7 +1514,6 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
 		if !targetnode.IsIngressGateway {
 			rules = getUserAclRulesForNode(&targetnode, rules)
 		}
-
 	}()
 	rules = make(map[string]models.AclRule)
 	var taggedNodes map[models.TagID][]models.Node
@@ -1445,16 +1534,6 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
 	}
 	targetNodeTags[models.TagID(targetnode.ID.String())] = struct{}{}
 	targetNodeTags["*"] = struct{}{}
-	/*
-		 if target node is egress gateway
-			if acl policy has egress route and it is present in target node egress ranges
-			fetches all the nodes in that policy and add rules
-	*/
-	if targetnode.IsEgressGateway {
-		for _, rangeI := range targetnode.EgressGatewayRanges {
-			targetNodeTags[models.TagID(rangeI)] = struct{}{}
-		}
-	}
 	for _, acl := range acls {
 		if !acl.Enabled {
 			continue
@@ -1647,22 +1726,25 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
 
 func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclRule) {
 	rules = make(map[string]models.AclRule)
-
-	taggedNodes := GetTagMapWithNodesByNetwork(models.NetworkID(targetnode.Network), false)
+	defer func() {
+		rules = getEgressUserRulesForNode(&targetnode, rules)
+	}()
+	taggedNodes := GetTagMapWithNodesByNetwork(models.NetworkID(targetnode.Network), true)
 
 	acls := listDevicePolicies(models.NetworkID(targetnode.Network))
 	var targetNodeTags = make(map[models.TagID]struct{})
 	targetNodeTags["*"] = struct{}{}
+
 	/*
 		 if target node is egress gateway
 			if acl policy has egress route and it is present in target node egress ranges
 			fetches all the nodes in that policy and add rules
 	*/
-	if targetnode.IsEgressGateway {
-		for _, rangeI := range targetnode.EgressGatewayRanges {
-			targetNodeTags[models.TagID(rangeI)] = struct{}{}
-		}
+
+	for _, rangeI := range targetnode.EgressGatewayRanges {
+		targetNodeTags[models.TagID(rangeI)] = struct{}{}
 	}
+	fmt.Println("TAGETR NODE TAGS: ", targetNodeTags)
 	for _, acl := range acls {
 		if !acl.Enabled {
 			continue
@@ -1671,8 +1753,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 		dstTags := convAclTagToValueMap(acl.Dst)
 		_, srcAll := srcTags["*"]
 		_, dstAll := dstTags["*"]
-
+		fmt.Println("====> SRC TAGS: ", srcTags)
+		fmt.Println("====> DST TAGS: ", dstTags)
 		for nodeTag := range targetNodeTags {
+			fmt.Println("====> CHECKINg NODE TAG: ", nodeTag)
 			aclRule := models.AclRule{
 				ID:              acl.ID,
 				AllowedProtocol: acl.Proto,
@@ -1737,9 +1821,6 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 							if node.ID == targetnode.ID {
 								continue
 							}
-							if node.IsStatic && node.StaticNode.IngressGatewayID == targetnode.ID.String() {
-								continue
-							}
 							if node.Address.IP != nil {
 								aclRule.IPList = append(aclRule.IPList, node.AddressIPNet4())
 							}
@@ -1833,22 +1914,23 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 					}
 				}
 			} else {
+				fmt.Println("====> HEREEEEEE 4 ", nodeTag)
 				_, all := dstTags["*"]
 				if _, ok := dstTags[nodeTag.String()]; ok || all {
 					// get all src tags
+					fmt.Println("====> HEREEEEEE 5 ", nodeTag, srcTags)
 					for src := range srcTags {
 						if src == nodeTag.String() {
 							continue
 						}
+						fmt.Println("===> checking SRC: 1", src)
 						// Get peers in the tags and add allowed rules
 						nodes := taggedNodes[models.TagID(src)]
+						fmt.Println("===> checking SRC: 2 ", src, nodes)
 						for _, node := range nodes {
 							if node.ID == targetnode.ID {
 								continue
 							}
-							if node.IsStatic && node.StaticNode.IngressGatewayID == targetnode.ID.String() {
-								continue
-							}
 							if node.Address.IP != nil {
 								aclRule.IPList = append(aclRule.IPList, node.AddressIPNet4())
 							}
@@ -1862,6 +1944,7 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 								aclRule.IP6List = append(aclRule.IP6List, node.StaticNode.AddressIPNet6())
 							}
 						}
+						fmt.Printf("ACL: RUELS: %+v\n", aclRule)
 					}
 				}
 			}

+ 3 - 0
logic/nodes.go

@@ -866,6 +866,9 @@ func GetTagMapWithNodesByNetwork(netID models.NetworkID, withStaticNodes bool) (
 			nodeI.Mutex.Lock()
 		}
 		for nodeTagID := range nodeI.Tags {
+			if nodeTagID == models.TagID(nodeI.ID.String()) {
+				continue
+			}
 			tagNodesMap[nodeTagID] = append(tagNodesMap[nodeTagID], nodeI)
 		}
 		if nodeI.Mutex != nil {

+ 3 - 28
logic/peers.go

@@ -440,7 +440,6 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 						IngressID:     node.ID.String(),
 						Network:       node.NetworkRange,
 						Network6:      node.NetworkRange6,
-						AllowAll:      defaultDevicePolicy.Enabled && defaultUserPolicy.Default,
 						StaticNodeIps: GetStaticNodeIps(node),
 						Rules:         GetFwRulesOnIngressGateway(node),
 					}
@@ -480,38 +479,14 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 
 		}
 		if node.IsEgressGateway {
-			if networkAllowAll {
-				// get egress ranges
-				for _, egressRangeI := range node.EgressGatewayRanges {
-					ip, cidr, err := net.ParseCIDR(egressRangeI)
-					if err != nil {
-						continue
-					}
-					egressInfo := hostPeerUpdate.FwUpdate.EgressInfo[node.ID.String()]
-					if egressInfo.EgressFwRules == nil {
-						egressInfo.EgressFwRules = make(map[string]models.AclRule)
-					}
-					if ip.To4() != nil && node.NetworkRange.IP != nil {
-
-						egressInfo.EgressFwRules[egressRangeI] = models.AclRule{
-							IPList:  []net.IPNet{node.NetworkRange},
-							Dst:     *cidr,
-							Allowed: true,
-						}
-					} else if ip.To16() != nil {
-						egressInfo.EgressFwRules[egressRangeI] = models.AclRule{
-							IP6List: []net.IPNet{node.NetworkRange6},
-							Dst6:    *cidr,
-							Allowed: true,
-						}
-					}
-				}
-			} else {
+			if !networkAllowAll {
+				fmt.Println("======>1 HEREEEEE")
 				egressInfo := hostPeerUpdate.FwUpdate.EgressInfo[node.ID.String()]
 				if egressInfo.EgressFwRules == nil {
 					egressInfo.EgressFwRules = make(map[string]models.AclRule)
 				}
 				egressInfo.EgressFwRules = GetEgressRulesForNode(node)
+				hostPeerUpdate.FwUpdate.EgressInfo[node.ID.String()] = egressInfo
 			}
 
 		}

+ 0 - 2
models/mqtt.go

@@ -53,7 +53,6 @@ type IngressInfo struct {
 	Network6      net.IPNet   `json:"network6"`
 	StaticNodeIps []net.IP    `json:"static_node_ips"`
 	Rules         []FwRule    `json:"rules"`
-	AllowAll      bool        `json:"allow_all"`
 	EgressRanges  []net.IPNet `json:"egress_ranges"`
 	EgressRanges6 []net.IPNet `json:"egress_ranges6"`
 }
@@ -107,7 +106,6 @@ type KeyUpdate struct {
 type FwUpdate struct {
 	AllowAll        bool                   `json:"allow_all"`
 	AllowedNetworks []net.IPNet            `json:"networks"`
-	EgressNetworks  []string               `json:"egress_networks"`
 	IsEgressGw      bool                   `json:"is_egress_gw"`
 	IsIngressGw     bool                   `json:"is_ingress_gw"`
 	EgressInfo      map[string]EgressInfo  `json:"egress_info"`