Skip to content

[client] Fix rule order for deny rules in peer ACLs #4147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

lixmal
Copy link
Collaborator

@lixmal lixmal commented Jul 14, 2025

Describe your changes

Rule order in peer ACLs was random, this PR makes deny rules always come first, just like with route ACLs

Issue ticket number and link

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)
  • Extended the README / documentation, if necessary

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

@Copilot Copilot AI review requested due to automatic review settings July 14, 2025 09:54
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR ensures that deny (drop) rules in peer ACLs are evaluated before allow rules by introducing a separate deny rules map and adjusting insertion order across components.

  • Added incomingDenyRules alongside incomingRules and updated all filtering, add/delete, and hook logic to use the correct map based on rule action.
  • Changed peerACLsBlock signature and call sites to swap the decoder and packet parameters.
  • Updated tests and native firewall (nftables/iptables) managers to insert drop rules at the beginning and added new tests for deny-rule precedence.

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
client/firewall/uspfilter/filter.go Introduced incomingDenyRules, split add/delete logic by action
client/firewall/uspfilter/tracer.go Updated peerACLsBlock calls to match new signature
client/firewall/uspfilter/filter_test.go Extended tests to verify rules in deny vs allow maps
client/firewall/uspfilter/filter_filter_test.go Added test cases for drop-over-accept precedence and updated general accept rule setup
client/firewall/uspfilter/allow_netbird*.go Reset incomingDenyRules on Close
client/firewall/nftables/manager_linux_test.go Insert DROP rules first in tests; added rule-order test
client/firewall/iptables/manager_linux_test.go Added deny-rule precedence tests in iptables manager
client/firewall/iptables/acl_linux.go Insert DROP rules at position 1; updated ipset naming to include action
Comments suppressed due to low confidence (4)

client/firewall/iptables/acl_linux.go:85

  • [nitpick] The transformIPsetName signature now includes the action parameter but the function lacks an updated doc comment. Adding a comment explaining the new parameter and its effect on the resulting ipset name will aid future maintainers.
) ([]firewall.Rule, error) {

client/firewall/uspfilter/filter.go:1017

  • [nitpick] This return nil, true represents the default "drop all" policy in peerACLsBlock but no comment explains why. Restoring or adding a clarifying comment will make the intended default behavior explicit.
	return nil, true

client/firewall/nftables/manager_linux_test.go:5

  • [nitpick] The import of encoding/binary is interleaved with other standard libraries, which breaks the project's import grouping. Move it into the main standard-library block to match the established style.
	"encoding/binary"

client/firewall/uspfilter/filter_filter_test.go:498

  • [nitpick] Tests use net.ParseIP for rule IPs while production code uses netip.Addr. Consider switching to netip.ParseAddr in tests for consistency and to reflect the actual API surface.
				rules, err := manager.AddPeerFiltering(

Comment on lines +420 to +430
var targetMap map[netip.Addr]RuleSet
if r.drop {
targetMap = m.incomingDenyRules
} else {
targetMap = m.incomingRules
}

if _, ok := targetMap[r.ip]; !ok {
targetMap[r.ip] = make(RuleSet)
}
m.incomingRules[r.ip][r.id] = r
targetMap[r.ip][r.id] = r
Copy link
Preview

Copilot AI Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Using a local targetMap to select between incomingRules and incomingDenyRules can obscure which global map is being mutated. Consider directly manipulating m.incomingRules or m.incomingDenyRules in their respective branches for clearer intent.

Copilot uses AI. Check for mistakes.

Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant