[PR #6332] [client] iptables: fall back to per-IP ACL rules when ipset is unavailable #25427

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

📋 Pull Request Information

Original PR: https://github.com/netbirdio/netbird/pull/6332
Author: @Lamera
Created: 6/3/2026
Status: 🔄 Open

Base: mainHead: fix/iptables-acl-ipset-fallback


📝 Commits (4)

  • 83202fe [client] iptables: fall back to per-IP ACL rules when ipset is unavailable
  • 8b903c9 [client] iptables: use a unique ipset probe name
  • ce80faa test: update ACL IPSet fallback test to use new manager initialization
  • e8b9ec0 ci: re-trigger pipeline

📊 Changes

2 files changed (+80 additions, -0 deletions)

View changed files

📝 client/firewall/iptables/acl_linux.go (+43 -0)
📝 client/firewall/iptables/manager_linux_test.go (+37 -0)

📄 Description

Problem

Since v0.68, every peer ACL rule on the iptables backend depends on an
ipset. On kernels that do not provide the ipset hash module
(ip_set_hash_net) — common on embedded/IoT devices and stripped-down custom
kernels — ipset creation fails with invalid argument.

AddPeerFiltering returns that error, but applyPeerACLs only logs it and
continues. As a result the NETBIRD-ACL-INPUT chain stays empty, and the
trailing catch-all DROP blocks all policy-permitted inbound traffic.

The failure is silent and fail-closed: the peer becomes unreachable even though
the policy explicitly allows the traffic. Last working release was v0.67.4; the
regression was introduced in v0.68.0.

Reported in discussion #6125.

Fix

  • Probe ipset support once during aclManager.init() by attempting to
    create (and destroy) a small hash:net probe set.
  • When ipset is unavailable, fall back to writing per-IP iptables rules
    (-s <ip>), matching the pre-0.68 behavior, so ACLs keep working. The
    existing filterRuleSpecs already supports the empty-ipset path.
  • Log a clear WARN pointing at the missing kernel module so the degradation
    is visible to operators (instead of silently dropping traffic).

This keeps the ipset fast path for kernels that support it, while restoring
correct ACL behavior on kernels that don't.

Testing

  • Added TestIptablesACLIPSetFallback, which forces the fallback path and
    asserts that the resulting rule uses -s <ip> (no --match-set) and is
    actually present in the ACL chain.
  • Verified on a real affected device (aarch64 embedded kernel without
    ip_set_hash_net): inbound connectivity to policy-permitted peers is
    restored.

Scope

iptables backend only. The nftables backend uses native sets and is not
affected.

Fixes #6125

Summary by CodeRabbit

  • Bug Fixes

    • Firewall ACLs now detect when kernel ipset hash:net support is unavailable and automatically fall back to generating effective per-IP iptables rules so access controls remain enforced instead of becoming silently ineffective.
  • Tests

    • Added a test that simulates missing ipset support and verifies the ACL manager produces valid non-ipset rules and installs them into the ACL chain.

Documentation

  • Documentation is not needed

🔄 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/6332 **Author:** [@Lamera](https://github.com/Lamera) **Created:** 6/3/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/iptables-acl-ipset-fallback` --- ### 📝 Commits (4) - [`83202fe`](https://github.com/netbirdio/netbird/commit/83202fe1933bdc4746bd374e803a37ce60862d50) [client] iptables: fall back to per-IP ACL rules when ipset is unavailable - [`8b903c9`](https://github.com/netbirdio/netbird/commit/8b903c9469fe89e15d81467377230dac42058e9b) [client] iptables: use a unique ipset probe name - [`ce80faa`](https://github.com/netbirdio/netbird/commit/ce80faa434eacc69a47994efb074db3654fb3693) test: update ACL IPSet fallback test to use new manager initialization - [`e8b9ec0`](https://github.com/netbirdio/netbird/commit/e8b9ec04d19ff03a34a97ecc197dbebca6c81e46) ci: re-trigger pipeline ### 📊 Changes **2 files changed** (+80 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `client/firewall/iptables/acl_linux.go` (+43 -0) 📝 `client/firewall/iptables/manager_linux_test.go` (+37 -0) </details> ### 📄 Description ## Problem Since v0.68, every peer ACL rule on the **iptables** backend depends on an ipset. On kernels that do not provide the ipset hash module (`ip_set_hash_net`) — common on embedded/IoT devices and stripped-down custom kernels — ipset creation fails with `invalid argument`. `AddPeerFiltering` returns that error, but `applyPeerACLs` only logs it and continues. As a result the `NETBIRD-ACL-INPUT` chain stays empty, and the trailing catch-all `DROP` blocks **all** policy-permitted inbound traffic. The failure is silent and fail-closed: the peer becomes unreachable even though the policy explicitly allows the traffic. Last working release was v0.67.4; the regression was introduced in v0.68.0. Reported in discussion #6125. ## Fix - Probe ipset support **once** during `aclManager.init()` by attempting to create (and destroy) a small `hash:net` probe set. - When ipset is unavailable, fall back to writing **per-IP iptables rules** (`-s <ip>`), matching the pre-0.68 behavior, so ACLs keep working. The existing `filterRuleSpecs` already supports the empty-ipset path. - Log a clear `WARN` pointing at the missing kernel module so the degradation is visible to operators (instead of silently dropping traffic). This keeps the ipset fast path for kernels that support it, while restoring correct ACL behavior on kernels that don't. ## Testing - Added `TestIptablesACLIPSetFallback`, which forces the fallback path and asserts that the resulting rule uses `-s <ip>` (no `--match-set`) and is actually present in the ACL chain. - Verified on a real affected device (aarch64 embedded kernel without `ip_set_hash_net`): inbound connectivity to policy-permitted peers is restored. ## Scope iptables backend only. The nftables backend uses native sets and is not affected. Fixes #6125 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Firewall ACLs now detect when kernel ipset hash:net support is unavailable and automatically fall back to generating effective per-IP iptables rules so access controls remain enforced instead of becoming silently ineffective. * **Tests** * Added a test that simulates missing ipset support and verifies the ACL manager produces valid non-ipset rules and installs them into the ACL chain. <!-- end of auto-generated comment: release notes by coderabbit.ai --> ## Documentation - [x] Documentation is **not needed** --- <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:06:00 -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#25427