Add nftables

This commit is contained in:
Viktor Liu
2025-03-26 16:22:44 +01:00
parent 13ec9ea0e7
commit d2c96469f0
3 changed files with 56 additions and 9 deletions

View File

@@ -114,6 +114,10 @@ func (r *router) init(stateManager *statemanager.Manager) error {
log.Errorf("failed to clean up rules from FORWARD chain: %s", err)
}
if err := r.setupConntrackZones(); err != nil {
log.Errorf("failed to setup conntrack zones: %v", err)
}
if err := r.createContainers(); err != nil {
return fmt.Errorf("create containers: %w", err)
}
@@ -396,10 +400,6 @@ func (r *router) cleanUpDefaultForwardRules() error {
}
func (r *router) createContainers() error {
if err := r.setupConntrackZones(); err != nil {
log.Errorf("failed to setup conntrack zones: %v", err)
}
for _, chainInfo := range []struct {
chain string
table string

View File

@@ -21,6 +21,7 @@ import (
nberrors "github.com/netbirdio/netbird/client/errors"
firewall "github.com/netbirdio/netbird/client/firewall/manager"
nbid "github.com/netbirdio/netbird/client/internal/acl/id"
nftypes "github.com/netbirdio/netbird/client/internal/netflow/types"
"github.com/netbirdio/netbird/client/internal/routemanager/ipfwdstate"
"github.com/netbirdio/netbird/client/internal/routemanager/refcounter"
nbnet "github.com/netbirdio/netbird/util/net"
@@ -33,6 +34,7 @@ const (
chainNameRoutingNat = "netbird-rt-postrouting"
chainNameRoutingRdr = "netbird-rt-redirect"
chainNameForward = "FORWARD"
chainNameRaw = "netbird-raw"
userDataAcceptForwardRuleIif = "frwacceptiif"
userDataAcceptForwardRuleOif = "frwacceptoif"
@@ -96,6 +98,10 @@ func (r *router) init(workTable *nftables.Table) error {
log.Errorf("failed to clean up rules from FORWARD chain: %s", err)
}
if err := r.setupConntrackZones(); err != nil {
log.Errorf("failed to setup conntrack zones: %v", err)
}
if err := r.createContainers(); err != nil {
return fmt.Errorf("create containers: %w", err)
}
@@ -226,6 +232,49 @@ func (r *router) createContainers() error {
return nil
}
// setupConntrackZones configures the connection tracking zones for the NetBird interface
func (r *router) setupConntrackZones() error {
rawChain := r.conn.AddChain(&nftables.Chain{
Name: chainNameRaw,
Table: r.workTable,
Type: nftables.ChainTypeFilter,
Hooknum: nftables.ChainHookPrerouting,
Priority: nftables.ChainPriorityRaw,
})
exprs := []expr.Any{
&expr.Meta{
Key: expr.MetaKeyIIFNAME,
Register: 1,
},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: ifname(r.wgIface.Name()),
},
&expr.Immediate{
Register: 1,
Data: binaryutil.NativeEndian.PutUint32(nftypes.ZoneID),
},
&expr.Ct{
Key: expr.CtKeyZONE,
Register: 1,
SourceRegister: true,
},
}
r.conn.AddRule(&nftables.Rule{
Table: r.workTable,
Chain: rawChain,
Exprs: exprs,
})
if err := r.conn.Flush(); err != nil {
return fmt.Errorf("nftables: flush conntrack zone: %w", err)
}
return nil
}
// AddRouteFiltering appends a nftables rule to the routing chain
func (r *router) AddRouteFiltering(
id []byte,

View File

@@ -225,16 +225,14 @@ func (c *ConnTrack) handleEvent(event nfct.Event) {
// relevantFlow checks if the flow is related to the specified interface
func (c *ConnTrack) relevantFlow(zone uint16, srcIP, dstIP netip.Addr) bool {
// This currently only covers inbound.
// TODO: handle outbound flows based on interface for site2site traffic
if zone == nftypes.ZoneID {
return true
}
wgnet := c.iface.Address().Network
if !wgnet.Contains(srcIP.AsSlice()) && !wgnet.Contains(dstIP.AsSlice()) {
return false
}
return true
return wgnet.Contains(srcIP.AsSlice()) || wgnet.Contains(dstIP.AsSlice())
}
// mapRxPackets maps packet counts to RX based on flow direction