Skip to content

Commit 64c6472

Browse files
authored
NM-103: User Acls fixes (#3638)
* fix all rsrcs comms * fix static checks * fix egress acls on CE * check for all resources access on a node * simplify egress acl rules * merged ce and pro acl rule func * fix uni direction acl rule for static nodes * allow relayed nodes traffic * remove anywhere dst rule on user node acls * fix: broadcast user groups update for acl changes * add egress ranges to DST * add all egress ranges for all resources
1 parent a323223 commit 64c6472

File tree

4 files changed

+175
-26
lines changed

4 files changed

+175
-26
lines changed

logic/acls.go

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,33 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
417417
Dst: []net.IPNet{targetnode.AddressIPNet4()},
418418
Dst6: []net.IPNet{targetnode.AddressIPNet6()},
419419
}
420+
e := schema.Egress{Network: targetnode.Network}
421+
egressRanges4 := []net.IPNet{}
422+
egressRanges6 := []net.IPNet{}
423+
eli, _ := e.ListByNetwork(db.WithContext(context.Background()))
424+
for _, eI := range eli {
425+
if !eI.Status || len(eI.Nodes) == 0 {
426+
continue
427+
}
428+
if _, ok := eI.Nodes[targetnode.ID.String()]; ok {
429+
if eI.Range != "" {
430+
_, cidr, err := net.ParseCIDR(eI.Range)
431+
if err == nil {
432+
if cidr.IP.To4() != nil {
433+
egressRanges4 = append(egressRanges4, *cidr)
434+
} else {
435+
egressRanges6 = append(egressRanges6, *cidr)
436+
}
437+
}
438+
}
439+
}
440+
}
441+
if len(egressRanges4) > 0 {
442+
aclRule.Dst = append(aclRule.Dst, egressRanges4...)
443+
}
444+
if len(egressRanges6) > 0 {
445+
aclRule.Dst6 = append(aclRule.Dst6, egressRanges6...)
446+
}
420447
rules[aclRule.ID] = aclRule
421448
return
422449
}
@@ -446,16 +473,51 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
446473
}
447474
srcTags := ConvAclTagToValueMap(acl.Src)
448475
dstTags := ConvAclTagToValueMap(acl.Dst)
476+
egressRanges4 := []net.IPNet{}
477+
egressRanges6 := []net.IPNet{}
449478
for _, dst := range acl.Dst {
479+
if dst.Value == "*" {
480+
e := schema.Egress{Network: targetnode.Network}
481+
eli, _ := e.ListByNetwork(db.WithContext(context.Background()))
482+
for _, eI := range eli {
483+
if !eI.Status || len(eI.Nodes) == 0 {
484+
continue
485+
}
486+
if _, ok := eI.Nodes[targetnode.ID.String()]; ok {
487+
if eI.Range != "" {
488+
_, cidr, err := net.ParseCIDR(eI.Range)
489+
if err == nil {
490+
if cidr.IP.To4() != nil {
491+
egressRanges4 = append(egressRanges4, *cidr)
492+
} else {
493+
egressRanges6 = append(egressRanges6, *cidr)
494+
}
495+
}
496+
}
497+
}
498+
}
499+
break
500+
}
450501
if dst.ID == models.EgressID {
451502
e := schema.Egress{ID: dst.Value}
452503
err := e.Get(db.WithContext(context.TODO()))
453-
if err == nil && e.Status {
454-
for nodeID := range e.Nodes {
455-
dstTags[nodeID] = struct{}{}
504+
if err == nil && e.Status && len(e.Nodes) > 0 {
505+
if _, ok := e.Nodes[targetnode.ID.String()]; ok {
506+
if e.Range != "" {
507+
_, cidr, err := net.ParseCIDR(e.Range)
508+
if err == nil {
509+
if cidr.IP.To4() != nil {
510+
egressRanges4 = append(egressRanges4, *cidr)
511+
} else {
512+
egressRanges6 = append(egressRanges6, *cidr)
513+
}
514+
}
515+
}
456516
}
517+
457518
}
458519
}
520+
459521
}
460522
_, srcAll := srcTags["*"]
461523
_, dstAll := dstTags["*"]
@@ -468,6 +530,12 @@ func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRu
468530
Dst: []net.IPNet{targetnode.AddressIPNet4()},
469531
Dst6: []net.IPNet{targetnode.AddressIPNet6()},
470532
}
533+
if len(egressRanges4) > 0 {
534+
aclRule.Dst = append(aclRule.Dst, egressRanges4...)
535+
}
536+
if len(egressRanges6) > 0 {
537+
aclRule.Dst6 = append(aclRule.Dst6, egressRanges6...)
538+
}
471539
for nodeTag := range targetNodeTags {
472540
if acl.AllowedDirection == models.TrafficDirectionBi {
473541
var existsInSrcTag bool

logic/extpeers.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -705,22 +705,6 @@ func GetExtclientAllowedIPs(client models.ExtClient) (allowedIPs []string) {
705705
return
706706
}
707707

708-
func GetStaticUserNodesByNetwork(network models.NetworkID) (staticNode []models.Node) {
709-
extClients, err := GetAllExtClients()
710-
if err != nil {
711-
return
712-
}
713-
for _, extI := range extClients {
714-
if extI.Network == network.String() {
715-
if extI.RemoteAccessClientID != "" {
716-
n := extI.ConvertToStaticNode()
717-
staticNode = append(staticNode, n)
718-
}
719-
}
720-
}
721-
return
722-
}
723-
724708
func GetStaticNodesByNetwork(network models.NetworkID, onlyWg bool) (staticNode []models.Node) {
725709
extClients, err := GetAllExtClients()
726710
if err != nil {

pro/controllers/users.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ func updateUserGroup(w http.ResponseWriter, r *http.Request) {
566566
},
567567
Origin: models.Dashboard,
568568
})
569-
569+
replacePeers := false
570570
go func() {
571571
networksAdded := make([]models.NetworkID, 0)
572572
networksRemoved := make([]models.NetworkID, 0)
@@ -617,6 +617,7 @@ func updateUserGroup(w http.ResponseWriter, r *http.Request) {
617617
CreatedAt: time.Now().UTC(),
618618
}
619619
_ = logic.InsertAcl(acl)
620+
replacePeers = true
620621
}
621622

622623
// since this group doesn't have a role for this network,
@@ -648,13 +649,15 @@ func updateUserGroup(w http.ResponseWriter, r *http.Request) {
648649
acl.Src = newAclSrc
649650
_ = logic.UpsertAcl(acl)
650651
}
652+
replacePeers = true
651653
}
652654
}
653655
}
654656
}()
655657

