[PR #6322] [client] Unify peer and route ACL filtering with multi-source rules #28025

Open
opened 2026-08-05 07:09:33 -04:00 by saavagebueno · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/netbirdio/netbird/pull/6322
Author: @lixmal
Created: 6/1/2026
Status: 🔄 Open

Base: mainHead: peer-acl-multi-source


📝 Commits (10+)

  • 38603c7 Unify peer and route ACL filtering with multi-source peer rules
  • f7e9df6 Remove partial userspace firewall mode and open foreign chains via a table-less allower
  • 1ed2067 Merge remote-tracking branch 'origin/main' into peer-acl-multi-source
  • 1c5b84b Snapshot iptables rule maps before persisting state
  • 09c0063 Merge branch 'main' into peer-acl-multi-source
  • a14586b Scope userspace firewall wildcard source rules per address family
  • 1b6294f Install nftables peer filter and mangle rules in a single transaction
  • a5d4373 Share the iptables jump rule spec between install and cleanup
  • ab7639d Fix legacy ACL source wildcard and keep rollback tracking on delete failure
  • 97d9559 Fix CI: recognize multi-value port set lookups in tests and correct PeerIP lint suppression

📊 Changes

77 files changed (+8335 additions, -6502 deletions)

View changed files

client/firewall/allower_other.go (+11 -0)
client/firewall/allower_windows.go (+10 -0)
📝 client/firewall/create.go (+7 -11)
📝 client/firewall/create_linux.go (+122 -71)
client/firewall/iptables/acl_linux.go (+0 -560)
client/firewall/iptables/chains_linux.go (+346 -0)
client/firewall/iptables/dnat_linux.go (+285 -0)
client/firewall/iptables/family_linux.go (+252 -0)
client/firewall/iptables/filter_linux.go (+346 -0)
client/firewall/iptables/interface_allower_linux.go (+93 -0)
client/firewall/iptables/ipset_linux.go (+104 -0)
📝 client/firewall/iptables/manager_linux.go (+93 -161)
📝 client/firewall/iptables/manager_linux_test.go (+54 -48)
client/firewall/iptables/router_linux.go (+0 -1154)
📝 client/firewall/iptables/router_linux_test.go (+31 -63)
client/firewall/iptables/routing_linux.go (+263 -0)
📝 client/firewall/iptables/rule.go (+10 -8)
client/firewall/iptables/rulestore_linux.go (+0 -127)
📝 client/firewall/iptables/state_linux.go (+11 -21)
client/firewall/iptables/testhelpers_linux_test.go (+27 -0)

...and 57 more files

📄 Description

Describe your changes

Unifies the peer ACL and route ACL paths in the firewall backends into a single filtering API, lets a peer rule carry multiple sources per address family instead of one rule per source, and removes the partial userspace firewall mode.

  • Replace the separate peer/route filtering calls with one AddFilterRule that takes a source list and a destination, dispatched to the correct address family (input chain for peer rules, forward chain for route rules)
  • Group incoming management rules that share a selector and install a single multi-source rule per family, deduplicating identical flows
  • Add a dual-stack address-family abstraction so v4 and v6 rules are built and stored side by side, skipping the v6 path when the interface has no IPv6
  • Split the nftables backend into focused files (chains, filtering, routing, DNAT, ipsets) around that abstraction
  • Delete filter rules by the rule the backend returns rather than by a bare id, so the id type is no longer overloaded as a rule handle
  • Remove the partial userspace firewall mode (userspace filter wrapping a native firewall); when the userspace firewall is forced, routing is always handled in userspace
  • Open the interface in foreign kernel filter chains through a single interface-allower abstraction (nftables, iptables-legacy fallback, firewalld trust, Windows netsh rule) instead of per-backend AllowNetbird methods
  • NB_FORCE_USERSPACE_ROUTER is now an alias for NB_FORCE_USERSPACE_FIREWALL: forcing userspace routing forces the userspace firewall, since the two are no longer separable

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)
  • This change does not modify the public API, gRPC protocols, functionality behavior, CLI / service flags, or introduce a new feature — OR I have discussed it with the NetBird team beforehand (link the issue / Slack thread in the description). See CONTRIBUTING.md.

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

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

