Kaynağa Gözat

add extclient egress ranges

abhishek9686 10 ay önce
ebeveyn
işleme
ebc3e90301
7 değiştirilmiş dosya ile 137 ekleme ve 93 silme
  1. 3 10
      controllers/acls.go
  2. 23 30
      logic/acls.go
  3. 90 22
      logic/extpeers.go
  4. 2 1
      logic/peers.go
  5. 2 16
      models/acl.go
  6. 9 8
      models/mqtt.go
  7. 8 6
      pro/logic/user_mgmt.go

+ 3 - 10
controllers/acls.go

@@ -7,6 +7,7 @@ import (
 	"net/url"
 	"time"
 
+	"github.com/google/uuid"
 	"github.com/gorilla/mux"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
@@ -128,7 +129,7 @@ func createAcl(w http.ResponseWriter, r *http.Request) {
 	}
 
 	acl := req
-	acl.GetID(req.NetworkID, req.Name)
+	acl.ID = uuid.New().String()
 	acl.CreatedBy = user.UserName
 	acl.CreatedAt = time.Now().UTC()
 	acl.Default = false
@@ -187,14 +188,6 @@ func updateAcl(w http.ResponseWriter, r *http.Request) {
 	}
 	if !acl.Default && updateAcl.NewName != "" {
 		//check if policy exists with same name
-		id := models.FormatAclID(updateAcl.NetworkID, updateAcl.NewName)
-		_, err := logic.GetAcl(id)
-		if err == nil {
-			logic.ReturnErrorResponse(w, r,
-				logic.FormatError(errors.New("policy already exists with name "+updateAcl.NewName), "badrequest"))
-			return
-		}
-		updateAcl.ID = id
 		updateAcl.Acl.Name = updateAcl.NewName
 	}
 	err = logic.UpdateAcl(updateAcl.Acl, acl)
@@ -218,7 +211,7 @@ func deleteAcl(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("acl id is required"), "badrequest"))
 		return
 	}
-	acl, err := logic.GetAcl(models.AclID(aclID))
+	acl, err := logic.GetAcl(aclID)
 	if err != nil {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return

+ 23 - 30
logic/acls.go

@@ -16,10 +16,11 @@ func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
 	if netID.String() == "" {
 		return
 	}
-	if !IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, "all-nodes"))) {
+	if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-nodes")) {
 		defaultDeviceAcl := models.Acl{
-			ID:        models.AclID(fmt.Sprintf("%s.%s", netID, "all-nodes")),
-			Name:      "all-nodes",
+			ID:        fmt.Sprintf("%s.%s", netID, "all-nodes"),
+			Name:      "All Nodes",
+			MetaData:  "This Policy allows all nodes in the network to communicate with each other",
 			Default:   true,
 			NetworkID: netID,
 			RuleType:  models.DevicePolicy,
@@ -40,11 +41,12 @@ func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
 		}
 		InsertAcl(defaultDeviceAcl)
 	}