656658
// reset configs for service user
657659
go proLogic.UpdatesUserGwAccessOnGrpUpdates(userGroup.ID, currUserG.NetworkRoles, userGroup.NetworkRoles)
660+
go mq.PublishPeerUpdate(replacePeers)
658661
logic.ReturnSuccessResponseWithJson(w, r, userGroup, "updated user group")
659662
}
660663

@@ -826,7 +829,7 @@ func deleteUserGroup(w http.ResponseWriter, r *http.Request) {
826829
},
827830
Origin: models.Dashboard,
828831
})
829-
832+
replacePeers := false
830833
go func() {
831834
for networkID := range userG.NetworkRoles {
832835
acls, err := logic.ListAclsByNetwork(networkID)
@@ -854,13 +857,14 @@ func deleteUserGroup(w http.ResponseWriter, r *http.Request) {
854857
acl.Src = newAclSrc
855858
_ = logic.UpsertAcl(acl)
856859
}
860+
replacePeers = true
857861
}
858862
}
859863
}
860864
}()
861865

862866
go proLogic.UpdatesUserGwAccessOnGrpUpdates(userG.ID, userG.NetworkRoles, make(map[models.NetworkID]map[models.UserRoleID]struct{}))
863-
go mq.PublishPeerUpdate(false)
867+
go mq.PublishPeerUpdate(replacePeers)
864868
logic.ReturnSuccessResponseWithJson(w, r, nil, "deleted user group")
865869
}
866870