Firewall refactor. The only user-visible change is that NB_FORCE_USERSPACE_ROUTER now also forces the userspace firewall; the partial userspace mode it used to apply to no longer exists.

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

https://github.com/netbirdio/docs/pull/__

Summary by CodeRabbit

  • New Features

    • Unified filter add/delete API, per-address-family firewall backends, deterministic DNAT/inbound/output support, and cross-platform interface allower implementations (Linux/Windows/others).
  • Bug Fixes

    • More robust startup/teardown, improved rollback and aggregated error reporting, safer rule install/remove, and clearer IPv6 handling and fallback logging.
  • Refactor

    • Consolidated peer/route flows into rule-centric APIs, canonical rule ID type, and a userspace firewall Config-driven constructor.
  • Tests

    • Expanded unit, integration, and benchmark coverage (firewall, ACLs, NAT/DNAT, IPv6).

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/netbirdio/netbird/pull/6322 **Author:** [@lixmal](https://github.com/lixmal) **Created:** 6/1/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `peer-acl-multi-source` --- ### 📝 Commits (10+) - [`38603c7`](https://github.com/netbirdio/netbird/commit/38603c75527632b9e6e3febd027c7225e465ca47) Unify peer and route ACL filtering with multi-source peer rules - [`f7e9df6`](https://github.com/netbirdio/netbird/commit/f7e9df6ffa84f7472b5dbb6228502d98b4c299a2) Remove partial userspace firewall mode and open foreign chains via a table-less allower - [`1ed2067`](https://github.com/netbirdio/netbird/commit/1ed2067b8b6c348cfb2ca9eaa0ecffd61b019e3b) Merge remote-tracking branch 'origin/main' into peer-acl-multi-source - [`1c5b84b`](https://github.com/netbirdio/netbird/commit/1c5b84b1a1665766a4d5c2b364bf4ef3b65f2d9e) Snapshot iptables rule maps before persisting state - [`09c0063`](https://github.com/netbirdio/netbird/commit/09c0063d71880a040ea32f276ef17e1c5a5756bc) Merge branch 'main' into peer-acl-multi-source - [`a14586b`](https://github.com/netbirdio/netbird/commit/a14586b1423a933b28657867845e9398ff78c8c9) Scope userspace firewall wildcard source rules per address family - [`1b6294f`](https://github.com/netbirdio/netbird/commit/1b6294f2ff6485d246c53dec5f1fd4b66c1facda) Install nftables peer filter and mangle rules in a single transaction - [`a5d4373`](https://github.com/netbirdio/netbird/commit/a5d4373ddcc4f1934be5f2e756e228762a864272) Share the iptables jump rule spec between install and cleanup - [`ab7639d`](https://github.com/netbirdio/netbird/commit/ab7639d1013828554185e28948620d31bdcff489) Fix legacy ACL source wildcard and keep rollback tracking on delete failure - [`97d9559`](https://github.com/netbirdio/netbird/commit/97d9559e6d28e18ba4d48e64e644501168b01255) Fix CI: recognize multi-value port set lookups in tests and correct PeerIP lint suppression ### 📊 Changes **77 files changed** (+8335 additions, -6502 deletions) <details> <summary>View changed files</summary> ➕ `client/firewall/allower_other.go` (+11 -0) ➕ `client/firewall/allower_windows.go` (+10 -0) 📝 `client/firewall/create.go` (+7 -11) 📝 `client/firewall/create_linux.go` (+122 -71) ➖ `client/firewall/iptables/acl_linux.go` (+0 -560) ➕ `client/firewall/iptables/chains_linux.go` (+346 -0) ➕ `client/firewall/iptables/dnat_linux.go` (+285 -0) ➕ `client/firewall/iptables/family_linux.go` (+252 -0) ➕ `client/firewall/iptables/filter_linux.go` (+346 -0) ➕ `client/firewall/iptables/interface_allower_linux.go` (+93 -0) ➕ `client/firewall/iptables/ipset_linux.go` (+104 -0) 📝 `client/firewall/iptables/manager_linux.go` (+93 -161) 📝 `client/firewall/iptables/manager_linux_test.go` (+54 -48) ➖ `client/firewall/iptables/router_linux.go` (+0 -1154) 📝 `client/firewall/iptables/router_linux_test.go` (+31 -63) ➕ `client/firewall/iptables/routing_linux.go` (+263 -0) 📝 `client/firewall/iptables/rule.go` (+10 -8) ➖ `client/firewall/iptables/rulestore_linux.go` (+0 -127) 📝 `client/firewall/iptables/state_linux.go` (+11 -21) ➕ `client/firewall/iptables/testhelpers_linux_test.go` (+27 -0) _...and 57 more files_ </details> ### 📄 Description ## Describe your changes Unifies the peer ACL and route ACL paths in the firewall backends into a single filtering API, lets a peer rule carry multiple sources per address family instead of one rule per source, and removes the partial userspace firewall mode. - Replace the separate peer/route filtering calls with one `AddFilterRule` that takes a source list and a destination, dispatched to the correct address family (input chain for peer rules, forward chain for route rules) - Group incoming management rules that share a selector and install a single multi-source rule per family, deduplicating identical flows - Add a dual-stack address-family abstraction so v4 and v6 rules are built and stored side by side, skipping the v6 path when the interface has no IPv6 - Split the nftables backend into focused files (chains, filtering, routing, DNAT, ipsets) around that abstraction - Delete filter rules by the rule the backend returns rather than by a bare id, so the id type is no longer overloaded as a rule handle - Remove the partial userspace firewall mode (userspace filter wrapping a native firewall); when the userspace firewall is forced, routing is always handled in userspace - Open the interface in foreign kernel filter chains through a single interface-allower abstraction (nftables, iptables-legacy fallback, firewalld trust, Windows netsh rule) instead of per-backend `AllowNetbird` methods - `NB_FORCE_USERSPACE_ROUTER` is now an alias for `NB_FORCE_USERSPACE_FIREWALL`: forcing userspace routing forces the userspace firewall, since the two are no longer separable ## Issue ticket number and link ## Stack <!-- branch-stack --> ### Checklist - [ ] Is it a bug fix - [ ] Is a typo/documentation fix - [ ] Is a feature enhancement - [x] It is a refactor - [x] Created tests that fail without the change (if possible) - [ ] This change does **not** modify the public API, gRPC protocols, functionality behavior, CLI / service flags, or introduce a new feature — **OR** I have discussed it with the NetBird team beforehand (link the issue / Slack thread in the description). See [CONTRIBUTING.md](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTING.md#discuss-changes-with-the-netbird-team-first). > By submitting this pull request, you confirm that you have read and agree to the terms of the [Contributor License Agreement](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md). ## Documentation Select exactly one: - [ ] I added/updated documentation for this change - [x] Documentation is **not needed** for this change (explain why) Firewall refactor. The only user-visible change is that `NB_FORCE_USERSPACE_ROUTER` now also forces the userspace firewall; the partial userspace mode it used to apply to no longer exists. ### Docs PR URL (required if "docs added" is checked) Paste the PR link from https://github.com/netbirdio/docs here: https://github.com/netbirdio/docs/pull/__ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Unified filter add/delete API, per-address-family firewall backends, deterministic DNAT/inbound/output support, and cross-platform interface allower implementations (Linux/Windows/others). * **Bug Fixes** * More robust startup/teardown, improved rollback and aggregated error reporting, safer rule install/remove, and clearer IPv6 handling and fallback logging. * **Refactor** * Consolidated peer/route flows into rule-centric APIs, canonical rule ID type, and a userspace firewall Config-driven constructor. * **Tests** * Expanded unit, integration, and benchmark coverage (firewall, ACLs, NAT/DNAT, IPv6). <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
saavagebueno added the pull-request label 2026-08-05 07:09:33 -04:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#28025