Skip to content

Commit

Permalink
fix: optimized rules allowList count
Browse files Browse the repository at this point in the history
  • Loading branch information
Qu Xuan committed Nov 15, 2019
1 parent 4346cc3 commit e6b64d6
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 1 deletion.
81 changes: 80 additions & 1 deletion util/secrules/secruleset.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ package secrules

import (
"bytes"
"net"
"sort"

"yunion.io/x/pkg/util/netutils"
)

type SecurityRuleSet []SecurityRule
Expand Down Expand Up @@ -55,6 +58,12 @@ func (srs SecurityRuleSet) String() string {
return buf.String()
}

func (srs SecurityRuleSet) Equals(srs1 SecurityRuleSet) bool {
sort.Sort(srs)
sort.Sort(srs1)
return srs.equals(srs1)
}

func (srs SecurityRuleSet) equals(srs1 SecurityRuleSet) bool {
if len(srs) != len(srs1) {
return false
Expand Down Expand Up @@ -191,5 +200,75 @@ func (srs SecurityRuleSet) collapse() SecurityRuleSet {
// save that contains, intersects
}
}
return srs1

//merge cidr
sort.Slice(srs1, func(i, j int) bool {
sr0 := &srs1[i]
sr1 := &srs1[j]
if sr0.Protocol != sr1.Protocol {
return sr0.Protocol < sr1.Protocol
}

if sr0.GetPortsString() != sr1.GetPortsString() {
return sr0.GetPortsString() < sr1.GetPortsString()
}
range0 := netutils.NewIPV4AddrRangeFromIPNet(sr0.IPNet)
range1 := netutils.NewIPV4AddrRangeFromIPNet(sr1.IPNet)
if range0.StartIp() != range1.StartIp() {
return range0.StartIp() < range1.StartIp()
}
if range0.EndIp() != range1.EndIp() {
return range0.EndIp() < range1.EndIp()
}
return sr0.Priority < sr1.Priority
})

// 将端口和协议相同的规则归类
needMerged := []SecurityRuleSet{}
for i, j := 0, 0; i < len(srs1); i++ {
if i == 0 {
needMerged = append(needMerged, SecurityRuleSet{srs1[i]})
continue
}
last := needMerged[j][len(needMerged[j])-1]
if last.Protocol == srs1[i].Protocol && last.GetPortsString() == srs1[i].GetPortsString() {
needMerged[j] = append(needMerged[j], srs1[i])
continue
}
needMerged = append(needMerged, SecurityRuleSet{srs1[i]})
j++
}

result := SecurityRuleSet{}
for _, srs := range needMerged {
result = append(result, srs.mergeNet()...)
}
return result
}

func (srs SecurityRuleSet) mergeNet() SecurityRuleSet {
result := SecurityRuleSet{}
ranges := []netutils.IPV4AddrRange{}
for i := 0; i < len(srs); i++ {
if i == 0 {
ranges = append(ranges, netutils.NewIPV4AddrRangeFromIPNet(srs[i].IPNet))
continue
}
preNet := ranges[len(ranges)-1]
nextNet := netutils.NewIPV4AddrRangeFromIPNet(srs[i].IPNet)
if preNet.IsOverlap(nextNet) || preNet.EndIp()+1 == nextNet.StartIp() {
ranges[len(ranges)-1] = netutils.NewIPV4AddrRange(preNet.StartIp(), nextNet.EndIp())
continue
}
ranges = append(ranges, nextNet)
}
nets := []*net.IPNet{}
for _, addr := range ranges {
nets = append(nets, addr.ToIPNets()...)
}
for _, net := range nets {
srs[0].IPNet = net
result = append(result, srs[0])
}
return result
}
11 changes: 11 additions & 0 deletions util/secrules/secruleset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,24 @@
package secrules

import (
"sort"
"testing"

"yunion.io/x/pkg/util/netutils"
)

func TestSecRuleSet_AllowList(t *testing.T) {
srs0 := SecurityRuleSet{
*MustParseSecurityRule("out:deny 192.168.222.2 tcp 3389"),
*MustParseSecurityRule("out:allow any"),
}
rules := srs0.AllowList()
for _, rule := range rules {
t.Logf("rule: %s", rule.String())
}
dieIf := func(t *testing.T, srs0, srs1 SecurityRuleSet) {
sort.Sort(srs0)
sort.Sort(srs1)
if !srs0.equals(srs1) {
t.Fatalf("not equal:\n%s\n%s", srs0, srs1)
}
Expand Down

0 comments on commit e6b64d6

Please sign in to comment.