Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[client] Add experimental support for userspace routing #3134

Open
wants to merge 63 commits into
base: main
Choose a base branch
from

Conversation

lixmal
Copy link
Contributor

@lixmal lixmal commented Dec 31, 2024

Describe your changes

  • Implements userspace packet routing for all operating systems
  • Option to use the native firewall if it supports routing (= previous behavior on Linux hosts in userspace)
  • Enables local traffic handling in netstack mode by forwarding packets to localhost
  • Adds route ACLs for forwarded traffic
  • Removes the inbound allow rule for non-netbird (= routed) return traffic, relying instead on connection tracking
  • Distinguishes between local and forwarded traffic based on interface IP address bitmap
  • Adds logger for connection trackers
  • Adds packet tracer
  • Process firewall drop rules first

New environment variables:

NB_DISABLE_USERSPACE_ROUTING: Disables userspace routing
NB_FORCE_USERSPACE_ROUTER: Forces use of userspace routing even if native OS routing is available
NB_ENABLE_NETSTACK_LOCAL_FORWARDING: Enables forwarding to localhost in netstack mode

New flow

flowchart TB
    Start([Inbound Packet]) --> StatefulEnabled{Stateful Enabled?}
    
    StatefulEnabled -->|Yes| TrackedConn{Matches Tracked Connection?}
    TrackedConn -->|Yes| Accept1[Accept Packet]
    TrackedConn -->|No| LocalIP
    
    StatefulEnabled -->|No| LocalIP{Is Local IP?}
    
    LocalIP -->|Yes| PeerACL{Peer ACLs Allow?}
    PeerACL -->|Yes| NetstackMode{Netstack Mode?}
    PeerACL -->|No| Drop1[Drop Packet]
    
    NetstackMode -->|Yes| ForwardLocal[Forward to Local Stack]
    NetstackMode -->|No| Accept2[Accept Packet]
    
    LocalIP -->|No| RoutingEnabled{Routing Enabled?}
    RoutingEnabled -->|No| Drop2[Drop Packet]
    RoutingEnabled -->|Yes| NativeRouter{Native Router?}
    
    NativeRouter -->|Yes| Accept3[Accept Packet]
    NativeRouter -->|No| RouteACLs{Route ACLs Allow?}
    
    RouteACLs -->|Yes| Forward[Pass to Forwarder]
    RouteACLs -->|No| Drop3[Drop Packet]
Loading

Example tracer output:

$ netbird debug trace in 100.64.31.206 1.1.1.1 -p tcp --dport 80

Packet trace 100.64.31.206:54435 -> 1.1.1.1:80 (TCP)

Received: Received TCP packet: 100.64.31.206:54435 -> 1.1.1.1:80
Connection Tracking: No existing connection found
Routing: Routing enabled, checking ACLs
Route ACL: Allowed by route ACLs
Forwarding: Forwarding to proxy-remote [proxy-remote to 1.1.1.1:80]
Completed: Processing completed

Final disposition: ALLOWED

Issue ticket number and link

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)
  • Extended the README / documentation, if necessary

@netbirdio netbirdio deleted a comment from Silex Jan 3, 2025
@mlsmaycon mlsmaycon requested a review from Copilot January 14, 2025 09:47

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 41 out of 56 changed files in this pull request and generated 1 comment.

Files not reviewed (15)
  • client/firewall/uspfilter/conntrack/udp_test.go: Evaluated as low risk
  • client/firewall/uspfilter/conntrack/icmp_test.go: Evaluated as low risk
  • client/firewall/create.go: Evaluated as low risk
  • client/firewall/uspfilter/conntrack/tcp_test.go: Evaluated as low risk
  • client/firewall/uspfilter/conntrack/common.go: Evaluated as low risk
  • client/firewall/create_linux.go: Evaluated as low risk
  • client/firewall/nftables/manager_linux.go: Evaluated as low risk
  • client/firewall/uspfilter/allow_netbird.go: Evaluated as low risk
  • client/firewall/manager/firewall.go: Evaluated as low risk
  • client/firewall/uspfilter/allow_netbird_windows.go: Evaluated as low risk
  • client/firewall/iptables/manager_linux.go: Evaluated as low risk
  • client/firewall/uspfilter/conntrack/udp.go: Evaluated as low risk
  • client/firewall/uspfilter/conntrack/common_test.go: Evaluated as low risk
  • client/firewall/uspfilter/conntrack/tcp.go: Evaluated as low risk
  • client/firewall/uspfilter/conntrack/icmp.go: Evaluated as low risk
Comments suppressed due to low confidence (2)

client/firewall/iface.go:15

  • [nitpick] The method name GetDevice is ambiguous. It should be renamed to GetFilteredDevice to be more descriptive.
GetDevice() *device.FilteredDevice

client/firewall/iface.go:16

  • [nitpick] The method name GetWGDevice is ambiguous. It should be renamed to GetWireGuardDevice to be more descriptive.
GetWGDevice() *wgdevice.Device
@netbirdio netbirdio deleted a comment from Copilot bot Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant