mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-30 18:49:08 +02:00
Code cleaning in firewall package
This commit is contained in:
@@ -13,7 +13,8 @@ import (
|
||||
"github.com/google/uuid"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
firewall "github.com/netbirdio/netbird/client/firewall/interface"
|
||||
"github.com/netbirdio/netbird/client/firewall/types"
|
||||
"github.com/netbirdio/netbird/client/firewall/uspfilter/conntrack"
|
||||
"github.com/netbirdio/netbird/client/iface"
|
||||
"github.com/netbirdio/netbird/client/iface/device"
|
||||
@@ -46,7 +47,7 @@ type Manager struct {
|
||||
wgNetwork *net.IPNet
|
||||
decoders sync.Pool
|
||||
wgIface IFaceMapper
|
||||
nativeFirewall firewall.Manager
|
||||
nativeFirewall firewall.Firewall
|
||||
|
||||
mutex sync.RWMutex
|
||||
|
||||
@@ -74,7 +75,7 @@ func Create(iface IFaceMapper) (*Manager, error) {
|
||||
return create(iface)
|
||||
}
|
||||
|
||||
func CreateWithNativeFirewall(iface IFaceMapper, nativeFirewall firewall.Manager) (*Manager, error) {
|
||||
func CreateWithNativeFirewall(iface IFaceMapper, nativeFirewall firewall.Firewall) (*Manager, error) {
|
||||
mgr, err := create(iface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -134,7 +135,7 @@ func (m *Manager) IsServerRouteSupported() bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) AddNatRule(pair firewall.RouterPair) error {
|
||||
func (m *Manager) AddNatRule(pair types.RouterPair) error {
|
||||
if m.nativeFirewall == nil {
|
||||
return errRouteNotSupported
|
||||
}
|
||||
@@ -142,7 +143,7 @@ func (m *Manager) AddNatRule(pair firewall.RouterPair) error {
|
||||
}
|
||||
|
||||
// RemoveNatRule removes a routing firewall rule
|
||||
func (m *Manager) RemoveNatRule(pair firewall.RouterPair) error {
|
||||
func (m *Manager) RemoveNatRule(pair types.RouterPair) error {
|
||||
if m.nativeFirewall == nil {
|
||||
return errRouteNotSupported
|
||||
}
|
||||
@@ -155,19 +156,19 @@ func (m *Manager) RemoveNatRule(pair firewall.RouterPair) error {
|
||||
// rule ID as comment for the rule
|
||||
func (m *Manager) AddPeerFiltering(
|
||||
ip net.IP,
|
||||
proto firewall.Protocol,
|
||||
sPort *firewall.Port,
|
||||
dPort *firewall.Port,
|
||||
action firewall.Action,
|
||||
proto types.Protocol,
|
||||
sPort *types.Port,
|
||||
dPort *types.Port,
|
||||
action types.Action,
|
||||
_ string,
|
||||
comment string,
|
||||
) ([]firewall.Rule, error) {
|
||||
) ([]types.Rule, error) {
|
||||
r := Rule{
|
||||
id: uuid.New().String(),
|
||||
ip: ip,
|
||||
ipLayer: layers.LayerTypeIPv6,
|
||||
matchByIP: true,
|
||||
drop: action == firewall.ActionDrop,
|
||||
drop: action == types.ActionDrop,
|
||||
comment: comment,
|
||||
}
|
||||
if ipNormalized := ip.To4(); ipNormalized != nil {
|
||||
@@ -188,16 +189,16 @@ func (m *Manager) AddPeerFiltering(
|
||||
}
|
||||
|
||||
switch proto {
|
||||
case firewall.ProtocolTCP:
|
||||
case types.ProtocolTCP:
|
||||
r.protoLayer = layers.LayerTypeTCP
|
||||
case firewall.ProtocolUDP:
|
||||
case types.ProtocolUDP:
|
||||
r.protoLayer = layers.LayerTypeUDP
|
||||
case firewall.ProtocolICMP:
|
||||
case types.ProtocolICMP:
|
||||
r.protoLayer = layers.LayerTypeICMPv4
|
||||
if r.ipLayer == layers.LayerTypeIPv6 {
|
||||
r.protoLayer = layers.LayerTypeICMPv6
|
||||
}
|
||||
case firewall.ProtocolALL:
|
||||
case types.ProtocolALL:
|
||||
r.protoLayer = layerTypeAll
|
||||
}
|
||||
|
||||
@@ -207,17 +208,17 @@ func (m *Manager) AddPeerFiltering(
|
||||
}
|
||||
m.incomingRules[r.ip.String()][r.id] = r
|
||||
m.mutex.Unlock()
|
||||
return []firewall.Rule{&r}, nil
|
||||
return []types.Rule{&r}, nil
|
||||
}
|
||||
|
||||
func (m *Manager) AddRouteFiltering(sources []netip.Prefix, destination netip.Prefix, proto firewall.Protocol, sPort *firewall.Port, dPort *firewall.Port, action firewall.Action) (firewall.Rule, error) {
|
||||
func (m *Manager) AddRouteFiltering(sources []netip.Prefix, destination netip.Prefix, proto types.Protocol, sPort *types.Port, dPort *types.Port, action types.Action) (types.Rule, error) {
|
||||
if m.nativeFirewall == nil {
|
||||
return nil, errRouteNotSupported
|
||||
}
|
||||
return m.nativeFirewall.AddRouteFiltering(sources, destination, proto, sPort, dPort, action)
|
||||
}
|
||||
|
||||
func (m *Manager) DeleteRouteRule(rule firewall.Rule) error {
|
||||
func (m *Manager) DeleteRouteRule(rule types.Rule) error {
|
||||
if m.nativeFirewall == nil {
|
||||
return errRouteNotSupported
|
||||
}
|
||||
@@ -225,7 +226,7 @@ func (m *Manager) DeleteRouteRule(rule firewall.Rule) error {
|
||||
}
|
||||
|
||||
// DeletePeerRule from the firewall by rule definition
|
||||
func (m *Manager) DeletePeerRule(rule firewall.Rule) error {
|
||||
func (m *Manager) DeletePeerRule(rule types.Rule) error {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
@@ -254,12 +255,12 @@ func (m *Manager) SetLegacyManagement(isLegacy bool) error {
|
||||
func (m *Manager) Flush() error { return nil }
|
||||
|
||||
// AddDNATRule adds a DNAT rule
|
||||
func (m *Manager) AddDNATRule(rule firewall.ForwardRule) (firewall.Rule, error) {
|
||||
func (m *Manager) AddDNATRule(rule types.ForwardRule) (types.Rule, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// DeleteDNATRule deletes a DNAT rule
|
||||
func (m *Manager) DeleteDNATRule(rule firewall.Rule) error {
|
||||
func (m *Manager) DeleteDNATRule(rule types.Rule) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/google/gopacket/layers"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
fw "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
"github.com/netbirdio/netbird/client/firewall/types"
|
||||
"github.com/netbirdio/netbird/client/firewall/uspfilter/conntrack"
|
||||
"github.com/netbirdio/netbird/client/iface/device"
|
||||
)
|
||||
@@ -90,8 +90,8 @@ func BenchmarkCoreFiltering(b *testing.B) {
|
||||
stateful: false,
|
||||
setupFunc: func(m *Manager) {
|
||||
// Single rule allowing all traffic
|
||||
_, err := m.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolALL, nil, nil,
|
||||
fw.ActionAccept, "", "allow all")
|
||||
_, err := m.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolALL, nil, nil,
|
||||
types.ActionAccept, "", "allow all")
|
||||
require.NoError(b, err)
|
||||
},
|
||||
desc: "Baseline: Single 'allow all' rule without connection tracking",
|
||||
@@ -111,10 +111,10 @@ func BenchmarkCoreFiltering(b *testing.B) {
|
||||
// Add explicit rules matching return traffic pattern
|
||||
for i := 0; i < 1000; i++ { // Simulate realistic ruleset size
|
||||
ip := generateRandomIPs(1)[0]
|
||||
_, err := m.AddPeerFiltering(ip, fw.ProtocolTCP,
|
||||
&fw.Port{Values: []int{1024 + i}},
|
||||
&fw.Port{Values: []int{80}},
|
||||
fw.ActionAccept, "", "explicit return")
|
||||
_, err := m.AddPeerFiltering(ip, types.ProtocolTCP,
|
||||
&types.Port{Values: []int{1024 + i}},
|
||||
&types.Port{Values: []int{80}},
|
||||
types.ActionAccept, "", "explicit return")
|
||||
require.NoError(b, err)
|
||||
}
|
||||
},
|
||||
@@ -125,8 +125,8 @@ func BenchmarkCoreFiltering(b *testing.B) {
|
||||
stateful: true,
|
||||
setupFunc: func(m *Manager) {
|
||||
// Add some basic rules but rely on state for established connections
|
||||
_, err := m.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolTCP, nil, nil,
|
||||
fw.ActionDrop, "", "default drop")
|
||||
_, err := m.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolTCP, nil, nil,
|
||||
types.ActionDrop, "", "default drop")
|
||||
require.NoError(b, err)
|
||||
},
|
||||
desc: "Connection tracking with established connections",
|
||||
@@ -587,10 +587,10 @@ func BenchmarkLongLivedConnections(b *testing.B) {
|
||||
// Setup initial state based on scenario
|
||||
if sc.rules {
|
||||
// Single rule to allow all return traffic from port 80
|
||||
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolTCP,
|
||||
&fw.Port{Values: []int{80}},
|
||||
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolTCP,
|
||||
&types.Port{Values: []int{80}},
|
||||
nil,
|
||||
fw.ActionAccept, "", "return traffic")
|
||||
types.ActionAccept, "", "return traffic")
|
||||
require.NoError(b, err)
|
||||
}
|
||||
|
||||
@@ -678,10 +678,10 @@ func BenchmarkShortLivedConnections(b *testing.B) {
|
||||
// Setup initial state based on scenario
|
||||
if sc.rules {
|
||||
// Single rule to allow all return traffic from port 80
|
||||
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolTCP,
|
||||
&fw.Port{Values: []int{80}},
|
||||
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolTCP,
|
||||
&types.Port{Values: []int{80}},
|
||||
nil,
|
||||
fw.ActionAccept, "", "return traffic")
|
||||
types.ActionAccept, "", "return traffic")
|
||||
require.NoError(b, err)
|
||||
}
|
||||
|
||||
@@ -796,10 +796,10 @@ func BenchmarkParallelLongLivedConnections(b *testing.B) {
|
||||
|
||||
// Setup initial state based on scenario
|
||||
if sc.rules {
|
||||
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolTCP,
|
||||
&fw.Port{Values: []int{80}},
|
||||
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolTCP,
|
||||
&types.Port{Values: []int{80}},
|
||||
nil,
|
||||
fw.ActionAccept, "", "return traffic")
|
||||
types.ActionAccept, "", "return traffic")
|
||||
require.NoError(b, err)
|
||||
}
|
||||
|
||||
@@ -883,10 +883,10 @@ func BenchmarkParallelShortLivedConnections(b *testing.B) {
|
||||
})
|
||||
|
||||
if sc.rules {
|
||||
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), fw.ProtocolTCP,
|
||||
&fw.Port{Values: []int{80}},
|
||||
_, err := manager.AddPeerFiltering(net.ParseIP("0.0.0.0"), types.ProtocolTCP,
|
||||
&types.Port{Values: []int{80}},
|
||||
nil,
|
||||
fw.ActionAccept, "", "return traffic")
|
||||
types.ActionAccept, "", "return traffic")
|
||||
require.NoError(b, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/google/gopacket/layers"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
fw "github.com/netbirdio/netbird/client/firewall/manager"
|
||||
"github.com/netbirdio/netbird/client/firewall/types"
|
||||
"github.com/netbirdio/netbird/client/firewall/uspfilter/conntrack"
|
||||
"github.com/netbirdio/netbird/client/iface"
|
||||
"github.com/netbirdio/netbird/client/iface/device"
|
||||
@@ -43,12 +43,12 @@ func TestManagerCreate(t *testing.T) {
|
||||
|
||||
m, err := Create(ifaceMock)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create Manager: %v", err)
|
||||
t.Errorf("failed to create Firewall: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if m == nil {
|
||||
t.Error("Manager is nil")
|
||||
t.Error("Firewall is nil")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,14 +63,14 @@ func TestManagerAddPeerFiltering(t *testing.T) {
|
||||
|
||||
m, err := Create(ifaceMock)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create Manager: %v", err)
|
||||
t.Errorf("failed to create Firewall: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
ip := net.ParseIP("192.168.1.1")
|
||||
proto := fw.ProtocolTCP
|
||||
port := &fw.Port{Values: []int{80}}
|
||||
action := fw.ActionDrop
|
||||
proto := types.ProtocolTCP
|
||||
port := &types.Port{Values: []int{80}}
|
||||
action := types.ActionDrop
|
||||
comment := "Test rule"
|
||||
|
||||
rule, err := m.AddPeerFiltering(ip, proto, nil, port, action, "", comment)
|
||||
@@ -97,14 +97,14 @@ func TestManagerDeleteRule(t *testing.T) {
|
||||
|
||||
m, err := Create(ifaceMock)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create Manager: %v", err)
|
||||
t.Errorf("failed to create Firewall: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
ip := net.ParseIP("192.168.1.1")
|
||||
proto := fw.ProtocolTCP
|
||||
port := &fw.Port{Values: []int{80}}
|
||||
action := fw.ActionDrop
|
||||
proto := types.ProtocolTCP
|
||||
port := &types.Port{Values: []int{80}}
|
||||
action := types.ActionDrop
|
||||
comment := "Test rule 2"
|
||||
|
||||
rule2, err := m.AddPeerFiltering(ip, proto, nil, port, action, "", comment)
|
||||
@@ -138,7 +138,7 @@ func TestAddUDPPacketHook(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in bool
|
||||
expDir fw.RuleDirection
|
||||
expDir types.RuleDirection
|
||||
ip net.IP
|
||||
dPort uint16
|
||||
hook func([]byte) bool
|
||||
@@ -147,7 +147,7 @@ func TestAddUDPPacketHook(t *testing.T) {
|
||||
{
|
||||
name: "Test Outgoing UDP Packet Hook",
|
||||
in: false,
|
||||
expDir: fw.RuleDirectionOUT,
|
||||
expDir: types.RuleDirectionOUT,
|
||||
ip: net.IPv4(10, 168, 0, 1),
|
||||
dPort: 8000,
|
||||
hook: func([]byte) bool { return true },
|
||||
@@ -155,7 +155,7 @@ func TestAddUDPPacketHook(t *testing.T) {
|
||||
{
|
||||
name: "Test Incoming UDP Packet Hook",
|
||||
in: true,
|
||||
expDir: fw.RuleDirectionIN,
|
||||
expDir: types.RuleDirectionIN,
|
||||
ip: net.IPv6loopback,
|
||||
dPort: 9000,
|
||||
hook: func([]byte) bool { return false },
|
||||
@@ -217,14 +217,14 @@ func TestManagerReset(t *testing.T) {
|
||||
|
||||
m, err := Create(ifaceMock)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create Manager: %v", err)
|
||||
t.Errorf("failed to create Firewall: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
ip := net.ParseIP("192.168.1.1")
|
||||
proto := fw.ProtocolTCP
|
||||
port := &fw.Port{Values: []int{80}}
|
||||
action := fw.ActionDrop
|
||||
proto := types.ProtocolTCP
|
||||
port := &types.Port{Values: []int{80}}
|
||||
action := types.ActionDrop
|
||||
comment := "Test rule"
|
||||
|
||||
_, err = m.AddPeerFiltering(ip, proto, nil, port, action, "", comment)
|
||||
@@ -235,7 +235,7 @@ func TestManagerReset(t *testing.T) {
|
||||
|
||||
err = m.Reset(nil)
|
||||
if err != nil {
|
||||
t.Errorf("failed to reset Manager: %v", err)
|
||||
t.Errorf("failed to reset Firewall: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ func TestNotMatchByIP(t *testing.T) {
|
||||
|
||||
m, err := Create(ifaceMock)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create Manager: %v", err)
|
||||
t.Errorf("failed to create Firewall: %v", err)
|
||||
return
|
||||
}
|
||||
m.wgNetwork = &net.IPNet{
|
||||
@@ -260,8 +260,8 @@ func TestNotMatchByIP(t *testing.T) {
|
||||
}
|
||||
|
||||
ip := net.ParseIP("0.0.0.0")
|
||||
proto := fw.ProtocolUDP
|
||||
action := fw.ActionAccept
|
||||
proto := types.ProtocolUDP
|
||||
action := types.ActionAccept
|
||||
comment := "Test rule"
|
||||
|
||||
_, err = m.AddPeerFiltering(ip, proto, nil, nil, action, "", comment)
|
||||
@@ -304,7 +304,7 @@ func TestNotMatchByIP(t *testing.T) {
|
||||
}
|
||||
|
||||
if err = m.Reset(nil); err != nil {
|
||||
t.Errorf("failed to reset Manager: %v", err)
|
||||
t.Errorf("failed to reset Firewall: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -319,7 +319,7 @@ func TestRemovePacketHook(t *testing.T) {
|
||||
// creating manager instance
|
||||
manager, err := Create(iface)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create Manager: %s", err)
|
||||
t.Fatalf("Failed to create Firewall: %s", err)
|
||||
}
|
||||
defer func() {
|
||||
require.NoError(t, manager.Reset(nil))
|
||||
@@ -463,8 +463,8 @@ func TestUSPFilterCreatePerformance(t *testing.T) {
|
||||
ip := net.ParseIP("10.20.0.100")
|
||||
start := time.Now()
|
||||
for i := 0; i < testMax; i++ {
|
||||
port := &fw.Port{Values: []int{1000 + i}}
|
||||
_, err = manager.AddPeerFiltering(ip, "tcp", nil, port, fw.ActionAccept, "", "accept HTTP traffic")
|
||||
port := &types.Port{Values: []int{1000 + i}}
|
||||
_, err = manager.AddPeerFiltering(ip, "tcp", nil, port, types.ActionAccept, "", "accept HTTP traffic")
|
||||
|
||||
require.NoError(t, err, "failed to add rule")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user