pro/logic/acls.go

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,25 @@ import (
1212
"github.com/gravitl/netmaker/schema"
1313
)
1414

15+
func getStaticUserNodesByNetwork(network models.NetworkID) (staticNode []models.Node) {
16+
extClients, err := logic.GetAllExtClients()
17+
if err != nil {
18+
return
19+
}
20+
for _, extI := range extClients {
21+
if extI.Network == network.String() {
22+
if extI.RemoteAccessClientID != "" {
23+
n := extI.ConvertToStaticNode()
24+
staticNode = append(staticNode, n)
25+
}
26+
}
27+
}
28+
return
29+
}
30+
1531
func GetFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []models.FwRule) {
1632
defaultUserPolicy, _ := logic.GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
17-
userNodes := logic.GetStaticUserNodesByNetwork(models.NetworkID(node.Network))
33+
userNodes := getStaticUserNodesByNetwork(models.NetworkID(node.Network))
1834
for _, userNodeI := range userNodes {
1935
if defaultUserPolicy.Enabled {
2036
if userNodeI.StaticNode.Address != "" {
@@ -767,7 +783,7 @@ func RemoveDeviceTagFromAclPolicies(tagID models.TagID, netID models.NetworkID)
767783

768784
func GetEgressUserRulesForNode(targetnode *models.Node,
769785
rules map[string]models.AclRule) map[string]models.AclRule {
770-
userNodes := logic.GetStaticUserNodesByNetwork(models.NetworkID(targetnode.Network))
786+
userNodes := getStaticUserNodesByNetwork(models.NetworkID(targetnode.Network))
771787
userGrpMap := GetUserGrpMap()
772788
allowedUsers := make(map[string][]models.Acl)
773789
acls := listUserPolicies(models.NetworkID(targetnode.Network))
@@ -896,7 +912,6 @@ func GetEgressUserRulesForNode(targetnode *models.Node,
896912
if err != nil {
897913
continue
898914
}
899-
900915
ip, cidr, err := net.ParseCIDR(e.Range)
901916
if err == nil {
902917
if ip.To4() != nil {
@@ -927,7 +942,7 @@ func GetEgressUserRulesForNode(targetnode *models.Node,
927942

928943
func GetUserAclRulesForNode(targetnode *models.Node,
929944
rules map[string]models.AclRule) map[string]models.AclRule {
930-
userNodes := logic.GetStaticUserNodesByNetwork(models.NetworkID(targetnode.Network))
945+
userNodes := getStaticUserNodesByNetwork(models.NetworkID(targetnode.Network))
931946
userGrpMap := GetUserGrpMap()
932947
allowedUsers := make(map[string][]models.Acl)
933948
acls := listUserPolicies(models.NetworkID(targetnode.Network))
@@ -953,6 +968,17 @@ func GetUserAclRulesForNode(targetnode *models.Node,
953968
_, all := dstTags["*"]
954969
addUsers := false
955970
if !all {
971+
for _, dst := range acl.Dst {
972+
if dst.ID == models.EgressID {
973+
e := schema.Egress{ID: dst.Value}
974+
err := e.Get(db.WithContext(context.TODO()))
975+
if err == nil && e.Status && len(e.Nodes) > 0 {
976+
if _, ok := e.Nodes[targetnode.ID.String()]; ok {
977+
dstTags[targetnode.ID.String()] = struct{}{}
978+
}
979+
}
980+
}
981+
}
956982
for nodeTag := range targetNodeTags {
957983
if _, ok := dstTags[nodeTag.String()]; ok {
958984
addUsers = true
@@ -1017,13 +1043,68 @@ func GetUserAclRulesForNode(targetnode *models.Node,
10171043
if !acl.Enabled {
10181044
continue
10191045
}
1046+
egressRanges4 := []net.IPNet{}
1047+
egressRanges6 := []net.IPNet{}
1048+
1049+
for _, dst := range acl.Dst {
1050+
if dst.Value == "*" {
1051+
e := schema.Egress{Network: targetnode.Network}
1052+
eli, _ := e.ListByNetwork(db.WithContext(context.Background()))
1053+
for _, eI := range eli {
1054+
if !eI.Status || len(eI.Nodes) == 0 {
1055+
continue
1056+
}
1057+
if _, ok := eI.Nodes[targetnode.ID.String()]; ok {
1058+
if eI.Range != "" {
1059+
_, cidr, err := net.ParseCIDR(eI.Range)
1060+
if err == nil {
1061+
if cidr.IP.To4() != nil {
1062+
egressRanges4 = append(egressRanges4, *cidr)
1063+
} else {
1064+
egressRanges6 = append(egressRanges6, *cidr)
1065+
}
1066+
}
1067+
}
1068+
}
1069+
}
1070+
break
1071+
}
1072+
if dst.ID == models.EgressID {
1073+
e := schema.Egress{ID: dst.Value}
1074+
err := e.Get(db.WithContext(context.TODO()))
1075+
if err == nil && e.Status && len(e.Nodes) > 0 {
1076+
if _, ok := e.Nodes[targetnode.ID.String()]; ok {
1077+
if e.Range != "" {
1078+
_, cidr, err := net.ParseCIDR(e.Range)
1079+
if err == nil {
1080+
if cidr.IP.To4() != nil {
1081+
egressRanges4 = append(egressRanges4, *cidr)
1082+
} else {
1083+
egressRanges6 = append(egressRanges6, *cidr)
1084+
}
1085+
}
1086+
}
1087+
}
1088+
1089+
}
1090+
}
1091+
1092+
}
10201093
r := models.AclRule{
10211094
ID: acl.ID,
10221095
AllowedProtocol: acl.Proto,
10231096
AllowedPorts: acl.Port,
10241097
Direction: acl.AllowedDirection,
1098+
Dst: []net.IPNet{targetnode.AddressIPNet4()},
1099+
Dst6: []net.IPNet{targetnode.AddressIPNet6()},
10251100
Allowed: true,
10261101
}
1102+
if len(egressRanges4) > 0 {
1103+
r.Dst = append(r.Dst, egressRanges4...)
1104+
}
1105+
if len(egressRanges6) > 0 {
1106+
r.Dst6 = append(r.Dst6, egressRanges6...)
1107+
}
10271108
// Get peers in the tags and add allowed rules
10281109
if userNode.StaticNode.Address != "" {
10291110
r.IPList = append(r.IPList, userNode.StaticNode.AddressIPNet4())
@@ -1032,14 +1113,26 @@ func GetUserAclRulesForNode(targetnode *models.Node,
10321113
r.IP6List = append(r.IP6List, userNode.StaticNode.AddressIPNet6())
10331114
}
10341115
if aclRule, ok := rules[acl.ID]; ok {
1116+
10351117
aclRule.IPList = append(aclRule.IPList, r.IPList...)
10361118
aclRule.IP6List = append(aclRule.IP6List, r.IP6List...)
1119+
1120+
aclRule.Dst = append(aclRule.Dst, r.Dst...)
1121+
aclRule.Dst6 = append(aclRule.Dst6, r.Dst6...)
1122+
10371123
aclRule.IPList = logic.UniqueIPNetList(aclRule.IPList)
10381124
aclRule.IP6List = logic.UniqueIPNetList(aclRule.IP6List)
1125+
1126+
aclRule.Dst = logic.UniqueIPNetList(aclRule.Dst)
1127+
aclRule.Dst6 = logic.UniqueIPNetList(aclRule.Dst6)
1128+
10391129
rules[acl.ID] = aclRule
10401130
} else {
10411131
r.IPList = logic.UniqueIPNetList(r.IPList)
10421132
r.IP6List = logic.UniqueIPNetList(r.IP6List)
1133+
1134+
r.Dst = logic.UniqueIPNetList(r.Dst)
1135+
r.Dst6 = logic.UniqueIPNetList(r.Dst6)
10431136
rules[acl.ID] = r
10441137
}
10451138
}

0 commit comments

Comments
 (0)