mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-18 08:16:39 +00:00
Extend protocol and firewall manager to handle old management (#915)
* Extend protocol and firewall manager to handle old management * Send correct empty firewall rules list when delete peer * Add extra tests for firewall manager and uspfilter * Work with inconsistent state * Review note * Update comment
This commit is contained in:
committed by
GitHub
parent
45a6263adc
commit
293499c3c0
@@ -22,7 +22,7 @@ type iFaceMapper interface {
|
||||
|
||||
// Manager is a ACL rules manager
|
||||
type Manager interface {
|
||||
ApplyFiltering(rules []*mgmProto.FirewallRule)
|
||||
ApplyFiltering(rules []*mgmProto.FirewallRule, allowByDefault bool)
|
||||
Stop()
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ type DefaultManager struct {
|
||||
}
|
||||
|
||||
// ApplyFiltering firewall rules to the local firewall manager processed by ACL policy.
|
||||
func (d *DefaultManager) ApplyFiltering(rules []*mgmProto.FirewallRule) {
|
||||
//
|
||||
// If allowByDefault is ture it appends allow ALL traffic rules to input and output chains.
|
||||
func (d *DefaultManager) ApplyFiltering(rules []*mgmProto.FirewallRule, allowByDefault bool) {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
@@ -47,6 +49,22 @@ func (d *DefaultManager) ApplyFiltering(rules []*mgmProto.FirewallRule) {
|
||||
applyFailed bool
|
||||
newRulePairs = make(map[string][]firewall.Rule)
|
||||
)
|
||||
if allowByDefault {
|
||||
rules = append(rules,
|
||||
&mgmProto.FirewallRule{
|
||||
PeerIP: "0.0.0.0",
|
||||
Direction: mgmProto.FirewallRule_IN,
|
||||
Action: mgmProto.FirewallRule_ACCEPT,
|
||||
Protocol: mgmProto.FirewallRule_ALL,
|
||||
},
|
||||
&mgmProto.FirewallRule{
|
||||
PeerIP: "0.0.0.0",
|
||||
Direction: mgmProto.FirewallRule_OUT,
|
||||
Action: mgmProto.FirewallRule_ACCEPT,
|
||||
Protocol: mgmProto.FirewallRule_ALL,
|
||||
},
|
||||
)
|
||||
}
|
||||
for _, r := range rules {
|
||||
rules, err := d.protoRuleToFirewallRule(r)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package acl
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
@@ -11,12 +10,6 @@ import (
|
||||
)
|
||||
|
||||
func TestDefaultManager(t *testing.T) {
|
||||
// TODO: enable when other platform will be added
|
||||
if runtime.GOOS != "linux" {
|
||||
t.Skipf("ACL manager not supported in the: %s", runtime.GOOS)
|
||||
return
|
||||
}
|
||||
|
||||
fwRules := []*mgmProto.FirewallRule{
|
||||
{
|
||||
PeerIP: "10.93.0.1",
|
||||
@@ -38,8 +31,9 @@ func TestDefaultManager(t *testing.T) {
|
||||
defer ctrl.Finish()
|
||||
|
||||
iface := mocks.NewMockIFaceMapper(ctrl)
|
||||
iface.EXPECT().IsUserspaceBind().Return(false)
|
||||
iface.EXPECT().Name().Return("lo")
|
||||
iface.EXPECT().IsUserspaceBind().Return(true)
|
||||
// iface.EXPECT().Name().Return("lo")
|
||||
iface.EXPECT().SetFiltering(gomock.Any())
|
||||
|
||||
// we receive one rule from the management so for testing purposes ignore it
|
||||
acl, err := Create(iface)
|
||||
@@ -50,7 +44,7 @@ func TestDefaultManager(t *testing.T) {
|
||||
defer acl.Stop()
|
||||
|
||||
t.Run("apply firewall rules", func(t *testing.T) {
|
||||
acl.ApplyFiltering(fwRules)
|
||||
acl.ApplyFiltering(fwRules, false)
|
||||
|
||||
if len(acl.rulesPairs) != 2 {
|
||||
t.Errorf("firewall rules not applied: %v", acl.rulesPairs)
|
||||
@@ -73,7 +67,7 @@ func TestDefaultManager(t *testing.T) {
|
||||
existedRulesID[id] = struct{}{}
|
||||
}
|
||||
|
||||
acl.ApplyFiltering(fwRules)
|
||||
acl.ApplyFiltering(fwRules, false)
|
||||
|
||||
// we should have one old and one new rule in the existed rules
|
||||
if len(acl.rulesPairs) != 2 {
|
||||
@@ -89,4 +83,18 @@ func TestDefaultManager(t *testing.T) {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("handle default rules", func(t *testing.T) {
|
||||
acl.ApplyFiltering(nil, false)
|
||||
if len(acl.rulesPairs) != 0 {
|
||||
t.Errorf("rules should be empty if default not allowed, got: %v rules", len(acl.rulesPairs))
|
||||
return
|
||||
}
|
||||
|
||||
acl.ApplyFiltering(nil, true)
|
||||
if len(acl.rulesPairs) != 2 {
|
||||
t.Errorf("two default rules should be set if default is allowed, got: %v rules", len(acl.rulesPairs))
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -637,7 +637,13 @@ func (e *Engine) updateNetworkMap(networkMap *mgmProto.NetworkMap) error {
|
||||
}
|
||||
|
||||
if e.acl != nil {
|
||||
e.acl.ApplyFiltering(networkMap.FirewallRules)
|
||||
// if we got empty rules list but management not set networkMap.FirewallRulesIsEmpty flag
|
||||
// we have old version of management without rules handling, we should allow all traffic
|
||||
allowByDefault := len(networkMap.FirewallRules) == 0 && !networkMap.FirewallRulesIsEmpty
|
||||
if allowByDefault {
|
||||
log.Warn("this peer is connected to a NetBird Management service with an older version. Allowing all traffic from connected peers")
|
||||
}
|
||||
e.acl.ApplyFiltering(networkMap.FirewallRules, allowByDefault)
|
||||
}
|
||||
e.networkSerial = serial
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user