-	if !IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, "all-users"))) {
+	if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-users")) {
 		defaultUserAcl := models.Acl{
-			ID:        models.AclID(fmt.Sprintf("%s.%s", netID, "all-users")),
+			ID:        fmt.Sprintf("%s.%s", netID, "all-users"),
 			Default:   true,
-			Name:      "all-users",
+			Name:      "All Users",
+			MetaData:  "This policy gives access to everything in the network for an user",
 			NetworkID: netID,
 			RuleType:  models.UserPolicy,
 			Src: []models.AclPolicyTag{
@@ -69,11 +71,11 @@ func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
 		InsertAcl(defaultUserAcl)
 	}
 
-	if !IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, "all-remote-access-gws"))) {
+	if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-remote-access-gws")) {
 		defaultUserAcl := models.Acl{
-			ID:        models.AclID(fmt.Sprintf("%s.%s", netID, "all-remote-access-gws")),
+			ID:        fmt.Sprintf("%s.%s", netID, "all-remote-access-gws"),
 			Default:   true,
-			Name:      "all-remote-access-gws",
+			Name:      "All Remote Access Gateways",
 			NetworkID: netID,
 			RuleType:  models.DevicePolicy,
 			Src: []models.AclPolicyTag{
@@ -115,15 +117,10 @@ func ValidateCreateAclReq(req models.Acl) error {
 	if err != nil {
 		return errors.New("failed to get network details for " + req.NetworkID.String())
 	}
-	err = CheckIDSyntax(req.Name)
-	if err != nil {
-		return err
-	}
-	req.GetID(req.NetworkID, req.Name)
-	_, err = GetAcl(req.ID)
-	if err == nil {
-		return errors.New("acl exists already with name " + req.Name)
-	}
+	// err = CheckIDSyntax(req.Name)
+	// if err != nil {
+	// 	return err
+	// }
 	return nil
 }
 
@@ -133,13 +130,13 @@ func InsertAcl(a models.Acl) error {
 	if err != nil {
 		return err
 	}
-	return database.Insert(a.ID.String(), string(d), database.ACLS_TABLE_NAME)
+	return database.Insert(a.ID, string(d), database.ACLS_TABLE_NAME)
 }
 
 // GetAcl - gets acl info by id
-func GetAcl(aID models.AclID) (models.Acl, error) {
+func GetAcl(aID string) (models.Acl, error) {
 	a := models.Acl{}
-	d, err := database.FetchRecord(database.ACLS_TABLE_NAME, aID.String())
+	d, err := database.FetchRecord(database.ACLS_TABLE_NAME, aID)
 	if err != nil {
 		return a, err
 	}
@@ -151,7 +148,7 @@ func GetAcl(aID models.AclID) (models.Acl, error) {
 }
 
 // IsAclExists - checks if acl exists
-func IsAclExists(aclID models.AclID) bool {
+func IsAclExists(aclID string) bool {
 	_, err := GetAcl(aclID)
 	return err == nil
 }
@@ -252,15 +249,11 @@ func UpdateAcl(newAcl, acl models.Acl) error {
 		acl.Dst = newAcl.Dst
 	}
 	acl.Enabled = newAcl.Enabled
-	if acl.ID != newAcl.ID {
-		database.DeleteRecord(database.ACLS_TABLE_NAME, acl.ID.String())
-		acl.ID = newAcl.ID
-	}
 	d, err := json.Marshal(acl)
 	if err != nil {
 		return err
 	}
-	return database.Insert(acl.ID.String(), string(d), database.ACLS_TABLE_NAME)
+	return database.Insert(acl.ID, string(d), database.ACLS_TABLE_NAME)
 }
 
 // UpsertAcl - upserts acl
@@ -269,12 +262,12 @@ func UpsertAcl(acl models.Acl) error {
 	if err != nil {
 		return err
 	}
-	return database.Insert(acl.ID.String(), string(d), database.ACLS_TABLE_NAME)
+	return database.Insert(acl.ID, string(d), database.ACLS_TABLE_NAME)
 }
 
 // DeleteAcl - deletes acl policy
 func DeleteAcl(a models.Acl) error {
-	return database.DeleteRecord(database.ACLS_TABLE_NAME, a.ID.String())
+	return database.DeleteRecord(database.ACLS_TABLE_NAME, a.ID)
 }
 
 // GetDefaultPolicy - fetches default policy in the network by ruleType
@@ -283,7 +276,7 @@ func GetDefaultPolicy(netID models.NetworkID, ruleType models.AclPolicyType) (mo
 	if ruleType == models.DevicePolicy {
 		aclID = "all-nodes"
 	}
-	acl, err := GetAcl(models.AclID(fmt.Sprintf("%s.%s", netID, aclID)))
+	acl, err := GetAcl(fmt.Sprintf("%s.%s", netID, aclID))
 	if err != nil {
 		return models.Acl{}, errors.New("default rule not found")
 	}

+ 90 - 22
logic/extpeers.go

@@ -443,39 +443,62 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
 					if userNodeI.StaticNode.Address != "" {
 						if !defaultUserPolicy.Enabled {
 							rules = append(rules, models.FwRule{
-								SrcIp: userNodeI.StaticNode.AddressIPNet4().IP,
-								DstIP: peer.StaticNode.AddressIPNet4().IP,
+								SrcIP: userNodeI.StaticNode.AddressIPNet4(),
+								DstIP: peer.StaticNode.AddressIPNet4(),
 								Allow: true,
 							})
 						}
 						rules = append(rules, models.FwRule{
-							SrcIp: peer.StaticNode.AddressIPNet4().IP,
-							DstIP: userNodeI.StaticNode.AddressIPNet4().IP,
+							SrcIP: peer.StaticNode.AddressIPNet4(),
+							DstIP: userNodeI.StaticNode.AddressIPNet4(),
 							Allow: true,
 						})
 					}
 					if userNodeI.StaticNode.Address6 != "" {
 						if !defaultUserPolicy.Enabled {
 							rules = append(rules, models.FwRule{
-								SrcIp: userNodeI.StaticNode.AddressIPNet6().IP,
-								DstIP: peer.StaticNode.AddressIPNet6().IP,
+								SrcIP: userNodeI.StaticNode.AddressIPNet6(),
+								DstIP: peer.StaticNode.AddressIPNet6(),
 								Allow: true,
 							})
 						}
 
 						rules = append(rules, models.FwRule{
-							SrcIp: peer.StaticNode.AddressIPNet6().IP,
-							DstIP: userNodeI.StaticNode.AddressIPNet6().IP,
+							SrcIP: peer.StaticNode.AddressIPNet6(),
+							DstIP: userNodeI.StaticNode.AddressIPNet6(),
 							Allow: true,
 						})
 					}
+					if len(peer.StaticNode.ExtraAllowedIPs) > 0 {
+						for _, additionalAllowedIPNet := range peer.StaticNode.ExtraAllowedIPs {
+							_, ipNet, err := net.ParseCIDR(additionalAllowedIPNet)
+							if err != nil {
+								continue
+							}
+							if ipNet.IP.To4() != nil {
+								rules = append(rules, models.FwRule{
+									SrcIP: userNodeI.StaticNode.AddressIPNet4(),
+									DstIP: *ipNet,
+									Allow: true,
+								})
+							} else {
+								rules = append(rules, models.FwRule{
+									SrcIP: userNodeI.StaticNode.AddressIPNet6(),
+									DstIP: *ipNet,
+									Allow: true,
+								})
+							}
+
+						}
+
+					}
 				} else {
 
 					if userNodeI.StaticNode.Address != "" {
 						if !defaultUserPolicy.Enabled {
 							rules = append(rules, models.FwRule{
-								SrcIp: userNodeI.StaticNode.AddressIPNet4().IP,
-								DstIP: peer.Address.IP,
+								SrcIP: userNodeI.StaticNode.AddressIPNet4(),
+								DstIP: peer.Address,
 								Allow: true,
 							})
 						}
@@ -483,8 +506,8 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
 
 					if userNodeI.StaticNode.Address6 != "" {
 						rules = append(rules, models.FwRule{
-							SrcIp: userNodeI.StaticNode.AddressIPNet6().IP,
-							DstIP: peer.Address6.IP,
+							SrcIP: userNodeI.StaticNode.AddressIPNet6(),
+							DstIP: peer.Address6,
 							Allow: true,
 						})
 					}
@@ -509,30 +532,53 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
 				if peer.IsStatic {
 					if nodeI.StaticNode.Address != "" {
 						rules = append(rules, models.FwRule{
-							SrcIp: nodeI.StaticNode.AddressIPNet4().IP,
-							DstIP: peer.StaticNode.AddressIPNet4().IP,
+							SrcIP: nodeI.StaticNode.AddressIPNet4(),
+							DstIP: peer.StaticNode.AddressIPNet4(),
 							Allow: true,
 						})
 					}
 					if nodeI.StaticNode.Address6 != "" {
 						rules = append(rules, models.FwRule{
-							SrcIp: nodeI.StaticNode.AddressIPNet6().IP,
-							DstIP: peer.StaticNode.AddressIPNet6().IP,
+							SrcIP: nodeI.StaticNode.AddressIPNet6(),
+							DstIP: peer.StaticNode.AddressIPNet6(),
 							Allow: true,
 						})
 					}
+					if len(peer.StaticNode.ExtraAllowedIPs) > 0 {
+						for _, additionalAllowedIPNet := range peer.StaticNode.ExtraAllowedIPs {
+							_, ipNet, err := net.ParseCIDR(additionalAllowedIPNet)
+							if err != nil {
+								continue
+							}
+							if ipNet.IP.To4() != nil {
+								rules = append(rules, models.FwRule{
+									SrcIP: nodeI.StaticNode.AddressIPNet4(),
+									DstIP: *ipNet,
+									Allow: true,
+								})
+							} else {
+								rules = append(rules, models.FwRule{
+									SrcIP: nodeI.StaticNode.AddressIPNet6(),
+									DstIP: *ipNet,
+									Allow: true,
+								})
+							}
+
+						}
+
+					}
 				} else {
 					if nodeI.StaticNode.Address != "" {
 						rules = append(rules, models.FwRule{
-							SrcIp: nodeI.StaticNode.AddressIPNet4().IP,
-							DstIP: peer.Address.IP,
+							SrcIP: nodeI.StaticNode.AddressIPNet4(),
+							DstIP: peer.Address,
 							Allow: true,
 						})
 					}
 					if nodeI.StaticNode.Address6 != "" {
 						rules = append(rules, models.FwRule{
-							SrcIp: nodeI.StaticNode.AddressIPNet6().IP,
-							DstIP: peer.Address6.IP,
+							SrcIP: nodeI.StaticNode.AddressIPNet6(),
+							DstIP: peer.Address6,
 							Allow: true,
 						})
 					}
@@ -642,8 +688,30 @@ func getExtPeerEgressRoute(node models.Node, extPeer models.ExtClient) (egressRo
 	return
 }
 
-func getExtpeersExtraRoutes(node models.Node, network string) (egressRoutes []models.EgressNetworkRoutes) {
-	extPeers, err := GetNetworkExtClients(network)
+func getExtpeerEgressRanges(node models.Node) (ranges []net.IPNet) {
+	extPeers, err := GetNetworkExtClients(node.Network)
+	if err != nil {
+		return
+	}
+	for _, extPeer := range extPeers {
+		if len(extPeer.ExtraAllowedIPs) == 0 {
+			continue
+		}
+		if !IsNodeAllowedToCommunicate(extPeer.ConvertToStaticNode(), node) {
+			continue
+		}
+		for _, allowedRange := range extPeer.ExtraAllowedIPs {
+			_, ipnet, err := net.ParseCIDR(allowedRange)
+			if err == nil {
+				ranges = append(ranges, *ipnet)
+			}
+		}
+	}
+
+}
+
+func getExtpeersExtraRoutes(node models.Node) (egressRoutes []models.EgressNetworkRoutes) {
+	extPeers, err := GetNetworkExtClients(node.Network)
 	if err != nil {
 		return
 	}

+ 2 - 1
logic/peers.go

@@ -183,7 +183,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 				})
 			}
 			if peer.IsIngressGateway {
-				hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(node, peer.Network)...)
+				hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(node)...)
 			}
 			_, isFailOverPeer := node.FailOverPeers[peer.ID.String()]
 			if servercfg.IsPro {
@@ -301,6 +301,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 						Network6:      node.NetworkRange6,
 						AllowAll:      defaultDevicePolicy.Enabled && defaultUserPolicy.Default,
 						StaticNodeIps: GetStaticNodeIps(node),
+						EgressRanges:  getExtpeerEgressRanges(node),
 						Rules:         GetFwRulesOnIngressGateway(node),
 					}
 					hostPeerUpdate.FwUpdate.IngressInfo[node.ID.String()] = ingFwUpdate

+ 2 - 16
models/acl.go

@@ -1,24 +1,9 @@
 package models
 
 import (
-	"fmt"
 	"time"
 )
 
-type AclID string
-
-func (aID AclID) String() string {
-	return string(aID)
-}
-
-func (a *Acl) GetID(netID NetworkID, name string) {
-	a.ID = AclID(fmt.Sprintf("%s.%s", netID.String(), name))
-}
-
-func FormatAclID(netID NetworkID, name string) AclID {
-	return AclID(fmt.Sprintf("%s.%s", netID.String(), name))
-}
-
 // AllowedTrafficDirection - allowed direction of traffic
 type AllowedTrafficDirection int
 
@@ -66,8 +51,9 @@ type AclPolicy struct {
 }
 
 type Acl struct {
-	ID               AclID                   `json:"id"`
+	ID               string                  `json:"id"`
 	Default          bool                    `json:"default"`
+	MetaData         string                  `json:"meta_data"`
 	Name             string                  `json:"name"`
 	NetworkID        NetworkID               `json:"network_id"`
 	RuleType         AclPolicyType           `json:"policy_type"`

+ 9 - 8
models/mqtt.go

@@ -27,19 +27,20 @@ type HostPeerUpdate struct {
 }
 
 type FwRule struct {
-	SrcIp net.IP
-	DstIP net.IP
+	SrcIP net.IPNet
+	DstIP net.IPNet
 	Allow bool
 }
 
 // IngressInfo - struct for ingress info
 type IngressInfo struct {
-	IngressID     string    `json:"ingress_id"`
-	Network       net.IPNet `json:"network"`
-	Network6      net.IPNet `json:"network6"`
-	StaticNodeIps []net.IP  `json:"static_node_ips"`
-	Rules         []FwRule  `json:"rules"`
-	AllowAll      bool      `json:"allow_all"`
+	IngressID     string      `json:"ingress_id"`
+	Network       net.IPNet   `json:"network"`
+	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"`
 }
 
 // EgressInfo - struct for egress info

+ 8 - 6
pro/logic/user_mgmt.go

@@ -1141,10 +1141,11 @@ func CreateDefaultUserPolicies(netID models.NetworkID) {
 		return
 	}
 
-	if !logic.IsAclExists(models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin))) {
+	if !logic.IsAclExists(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin)) {
 		defaultUserAcl := models.Acl{
-			ID:        models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin)),
-			Name:      fmt.Sprintf("%s-grp", models.NetworkAdmin),
+			ID:        fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin),
+			Name:      "Network Admin",
+			MetaData:  "This Policy allows all network admins to communicate with all remote access gateways",
 			Default:   true,
 			NetworkID: netID,
 			RuleType:  models.UserPolicy,
@@ -1166,10 +1167,11 @@ func CreateDefaultUserPolicies(netID models.NetworkID) {
 		logic.InsertAcl(defaultUserAcl)
 	}
 
-	if !logic.IsAclExists(models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser))) {
+	if !logic.IsAclExists(fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser)) {
 		defaultUserAcl := models.Acl{
-			ID:        models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser)),
-			Name:      fmt.Sprintf("%s-grp", models.NetworkUser),
+			ID:        fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser),
+			Name:      "Network User",
+			MetaData:  "This Policy allows all network users to communicate with all remote access gateways",
 			Default:   true,
 			NetworkID: netID,
 			RuleType:  models.UserPolicy,