Optimize ACL performance (#994)

* Optimize rules with All groups

* Use IP sets in ACLs (nftables implementation)

* Fix squash rule when we receive optimized rules list from management
This commit is contained in:
Givi Khojanashvili
2023-07-18 13:12:50 +04:00
committed by GitHub
parent 7ebe58f20a
commit e69ec6ab6a
15 changed files with 727 additions and 114 deletions

View File

@@ -2,9 +2,11 @@ package server
import (
_ "embed"
"fmt"
"strconv"
"strings"
log "github.com/sirupsen/logrus"
"github.com/netbirdio/netbird/management/proto"
"github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/status"
@@ -240,7 +242,15 @@ func (a *Account) connResourcesGenerator() (func(*PolicyRule, []*Peer, int), fun
peersExists := make(map[string]struct{})
rules := make([]*FirewallRule, 0)
peers := make([]*Peer, 0)
all, err := a.GetGroupAll()
if err != nil {
log.Errorf("failed to get group all: %v", err)
all = &Group{}
}
return func(rule *PolicyRule, groupPeers []*Peer, direction int) {
isAll := (len(all.Peers) - 1) == len(groupPeers)
for _, peer := range groupPeers {
if peer == nil {
continue
@@ -250,29 +260,33 @@ func (a *Account) connResourcesGenerator() (func(*PolicyRule, []*Peer, int), fun
peersExists[peer.ID] = struct{}{}
}
fwRule := FirewallRule{
fr := FirewallRule{
PeerIP: peer.IP.String(),
Direction: direction,
Action: string(rule.Action),
Protocol: string(rule.Protocol),
}
ruleID := fmt.Sprintf("%s%d", peer.ID+peer.IP.String(), direction)
ruleID += string(rule.Protocol) + string(rule.Action) + strings.Join(rule.Ports, ",")
if isAll {
fr.PeerIP = "0.0.0.0"
}
ruleID := (rule.ID + fr.PeerIP + strconv.Itoa(direction) +
fr.Protocol + fr.Action + strings.Join(rule.Ports, ","))
if _, ok := rulesExists[ruleID]; ok {
continue
}
rulesExists[ruleID] = struct{}{}
if len(rule.Ports) == 0 {
rules = append(rules, &fwRule)
rules = append(rules, &fr)
continue
}
for _, port := range rule.Ports {
addRule := fwRule
addRule.Port = port
rules = append(rules, &addRule)
pr := fr // clone rule and add set new port
pr.Port = port
rules = append(rules, &pr)
}
}
}, func() ([]*Peer, []*FirewallRule) {

View File

@@ -126,6 +126,20 @@ func TestAccount_getPeersByPolicy(t *testing.T) {
assert.Contains(t, peers, account.Peers["peerF"])
epectedFirewallRules := []*FirewallRule{
{
PeerIP: "0.0.0.0",
Direction: firewallRuleDirectionIN,
Action: "accept",
Protocol: "all",
Port: "",
},
{
PeerIP: "0.0.0.0",
Direction: firewallRuleDirectionOUT,
Action: "accept",
Protocol: "all",
Port: "",
},
{
PeerIP: "100.65.14.88",
Direction: firewallRuleDirectionIN,