From d96f882acb2576d329f2eb8a6c7340ccf6c5c701 Mon Sep 17 00:00:00 2001 From: Pascal Fischer Date: Tue, 27 Jun 2023 17:26:15 +0200 Subject: [PATCH 1/7] seems to work but delete fails --- client/firewall/uspfilter/uspfilter.go | 96 +++++++++++++++----------- 1 file changed, 55 insertions(+), 41 deletions(-) diff --git a/client/firewall/uspfilter/uspfilter.go b/client/firewall/uspfilter/uspfilter.go index adc2d552a..e834cf8b6 100644 --- a/client/firewall/uspfilter/uspfilter.go +++ b/client/firewall/uspfilter/uspfilter.go @@ -23,8 +23,8 @@ type IFaceMapper interface { // Manager userspace firewall manager type Manager struct { - outgoingRules []Rule - incomingRules []Rule + outgoingRules map[string][]Rule + incomingRules map[string][]Rule rulesIndex map[string]int wgNetwork *net.IPNet decoders sync.Pool @@ -62,6 +62,8 @@ func Create(iface IFaceMapper) (*Manager, error) { return d }, }, + outgoingRules: make(map[string][]Rule), + incomingRules: make(map[string][]Rule), } if err := iface.SetFilter(m); err != nil { @@ -126,10 +128,10 @@ func (m *Manager) AddFiltering( m.mutex.Lock() var p int if direction == fw.RuleDirectionIN { - m.incomingRules = append(m.incomingRules, r) + m.incomingRules[r.ip.String()] = append(m.incomingRules[r.ip.String()], r) p = len(m.incomingRules) - 1 } else { - m.outgoingRules = append(m.outgoingRules, r) + m.outgoingRules[r.ip.String()] = append(m.outgoingRules[r.ip.String()], r) p = len(m.outgoingRules) - 1 } m.rulesIndex[r.id] = p @@ -156,11 +158,11 @@ func (m *Manager) DeleteRule(rule fw.Rule) error { var toUpdate []Rule if r.direction == fw.RuleDirectionIN { - m.incomingRules = append(m.incomingRules[:p], m.incomingRules[p+1:]...) - toUpdate = m.incomingRules + m.incomingRules[r.ip.String()] = append(m.incomingRules[r.ip.String()][:p], m.incomingRules[r.ip.String()][p+1:]...) + toUpdate = m.incomingRules[r.ip.String()] } else { - m.outgoingRules = append(m.outgoingRules[:p], m.outgoingRules[p+1:]...) - toUpdate = m.outgoingRules + m.outgoingRules[r.ip.String()] = append(m.outgoingRules[r.ip.String()][:p], m.outgoingRules[r.ip.String()][p+1:]...) + toUpdate = m.outgoingRules[r.ip.String()] } for i := 0; i < len(toUpdate); i++ { @@ -174,8 +176,8 @@ func (m *Manager) Reset() error { m.mutex.Lock() defer m.mutex.Unlock() - m.outgoingRules = m.outgoingRules[:0] - m.incomingRules = m.incomingRules[:0] + m.outgoingRules = make(map[string][]Rule) + m.incomingRules = make(map[string][]Rule) m.rulesIndex = make(map[string]int) return nil @@ -192,7 +194,7 @@ func (m *Manager) DropIncoming(packetData []byte) bool { } // dropFilter imlements same logic for booth direction of the traffic -func (m *Manager) dropFilter(packetData []byte, rules []Rule, isIncomingPacket bool) bool { +func (m *Manager) dropFilter(packetData []byte, rules map[string][]Rule, isIncomingPacket bool) bool { m.mutex.RLock() defer m.mutex.RUnlock() @@ -226,29 +228,37 @@ func (m *Manager) dropFilter(packetData []byte, rules []Rule, isIncomingPacket b } payloadLayer := d.decoded[1] + var srcIP, dstIP net.IP + var ipRules []Rule + switch ipLayer { + case layers.LayerTypeIPv4: + if isIncomingPacket { + srcIP = d.ip4.SrcIP + ipRules = rules[srcIP.String()] + } else { + dstIP = d.ip4.DstIP + ipRules = rules[dstIP.String()] + } + case layers.LayerTypeIPv6: + if isIncomingPacket { + srcIP = d.ip6.SrcIP + ipRules = rules[srcIP.String()] + } else { + dstIP = d.ip6.DstIP + ipRules = rules[dstIP.String()] + } + } + // check if IP address match by IP - for _, rule := range rules { + for _, rule := range ipRules { if rule.matchByIP { - switch ipLayer { - case layers.LayerTypeIPv4: - if isIncomingPacket { - if !d.ip4.SrcIP.Equal(rule.ip) { - continue - } - } else { - if !d.ip4.DstIP.Equal(rule.ip) { - continue - } + if isIncomingPacket { + if !srcIP.Equal(rule.ip) { + continue } - case layers.LayerTypeIPv6: - if isIncomingPacket { - if !d.ip6.SrcIP.Equal(rule.ip) { - continue - } - } else { - if !d.ip6.DstIP.Equal(rule.ip) { - continue - } + } else { + if !dstIP.Equal(rule.ip) { + continue } } } @@ -328,11 +338,11 @@ func (m *Manager) AddUDPPacketHook( var toUpdate []Rule if in { r.direction = fw.RuleDirectionIN - m.incomingRules = append([]Rule{r}, m.incomingRules...) - toUpdate = m.incomingRules + m.incomingRules[r.ip.String()] = append([]Rule{r}, m.incomingRules[r.ip.String()]...) + toUpdate = m.incomingRules[r.ip.String()] } else { - m.outgoingRules = append([]Rule{r}, m.outgoingRules...) - toUpdate = m.outgoingRules + m.outgoingRules[r.ip.String()] = append([]Rule{r}, m.outgoingRules[r.ip.String()]...) + toUpdate = m.outgoingRules[r.ip.String()] } for i := range toUpdate { @@ -345,14 +355,18 @@ func (m *Manager) AddUDPPacketHook( // RemovePacketHook removes packet hook by given ID func (m *Manager) RemovePacketHook(hookID string) error { - for _, r := range m.incomingRules { - if r.id == hookID { - return m.DeleteRule(&r) + for _, arr := range m.incomingRules { + for _, r := range arr { + if r.id == hookID { + return m.DeleteRule(&r) + } } } - for _, r := range m.outgoingRules { - if r.id == hookID { - return m.DeleteRule(&r) + for _, arr := range m.outgoingRules { + for _, r := range arr { + if r.id == hookID { + return m.DeleteRule(&r) + } } } return fmt.Errorf("hook with given id not found") From b39ffef22c8855c08fd35029aaedd91d9f50d642 Mon Sep 17 00:00:00 2001 From: Pascal Fischer Date: Tue, 27 Jun 2023 17:44:05 +0200 Subject: [PATCH 2/7] add missing all rule --- client/firewall/uspfilter/uspfilter.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/firewall/uspfilter/uspfilter.go b/client/firewall/uspfilter/uspfilter.go index e834cf8b6..9d16925cf 100644 --- a/client/firewall/uspfilter/uspfilter.go +++ b/client/firewall/uspfilter/uspfilter.go @@ -129,10 +129,10 @@ func (m *Manager) AddFiltering( var p int if direction == fw.RuleDirectionIN { m.incomingRules[r.ip.String()] = append(m.incomingRules[r.ip.String()], r) - p = len(m.incomingRules) - 1 + p = len(m.incomingRules[r.ip.String()]) - 1 } else { m.outgoingRules[r.ip.String()] = append(m.outgoingRules[r.ip.String()], r) - p = len(m.outgoingRules) - 1 + p = len(m.outgoingRules[r.ip.String()]) - 1 } m.rulesIndex[r.id] = p m.mutex.Unlock() @@ -234,18 +234,18 @@ func (m *Manager) dropFilter(packetData []byte, rules map[string][]Rule, isIncom case layers.LayerTypeIPv4: if isIncomingPacket { srcIP = d.ip4.SrcIP - ipRules = rules[srcIP.String()] + ipRules = append(rules[srcIP.String()], rules["0.0.0.0"]...) } else { dstIP = d.ip4.DstIP - ipRules = rules[dstIP.String()] + ipRules = append(rules[dstIP.String()], rules["0.0.0.0"]...) } case layers.LayerTypeIPv6: if isIncomingPacket { srcIP = d.ip6.SrcIP - ipRules = rules[srcIP.String()] + ipRules = append(rules[srcIP.String()], rules["::"]...) } else { dstIP = d.ip6.DstIP - ipRules = rules[dstIP.String()] + ipRules = append(rules[dstIP.String()], rules["::"]...) } } From 51878659f8382794a01ecb7cfc0517e7db55bc5b Mon Sep 17 00:00:00 2001 From: Pascal Fischer Date: Wed, 28 Jun 2023 02:50:12 +0200 Subject: [PATCH 3/7] remove Rule index map --- client/firewall/uspfilter/uspfilter.go | 113 ++++++++++++------------- 1 file changed, 53 insertions(+), 60 deletions(-) diff --git a/client/firewall/uspfilter/uspfilter.go b/client/firewall/uspfilter/uspfilter.go index 9d16925cf..3cbd3e6af 100644 --- a/client/firewall/uspfilter/uspfilter.go +++ b/client/firewall/uspfilter/uspfilter.go @@ -23,9 +23,8 @@ type IFaceMapper interface { // Manager userspace firewall manager type Manager struct { - outgoingRules map[string][]Rule - incomingRules map[string][]Rule - rulesIndex map[string]int + outgoingRules map[string]map[string]Rule + incomingRules map[string]map[string]Rule wgNetwork *net.IPNet decoders sync.Pool @@ -48,7 +47,6 @@ type decoder struct { // Create userspace firewall manager constructor func Create(iface IFaceMapper) (*Manager, error) { m := &Manager{ - rulesIndex: make(map[string]int), decoders: sync.Pool{ New: func() any { d := &decoder{ @@ -62,8 +60,8 @@ func Create(iface IFaceMapper) (*Manager, error) { return d }, }, - outgoingRules: make(map[string][]Rule), - incomingRules: make(map[string][]Rule), + outgoingRules: make(map[string]map[string]Rule), + incomingRules: make(map[string]map[string]Rule), } if err := iface.SetFilter(m); err != nil { @@ -126,15 +124,17 @@ func (m *Manager) AddFiltering( } m.mutex.Lock() - var p int if direction == fw.RuleDirectionIN { - m.incomingRules[r.ip.String()] = append(m.incomingRules[r.ip.String()], r) - p = len(m.incomingRules[r.ip.String()]) - 1 + if _, ok := m.incomingRules[r.ip.String()]; !ok { + m.incomingRules[r.ip.String()] = make(map[string]Rule) + } + m.incomingRules[r.ip.String()][r.id] = r } else { - m.outgoingRules[r.ip.String()] = append(m.outgoingRules[r.ip.String()], r) - p = len(m.outgoingRules[r.ip.String()]) - 1 + if _, ok := m.outgoingRules[r.ip.String()]; !ok { + m.outgoingRules[r.ip.String()] = make(map[string]Rule) + } + m.outgoingRules[r.ip.String()][r.id] = r } - m.rulesIndex[r.id] = p m.mutex.Unlock() return &r, nil @@ -150,24 +150,20 @@ func (m *Manager) DeleteRule(rule fw.Rule) error { return fmt.Errorf("delete rule: invalid rule type: %T", rule) } - p, ok := m.rulesIndex[r.id] - if !ok { - return fmt.Errorf("delete rule: no rule with such id: %v", r.id) - } - delete(m.rulesIndex, r.id) - - var toUpdate []Rule if r.direction == fw.RuleDirectionIN { - m.incomingRules[r.ip.String()] = append(m.incomingRules[r.ip.String()][:p], m.incomingRules[r.ip.String()][p+1:]...) - toUpdate = m.incomingRules[r.ip.String()] + _, ok := m.incomingRules[r.ip.String()][r.id] + if !ok { + return fmt.Errorf("delete rule: no rule with such id: %v", r.id) + } + delete(m.incomingRules[r.ip.String()], r.id) } else { - m.outgoingRules[r.ip.String()] = append(m.outgoingRules[r.ip.String()][:p], m.outgoingRules[r.ip.String()][p+1:]...) - toUpdate = m.outgoingRules[r.ip.String()] + _, ok := m.outgoingRules[r.ip.String()][r.id] + if !ok { + return fmt.Errorf("delete rule: no rule with such id: %v", r.id) + } + delete(m.outgoingRules[r.ip.String()], r.id) } - for i := 0; i < len(toUpdate); i++ { - m.rulesIndex[toUpdate[i].id] = i - } return nil } @@ -176,9 +172,8 @@ func (m *Manager) Reset() error { m.mutex.Lock() defer m.mutex.Unlock() - m.outgoingRules = make(map[string][]Rule) - m.incomingRules = make(map[string][]Rule) - m.rulesIndex = make(map[string]int) + m.outgoingRules = make(map[string]map[string]Rule) + m.incomingRules = make(map[string]map[string]Rule) return nil } @@ -194,7 +189,7 @@ func (m *Manager) DropIncoming(packetData []byte) bool { } // dropFilter imlements same logic for booth direction of the traffic -func (m *Manager) dropFilter(packetData []byte, rules map[string][]Rule, isIncomingPacket bool) bool { +func (m *Manager) dropFilter(packetData []byte, rules map[string]map[string]Rule, isIncomingPacket bool) bool { m.mutex.RLock() defer m.mutex.RUnlock() @@ -226,41 +221,39 @@ func (m *Manager) dropFilter(packetData []byte, rules map[string][]Rule, isIncom log.Errorf("unknown layer: %v", d.decoded[0]) return true } - payloadLayer := d.decoded[1] - var srcIP, dstIP net.IP - var ipRules []Rule + var ip net.IP switch ipLayer { case layers.LayerTypeIPv4: if isIncomingPacket { - srcIP = d.ip4.SrcIP - ipRules = append(rules[srcIP.String()], rules["0.0.0.0"]...) + ip = d.ip4.SrcIP } else { - dstIP = d.ip4.DstIP - ipRules = append(rules[dstIP.String()], rules["0.0.0.0"]...) + ip = d.ip4.DstIP } case layers.LayerTypeIPv6: if isIncomingPacket { - srcIP = d.ip6.SrcIP - ipRules = append(rules[srcIP.String()], rules["::"]...) + ip = d.ip6.SrcIP } else { - dstIP = d.ip6.DstIP - ipRules = append(rules[dstIP.String()], rules["::"]...) + ip = d.ip6.DstIP } } + _, ok := rules["0.0.0.0"] + if ok { + return false + } + + _, ok = rules["::"] + if ok { + return false + } + + payloadLayer := d.decoded[1] + // check if IP address match by IP - for _, rule := range ipRules { - if rule.matchByIP { - if isIncomingPacket { - if !srcIP.Equal(rule.ip) { - continue - } - } else { - if !dstIP.Equal(rule.ip) { - continue - } - } + for _, rule := range rules[ip.String()] { + if rule.matchByIP && !ip.Equal(rule.ip) { + continue } if rule.protoLayer == layerTypeAll { @@ -335,19 +328,19 @@ func (m *Manager) AddUDPPacketHook( } m.mutex.Lock() - var toUpdate []Rule if in { r.direction = fw.RuleDirectionIN - m.incomingRules[r.ip.String()] = append([]Rule{r}, m.incomingRules[r.ip.String()]...) - toUpdate = m.incomingRules[r.ip.String()] + if _, ok := m.incomingRules[r.ip.String()]; !ok { + m.incomingRules[r.ip.String()] = make(map[string]Rule) + } + m.incomingRules[r.ip.String()][r.id] = r } else { - m.outgoingRules[r.ip.String()] = append([]Rule{r}, m.outgoingRules[r.ip.String()]...) - toUpdate = m.outgoingRules[r.ip.String()] + if _, ok := m.outgoingRules[r.ip.String()]; !ok { + m.outgoingRules[r.ip.String()] = make(map[string]Rule) + } + m.outgoingRules[r.ip.String()][r.id] = r } - for i := range toUpdate { - m.rulesIndex[toUpdate[i].id] = i - } m.mutex.Unlock() return r.id From 33a155d9aa94024c6e760203c272ab45286f66d6 Mon Sep 17 00:00:00 2001 From: Pascal Fischer Date: Wed, 28 Jun 2023 03:03:01 +0200 Subject: [PATCH 4/7] fix all rules check --- client/firewall/uspfilter/uspfilter.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/client/firewall/uspfilter/uspfilter.go b/client/firewall/uspfilter/uspfilter.go index 3cbd3e6af..94725658a 100644 --- a/client/firewall/uspfilter/uspfilter.go +++ b/client/firewall/uspfilter/uspfilter.go @@ -238,13 +238,7 @@ func (m *Manager) dropFilter(packetData []byte, rules map[string]map[string]Rule } } - _, ok := rules["0.0.0.0"] - if ok { - return false - } - - _, ok = rules["::"] - if ok { + if len(rules["0.0.0.0"]) > 0 || len(rules["::"]) > 0 { return false } From 54fe05f6d86180500a2efe9cb08ed81ae6377ebb Mon Sep 17 00:00:00 2001 From: Pascal Fischer Date: Wed, 28 Jun 2023 10:35:29 +0200 Subject: [PATCH 5/7] fix test --- client/firewall/uspfilter/uspfilter_test.go | 54 ++++++++++----------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/client/firewall/uspfilter/uspfilter_test.go b/client/firewall/uspfilter/uspfilter_test.go index eed31c627..ab921b1eb 100644 --- a/client/firewall/uspfilter/uspfilter_test.go +++ b/client/firewall/uspfilter/uspfilter_test.go @@ -123,8 +123,8 @@ func TestManagerDeleteRule(t *testing.T) { return } - if idx, ok := m.rulesIndex[rule2.GetRuleID()]; !ok || len(m.incomingRules) != 1 || idx != 0 { - t.Errorf("rule2 is not in the rulesIndex") + if _, ok := m.incomingRules[ip.String()][rule2.GetRuleID()]; !ok { + t.Errorf("rule2 is not in the incomingRules") } err = m.DeleteRule(rule2) @@ -133,8 +133,8 @@ func TestManagerDeleteRule(t *testing.T) { return } - if len(m.rulesIndex) != 0 || len(m.incomingRules) != 0 { - t.Errorf("rule1 still in the rulesIndex") + if _, ok := m.incomingRules[ip.String()][rule2.GetRuleID()]; ok { + t.Errorf("rule2 is not in the incomingRules") } } @@ -169,26 +169,29 @@ func TestAddUDPPacketHook(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { manager := &Manager{ - incomingRules: []Rule{}, - outgoingRules: []Rule{}, - rulesIndex: make(map[string]int), + incomingRules: map[string]map[string]Rule{}, + outgoingRules: map[string]map[string]Rule{}, } manager.AddUDPPacketHook(tt.in, tt.ip, tt.dPort, tt.hook) var addedRule Rule if tt.in { - if len(manager.incomingRules) != 1 { + if len(manager.incomingRules[tt.ip.String()]) != 1 { t.Errorf("expected 1 incoming rule, got %d", len(manager.incomingRules)) return } - addedRule = manager.incomingRules[0] + for _, rule := range manager.incomingRules[tt.ip.String()] { + addedRule = rule + } } else { if len(manager.outgoingRules) != 1 { t.Errorf("expected 1 outgoing rule, got %d", len(manager.outgoingRules)) return } - addedRule = manager.outgoingRules[0] + for _, rule := range manager.outgoingRules[tt.ip.String()] { + addedRule = rule + } } if !tt.ip.Equal(addedRule.ip) { @@ -211,17 +214,6 @@ func TestAddUDPPacketHook(t *testing.T) { t.Errorf("expected udpHook to be set") return } - - // Ensure rulesIndex is correctly updated - index, ok := manager.rulesIndex[addedRule.id] - if !ok { - t.Errorf("expected rule to be in rulesIndex") - return - } - if index != 0 { - t.Errorf("expected rule index to be 0, got %d", index) - return - } }) } } @@ -256,7 +248,7 @@ func TestManagerReset(t *testing.T) { return } - if len(m.rulesIndex) != 0 || len(m.outgoingRules) != 0 || len(m.incomingRules) != 0 { + if len(m.outgoingRules) != 0 || len(m.incomingRules) != 0 { t.Errorf("rules is not empty") } } @@ -346,10 +338,12 @@ func TestRemovePacketHook(t *testing.T) { // Assert the hook is added by finding it in the manager's outgoing rules found := false - for _, rule := range manager.outgoingRules { - if rule.id == hookID { - found = true - break + for _, arr := range manager.outgoingRules { + for _, rule := range arr { + if rule.id == hookID { + found = true + break + } } } @@ -364,9 +358,11 @@ func TestRemovePacketHook(t *testing.T) { } // Assert the hook is removed by checking it in the manager's outgoing rules - for _, rule := range manager.outgoingRules { - if rule.id == hookID { - t.Fatalf("The hook was not removed properly.") + for _, arr := range manager.outgoingRules { + for _, rule := range arr { + if rule.id == hookID { + t.Fatalf("The hook was not removed properly.") + } } } } From e074c244878ec04d5cbf20bf76d5b885745c829b Mon Sep 17 00:00:00 2001 From: Pascal Fischer Date: Wed, 28 Jun 2023 14:09:23 +0200 Subject: [PATCH 6/7] add type for RuleSet --- client/firewall/uspfilter/uspfilter.go | 21 ++++++++++++--------- client/firewall/uspfilter/uspfilter_test.go | 4 ++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/client/firewall/uspfilter/uspfilter.go b/client/firewall/uspfilter/uspfilter.go index 94725658a..ab27f631f 100644 --- a/client/firewall/uspfilter/uspfilter.go +++ b/client/firewall/uspfilter/uspfilter.go @@ -21,10 +21,13 @@ type IFaceMapper interface { SetFilter(iface.PacketFilter) error } +// RuleSet is a set of rules grouped by a string key +type RuleSet map[string]Rule + // Manager userspace firewall manager type Manager struct { - outgoingRules map[string]map[string]Rule - incomingRules map[string]map[string]Rule + outgoingRules map[string]RuleSet + incomingRules map[string]RuleSet wgNetwork *net.IPNet decoders sync.Pool @@ -60,8 +63,8 @@ func Create(iface IFaceMapper) (*Manager, error) { return d }, }, - outgoingRules: make(map[string]map[string]Rule), - incomingRules: make(map[string]map[string]Rule), + outgoingRules: make(map[string]RuleSet), + incomingRules: make(map[string]RuleSet), } if err := iface.SetFilter(m); err != nil { @@ -126,12 +129,12 @@ func (m *Manager) AddFiltering( m.mutex.Lock() if direction == fw.RuleDirectionIN { if _, ok := m.incomingRules[r.ip.String()]; !ok { - m.incomingRules[r.ip.String()] = make(map[string]Rule) + m.incomingRules[r.ip.String()] = make(RuleSet) } m.incomingRules[r.ip.String()][r.id] = r } else { if _, ok := m.outgoingRules[r.ip.String()]; !ok { - m.outgoingRules[r.ip.String()] = make(map[string]Rule) + m.outgoingRules[r.ip.String()] = make(RuleSet) } m.outgoingRules[r.ip.String()][r.id] = r } @@ -172,8 +175,8 @@ func (m *Manager) Reset() error { m.mutex.Lock() defer m.mutex.Unlock() - m.outgoingRules = make(map[string]map[string]Rule) - m.incomingRules = make(map[string]map[string]Rule) + m.outgoingRules = make(map[string]RuleSet) + m.incomingRules = make(map[string]RuleSet) return nil } @@ -189,7 +192,7 @@ func (m *Manager) DropIncoming(packetData []byte) bool { } // dropFilter imlements same logic for booth direction of the traffic -func (m *Manager) dropFilter(packetData []byte, rules map[string]map[string]Rule, isIncomingPacket bool) bool { +func (m *Manager) dropFilter(packetData []byte, rules map[string]RuleSet, isIncomingPacket bool) bool { m.mutex.RLock() defer m.mutex.RUnlock() diff --git a/client/firewall/uspfilter/uspfilter_test.go b/client/firewall/uspfilter/uspfilter_test.go index ab921b1eb..c7f38a44f 100644 --- a/client/firewall/uspfilter/uspfilter_test.go +++ b/client/firewall/uspfilter/uspfilter_test.go @@ -169,8 +169,8 @@ func TestAddUDPPacketHook(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { manager := &Manager{ - incomingRules: map[string]map[string]Rule{}, - outgoingRules: map[string]map[string]Rule{}, + incomingRules: map[string]RuleSet{}, + outgoingRules: map[string]RuleSet{}, } manager.AddUDPPacketHook(tt.in, tt.ip, tt.dPort, tt.hook) From 6e264d9de704b4ae50ef462e3d8e32ea2a575fa2 Mon Sep 17 00:00:00 2001 From: Pascal Fischer Date: Tue, 11 Jul 2023 19:58:21 +0200 Subject: [PATCH 7/7] fix rule order to solve DNS resolver issue --- client/firewall/uspfilter/uspfilter.go | 46 ++++++++++++++++---------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/client/firewall/uspfilter/uspfilter.go b/client/firewall/uspfilter/uspfilter.go index ab27f631f..5cc215256 100644 --- a/client/firewall/uspfilter/uspfilter.go +++ b/client/firewall/uspfilter/uspfilter.go @@ -241,20 +241,32 @@ func (m *Manager) dropFilter(packetData []byte, rules map[string]RuleSet, isInco } } - if len(rules["0.0.0.0"]) > 0 || len(rules["::"]) > 0 { - return false + filter, ok := validateRule(ip, packetData, rules[ip.String()], d) + if ok { + return filter + } + filter, ok = validateRule(ip, packetData, rules["0.0.0.0"], d) + if ok { + return filter + } + filter, ok = validateRule(ip, packetData, rules["::"], d) + if ok { + return filter } - payloadLayer := d.decoded[1] + // default policy is DROP ALL + return true +} - // check if IP address match by IP - for _, rule := range rules[ip.String()] { +func validateRule(ip net.IP, packetData []byte, rules map[string]Rule, d *decoder) (bool, bool) { + payloadLayer := d.decoded[1] + for _, rule := range rules { if rule.matchByIP && !ip.Equal(rule.ip) { continue } if rule.protoLayer == layerTypeAll { - return rule.drop + return rule.drop, true } if payloadLayer != rule.protoLayer { @@ -264,38 +276,36 @@ func (m *Manager) dropFilter(packetData []byte, rules map[string]RuleSet, isInco switch payloadLayer { case layers.LayerTypeTCP: if rule.sPort == 0 && rule.dPort == 0 { - return rule.drop + return rule.drop, true } if rule.sPort != 0 && rule.sPort == uint16(d.tcp.SrcPort) { - return rule.drop + return rule.drop, true } if rule.dPort != 0 && rule.dPort == uint16(d.tcp.DstPort) { - return rule.drop + return rule.drop, true } case layers.LayerTypeUDP: // if rule has UDP hook (and if we are here we match this rule) // we ignore rule.drop and call this hook if rule.udpHook != nil { - return rule.udpHook(packetData) + return rule.udpHook(packetData), true } if rule.sPort == 0 && rule.dPort == 0 { - return rule.drop + return rule.drop, true } if rule.sPort != 0 && rule.sPort == uint16(d.udp.SrcPort) { - return rule.drop + return rule.drop, true } if rule.dPort != 0 && rule.dPort == uint16(d.udp.DstPort) { - return rule.drop + return rule.drop, true } - return rule.drop + return rule.drop, true case layers.LayerTypeICMPv4, layers.LayerTypeICMPv6: - return rule.drop + return rule.drop, true } } - - // default policy is DROP ALL - return true + return false, false } // SetNetwork of the wireguard interface to which filtering applied