diff --git a/client/firewall/iptables/router_linux.go b/client/firewall/iptables/router_linux.go index eae9f7e25..5b1b162ef 100644 --- a/client/firewall/iptables/router_linux.go +++ b/client/firewall/iptables/router_linux.go @@ -16,6 +16,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" "github.com/netbirdio/netbird/client/internal/statemanager" @@ -27,6 +28,7 @@ const ( tableFilter = "filter" tableNat = "nat" tableMangle = "mangle" + tableRaw = "raw" chainPOSTROUTING = "POSTROUTING" chainPREROUTING = "PREROUTING" @@ -41,6 +43,7 @@ const ( jumpManglePre = "jump-mangle-pre" jumpNatPre = "jump-nat-pre" jumpNatPost = "jump-nat-post" + zoneRawPre = "zone-raw-pre" matchSet = "--match-set" dnatSuffix = "_dnat" @@ -354,6 +357,10 @@ func (r *router) Reset() error { merr = multierror.Append(merr, err) } + if err := r.cleanupConntrackZones(); err != nil { + merr = multierror.Append(merr, err) + } + r.updateState() return nberrors.FormatErrorOrNil(merr) @@ -389,6 +396,10 @@ 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 @@ -423,6 +434,33 @@ func (r *router) createContainers() error { return nil } +func (r *router) setupConntrackZones() error { + preRule := []string{ + "-i", r.wgIface.Name(), + "-j", "CT", + "--zone", fmt.Sprintf("%d", nftypes.ZoneID), + } + + if err := r.iptablesClient.AppendUnique(tableRaw, chainPREROUTING, preRule...); err != nil { + return fmt.Errorf("add raw prerouting zone rule: %w", err) + } + + r.rules[zoneRawPre] = preRule + + return nil +} + +func (r *router) cleanupConntrackZones() error { + if preRule, exists := r.rules[zoneRawPre]; exists { + if err := r.iptablesClient.DeleteIfExists(tableRaw, chainPREROUTING, preRule...); err != nil { + return fmt.Errorf("remove raw prerouting zone rule: %w", err) + } + delete(r.rules, zoneRawPre) + } + + return nil +} + func (r *router) addPostroutingRules() error { // First rule for outbound masquerade rule1 := []string{ @@ -464,7 +502,7 @@ func (r *router) insertEstablishedRule(chain string) error { } func (r *router) addJumpRules() error { - // Jump to NAT chain + // Jump to nat chain natRule := []string{"-j", chainRTNAT} if err := r.iptablesClient.Insert(tableNat, chainPOSTROUTING, 1, natRule...); err != nil { return fmt.Errorf("add nat postrouting jump rule: %v", err) diff --git a/client/internal/netflow/conntrack/conntrack.go b/client/internal/netflow/conntrack/conntrack.go index c0614406d..63fb84aa8 100644 --- a/client/internal/netflow/conntrack/conntrack.go +++ b/client/internal/netflow/conntrack/conntrack.go @@ -176,7 +176,7 @@ func (c *ConnTrack) handleEvent(event nfct.Event) { srcIP := flow.TupleOrig.IP.SourceAddress dstIP := flow.TupleOrig.IP.DestinationAddress - if !c.relevantFlow(srcIP, dstIP) { + if !c.relevantFlow(flow.Zone, srcIP, dstIP) { return } @@ -224,8 +224,10 @@ func (c *ConnTrack) handleEvent(event nfct.Event) { } // relevantFlow checks if the flow is related to the specified interface -func (c *ConnTrack) relevantFlow(srcIP, dstIP netip.Addr) bool { - // TODO: filter traffic by interface +func (c *ConnTrack) relevantFlow(zone uint16, srcIP, dstIP netip.Addr) bool { + if zone == nftypes.ZoneID { + return true + } wgnet := c.iface.Address().Network if !wgnet.Contains(srcIP.AsSlice()) && !wgnet.Contains(dstIP.AsSlice()) { diff --git a/client/internal/netflow/types/types.go b/client/internal/netflow/types/types.go index 881f30bd8..1f34e49db 100644 --- a/client/internal/netflow/types/types.go +++ b/client/internal/netflow/types/types.go @@ -10,6 +10,8 @@ import ( "github.com/netbirdio/netbird/client/iface/wgaddr" ) +const ZoneID = 0x1BD0 + type Protocol uint8 const (