mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-19 00:36:38 +00:00
Compare commits
2 Commits
dependabot
...
use-conntr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2c96469f0 | ||
|
|
13ec9ea0e7 |
@@ -16,6 +16,7 @@ import (
|
|||||||
nberrors "github.com/netbirdio/netbird/client/errors"
|
nberrors "github.com/netbirdio/netbird/client/errors"
|
||||||
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
||||||
nbid "github.com/netbirdio/netbird/client/internal/acl/id"
|
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/ipfwdstate"
|
||||||
"github.com/netbirdio/netbird/client/internal/routemanager/refcounter"
|
"github.com/netbirdio/netbird/client/internal/routemanager/refcounter"
|
||||||
"github.com/netbirdio/netbird/client/internal/statemanager"
|
"github.com/netbirdio/netbird/client/internal/statemanager"
|
||||||
@@ -27,6 +28,7 @@ const (
|
|||||||
tableFilter = "filter"
|
tableFilter = "filter"
|
||||||
tableNat = "nat"
|
tableNat = "nat"
|
||||||
tableMangle = "mangle"
|
tableMangle = "mangle"
|
||||||
|
tableRaw = "raw"
|
||||||
|
|
||||||
chainPOSTROUTING = "POSTROUTING"
|
chainPOSTROUTING = "POSTROUTING"
|
||||||
chainPREROUTING = "PREROUTING"
|
chainPREROUTING = "PREROUTING"
|
||||||
@@ -41,6 +43,7 @@ const (
|
|||||||
jumpManglePre = "jump-mangle-pre"
|
jumpManglePre = "jump-mangle-pre"
|
||||||
jumpNatPre = "jump-nat-pre"
|
jumpNatPre = "jump-nat-pre"
|
||||||
jumpNatPost = "jump-nat-post"
|
jumpNatPost = "jump-nat-post"
|
||||||
|
zoneRawPre = "zone-raw-pre"
|
||||||
matchSet = "--match-set"
|
matchSet = "--match-set"
|
||||||
|
|
||||||
dnatSuffix = "_dnat"
|
dnatSuffix = "_dnat"
|
||||||
@@ -111,6 +114,10 @@ func (r *router) init(stateManager *statemanager.Manager) error {
|
|||||||
log.Errorf("failed to clean up rules from FORWARD chain: %s", err)
|
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 {
|
if err := r.createContainers(); err != nil {
|
||||||
return fmt.Errorf("create containers: %w", err)
|
return fmt.Errorf("create containers: %w", err)
|
||||||
}
|
}
|
||||||
@@ -354,6 +361,10 @@ func (r *router) Reset() error {
|
|||||||
merr = multierror.Append(merr, err)
|
merr = multierror.Append(merr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := r.cleanupConntrackZones(); err != nil {
|
||||||
|
merr = multierror.Append(merr, err)
|
||||||
|
}
|
||||||
|
|
||||||
r.updateState()
|
r.updateState()
|
||||||
|
|
||||||
return nberrors.FormatErrorOrNil(merr)
|
return nberrors.FormatErrorOrNil(merr)
|
||||||
@@ -423,6 +434,33 @@ func (r *router) createContainers() error {
|
|||||||
return nil
|
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 {
|
func (r *router) addPostroutingRules() error {
|
||||||
// First rule for outbound masquerade
|
// First rule for outbound masquerade
|
||||||
rule1 := []string{
|
rule1 := []string{
|
||||||
@@ -464,7 +502,7 @@ func (r *router) insertEstablishedRule(chain string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *router) addJumpRules() error {
|
func (r *router) addJumpRules() error {
|
||||||
// Jump to NAT chain
|
// Jump to nat chain
|
||||||
natRule := []string{"-j", chainRTNAT}
|
natRule := []string{"-j", chainRTNAT}
|
||||||
if err := r.iptablesClient.Insert(tableNat, chainPOSTROUTING, 1, natRule...); err != nil {
|
if err := r.iptablesClient.Insert(tableNat, chainPOSTROUTING, 1, natRule...); err != nil {
|
||||||
return fmt.Errorf("add nat postrouting jump rule: %v", err)
|
return fmt.Errorf("add nat postrouting jump rule: %v", err)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
nberrors "github.com/netbirdio/netbird/client/errors"
|
nberrors "github.com/netbirdio/netbird/client/errors"
|
||||||
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
firewall "github.com/netbirdio/netbird/client/firewall/manager"
|
||||||
nbid "github.com/netbirdio/netbird/client/internal/acl/id"
|
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/ipfwdstate"
|
||||||
"github.com/netbirdio/netbird/client/internal/routemanager/refcounter"
|
"github.com/netbirdio/netbird/client/internal/routemanager/refcounter"
|
||||||
nbnet "github.com/netbirdio/netbird/util/net"
|
nbnet "github.com/netbirdio/netbird/util/net"
|
||||||
@@ -33,6 +34,7 @@ const (
|
|||||||
chainNameRoutingNat = "netbird-rt-postrouting"
|
chainNameRoutingNat = "netbird-rt-postrouting"
|
||||||
chainNameRoutingRdr = "netbird-rt-redirect"
|
chainNameRoutingRdr = "netbird-rt-redirect"
|
||||||
chainNameForward = "FORWARD"
|
chainNameForward = "FORWARD"
|
||||||
|
chainNameRaw = "netbird-raw"
|
||||||
|
|
||||||
userDataAcceptForwardRuleIif = "frwacceptiif"
|
userDataAcceptForwardRuleIif = "frwacceptiif"
|
||||||
userDataAcceptForwardRuleOif = "frwacceptoif"
|
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)
|
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 {
|
if err := r.createContainers(); err != nil {
|
||||||
return fmt.Errorf("create containers: %w", err)
|
return fmt.Errorf("create containers: %w", err)
|
||||||
}
|
}
|
||||||
@@ -226,6 +232,49 @@ func (r *router) createContainers() error {
|
|||||||
return nil
|
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
|
// AddRouteFiltering appends a nftables rule to the routing chain
|
||||||
func (r *router) AddRouteFiltering(
|
func (r *router) AddRouteFiltering(
|
||||||
id []byte,
|
id []byte,
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ func (c *ConnTrack) handleEvent(event nfct.Event) {
|
|||||||
srcIP := flow.TupleOrig.IP.SourceAddress
|
srcIP := flow.TupleOrig.IP.SourceAddress
|
||||||
dstIP := flow.TupleOrig.IP.DestinationAddress
|
dstIP := flow.TupleOrig.IP.DestinationAddress
|
||||||
|
|
||||||
if !c.relevantFlow(srcIP, dstIP) {
|
if !c.relevantFlow(flow.Zone, srcIP, dstIP) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,15 +224,15 @@ func (c *ConnTrack) handleEvent(event nfct.Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// relevantFlow checks if the flow is related to the specified interface
|
// relevantFlow checks if the flow is related to the specified interface
|
||||||
func (c *ConnTrack) relevantFlow(srcIP, dstIP netip.Addr) bool {
|
func (c *ConnTrack) relevantFlow(zone uint16, srcIP, dstIP netip.Addr) bool {
|
||||||
// TODO: filter traffic by interface
|
// This currently only covers inbound.
|
||||||
|
// TODO: handle outbound flows based on interface for site2site traffic
|
||||||
wgnet := c.iface.Address().Network
|
if zone == nftypes.ZoneID {
|
||||||
if !wgnet.Contains(srcIP.AsSlice()) && !wgnet.Contains(dstIP.AsSlice()) {
|
return true
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
wgnet := c.iface.Address().Network
|
||||||
|
return wgnet.Contains(srcIP.AsSlice()) || wgnet.Contains(dstIP.AsSlice())
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapRxPackets maps packet counts to RX based on flow direction
|
// mapRxPackets maps packet counts to RX based on flow direction
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import (
|
|||||||
"github.com/netbirdio/netbird/client/iface/wgaddr"
|
"github.com/netbirdio/netbird/client/iface/wgaddr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const ZoneID = 0x1BD0
|
||||||
|
|
||||||
type Protocol uint8
|
type Protocol uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
Reference in New Issue
Block a user