Skip to content

Commit

Permalink
Merge branch 'main' into feature/add-db-timings-to-log
Browse files Browse the repository at this point in the history
  • Loading branch information
pascal-fischer authored Nov 1, 2024
2 parents 3de9145 + 9812de8 commit f0a40a7
Show file tree
Hide file tree
Showing 50 changed files with 930 additions and 1,166 deletions.
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: [netbirdio]
8 changes: 5 additions & 3 deletions client/cmd/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ func parsePeers(peers peersStateOutput, rosenpassEnabled, rosenpassPermissive bo
func skipDetailByFilters(peerState *proto.PeerState, isConnected bool) bool {
statusEval := false
ipEval := false
nameEval := false
nameEval := true

if statusFilter != "" {
lowerStatusFilter := strings.ToLower(statusFilter)
Expand All @@ -700,11 +700,13 @@ func skipDetailByFilters(peerState *proto.PeerState, isConnected bool) bool {

if len(prefixNamesFilter) > 0 {
for prefixNameFilter := range prefixNamesFilterMap {
if !strings.HasPrefix(peerState.Fqdn, prefixNameFilter) {
nameEval = true
if strings.HasPrefix(peerState.Fqdn, prefixNameFilter) {
nameEval = false
break
}
}
} else {
nameEval = false
}

return statusEval || ipEval || nameEval
Expand Down
62 changes: 28 additions & 34 deletions client/firewall/create_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package firewall

import (
"errors"
"fmt"
"os"

Expand Down Expand Up @@ -37,62 +38,55 @@ func NewFirewall(iface IFaceMapper, stateManager *statemanager.Manager) (firewal
// in any case, because we need to allow netbird interface traffic
// so we use AllowNetbird traffic from these firewall managers
// for the userspace packet filtering firewall
fm, errFw := createNativeFirewall(iface)
fm, err := createNativeFirewall(iface, stateManager)

if fm != nil {
if err := fm.Init(stateManager); err != nil {
log.Errorf("failed to init nftables manager: %s", err)
}
if !iface.IsUserspaceBind() {
return fm, err
}

if err != nil {
log.Warnf("failed to create native firewall: %v. Proceeding with userspace", err)
}
return createUserspaceFirewall(iface, fm)
}

if iface.IsUserspaceBind() {
return createUserspaceFirewall(iface, fm, errFw)
func createNativeFirewall(iface IFaceMapper, stateManager *statemanager.Manager) (firewall.Manager, error) {
fm, err := createFW(iface)
if err != nil {
return nil, fmt.Errorf("create firewall: %s", err)
}

return fm, errFw
if err = fm.Init(stateManager); err != nil {
return nil, fmt.Errorf("init firewall: %s", err)
}

return fm, nil
}

func createNativeFirewall(iface IFaceMapper) (firewall.Manager, error) {
func createFW(iface IFaceMapper) (firewall.Manager, error) {
switch check() {
case IPTABLES:
return createIptablesFirewall(iface)
log.Info("creating an iptables firewall manager")
return nbiptables.Create(iface)
case NFTABLES:
return createNftablesFirewall(iface)
log.Info("creating an nftables firewall manager")
return nbnftables.Create(iface)
default:
log.Info("no firewall manager found, trying to use userspace packet filtering firewall")
return nil, fmt.Errorf("no firewall manager found")
return nil, errors.New("no firewall manager found")
}
}

func createIptablesFirewall(iface IFaceMapper) (firewall.Manager, error) {
log.Info("creating an iptables firewall manager")
fm, err := nbiptables.Create(iface)
if err != nil {
log.Errorf("failed to create iptables manager: %s", err)
}
return fm, err
}

func createNftablesFirewall(iface IFaceMapper) (firewall.Manager, error) {
log.Info("creating an nftables firewall manager")
fm, err := nbnftables.Create(iface)
if err != nil {
log.Errorf("failed to create nftables manager: %s", err)
}
return fm, err
}

func createUserspaceFirewall(iface IFaceMapper, fm firewall.Manager, errFw error) (firewall.Manager, error) {
func createUserspaceFirewall(iface IFaceMapper, fm firewall.Manager) (firewall.Manager, error) {
var errUsp error
if errFw == nil {
if fm != nil {
fm, errUsp = uspfilter.CreateWithNativeFirewall(iface, fm)
} else {
fm, errUsp = uspfilter.Create(iface)
}

if errUsp != nil {
log.Debugf("failed to create userspace filtering firewall: %s", errUsp)
return nil, errUsp
return nil, fmt.Errorf("create userspace firewall: %s", errUsp)
}

if err := fm.AllowNetbird(); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions client/firewall/iptables/router_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ func (r *router) RemoveAllLegacyRouteRules() error {
}
if err := r.iptablesClient.DeleteIfExists(tableFilter, chainRTFWD, rule...); err != nil {
merr = multierror.Append(merr, fmt.Errorf("remove legacy forwarding rule: %v", err))
} else {
delete(r.rules, k)
}
}

Expand Down
18 changes: 1 addition & 17 deletions client/firewall/nftables/manager_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,23 +230,7 @@ func (m *Manager) AllowNetbird() error {

// SetLegacyManagement sets the route manager to use legacy management
func (m *Manager) SetLegacyManagement(isLegacy bool) error {
oldLegacy := m.router.legacyManagement

if oldLegacy != isLegacy {
m.router.legacyManagement = isLegacy
log.Debugf("Set legacy management to %v", isLegacy)
}

// client reconnected to a newer mgmt, we need to cleanup the legacy rules
if !isLegacy && oldLegacy {
if err := m.router.RemoveAllLegacyRouteRules(); err != nil {
return fmt.Errorf("remove legacy routing rules: %v", err)
}

log.Debugf("Legacy routing rules removed")
}

return nil
return firewall.SetLegacyManagement(m.router, isLegacy)
}

// Reset firewall to the default state
Expand Down
3 changes: 3 additions & 0 deletions client/firewall/nftables/router_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,10 @@ func (r *router) RemoveAllLegacyRouteRules() error {
}
if err := r.conn.DelRule(rule); err != nil {
merr = multierror.Append(merr, fmt.Errorf("remove legacy forwarding rule: %v", err))
} else {
delete(r.rules, k)
}

}
return nberrors.FormatErrorOrNil(merr)
}
Expand Down
7 changes: 5 additions & 2 deletions client/firewall/uspfilter/uspfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,11 @@ func (m *Manager) DeletePeerRule(rule firewall.Rule) error {
}

// SetLegacyManagement doesn't need to be implemented for this manager
func (m *Manager) SetLegacyManagement(_ bool) error {
return nil
func (m *Manager) SetLegacyManagement(isLegacy bool) error {
if m.nativeFirewall == nil {
return errRouteNotSupported
}
return m.nativeFirewall.SetLegacyManagement(isLegacy)
}

// Flush doesn't need to be implemented for this manager
Expand Down
2 changes: 1 addition & 1 deletion client/iface/wgproxy/bind/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ func (p *ProxyBind) proxyToLocal(ctx context.Context) {
}
}()

buf := make([]byte, 1500)
for {
buf := make([]byte, 1500)
n, err := p.remoteConn.Read(buf)
if err != nil {
if ctx.Err() != nil {
Expand Down
30 changes: 22 additions & 8 deletions client/internal/acl/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,26 @@ package acl
import (
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"net"
"net/netip"
"strconv"
"sync"
"time"

"github.com/hashicorp/go-multierror"
log "github.com/sirupsen/logrus"

nberrors "github.com/netbirdio/netbird/client/errors"
firewall "github.com/netbirdio/netbird/client/firewall/manager"
"github.com/netbirdio/netbird/client/internal/acl/id"
"github.com/netbirdio/netbird/client/ssh"
mgmProto "github.com/netbirdio/netbird/management/proto"
)

var ErrSourceRangesEmpty = errors.New("sources range is empty")

// Manager is a ACL rules manager
type Manager interface {
ApplyFiltering(networkMap *mgmProto.NetworkMap)
Expand Down Expand Up @@ -167,31 +172,40 @@ func (d *DefaultManager) applyPeerACLs(networkMap *mgmProto.NetworkMap) {
}

func (d *DefaultManager) applyRouteACLs(rules []*mgmProto.RouteFirewallRule) error {
var newRouteRules = make(map[id.RuleID]struct{})
newRouteRules := make(map[id.RuleID]struct{}, len(rules))
var merr *multierror.Error

// Apply new rules - firewall manager will return existing rule ID if already present
for _, rule := range rules {
id, err := d.applyRouteACL(rule)
if err != nil {
return fmt.Errorf("apply route ACL: %w", err)
if errors.Is(err, ErrSourceRangesEmpty) {
log.Debugf("skipping empty rule with destination %s: %v", rule.Destination, err)
} else {
merr = multierror.Append(merr, fmt.Errorf("add route rule: %w", err))
}
continue
}
newRouteRules[id] = struct{}{}
}

// Clean up old firewall rules
for id := range d.routeRules {
if _, ok := newRouteRules[id]; !ok {
if _, exists := newRouteRules[id]; !exists {
if err := d.firewall.DeleteRouteRule(id); err != nil {
log.Errorf("failed to delete route firewall rule: %v", err)
continue
merr = multierror.Append(merr, fmt.Errorf("delete route rule: %w", err))
}
delete(d.routeRules, id)
// implicitly deleted from the map
}
}

d.routeRules = newRouteRules
return nil
return nberrors.FormatErrorOrNil(merr)
}

func (d *DefaultManager) applyRouteACL(rule *mgmProto.RouteFirewallRule) (id.RuleID, error) {
if len(rule.SourceRanges) == 0 {
return "", fmt.Errorf("source ranges is empty")
return "", ErrSourceRangesEmpty
}

var sources []netip.Prefix
Expand Down
5 changes: 5 additions & 0 deletions client/internal/peer/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ func (conn *Conn) iCEConnectionIsReady(priority ConnPriority, iceConnInfo ICECon
return
}

if remoteConnNil(conn.log, iceConnInfo.RemoteConn) {
conn.log.Errorf("remote ICE connection is nil")
return
}

conn.log.Debugf("ICE connection is ready")

if conn.currentConnPriority > priority {
Expand Down
12 changes: 5 additions & 7 deletions client/internal/peer/ice/agent.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package ice

import (
"github.com/netbirdio/netbird/client/internal/stdnet"
"time"

"github.com/pion/ice/v3"
"github.com/pion/randutil"
"github.com/pion/stun/v2"
log "github.com/sirupsen/logrus"
"runtime"
"time"

"github.com/netbirdio/netbird/client/internal/stdnet"
)

const (
Expand Down Expand Up @@ -77,10 +78,7 @@ func CandidateTypes() []ice.CandidateType {
if hasICEForceRelayConn() {
return []ice.CandidateType{ice.CandidateTypeRelay}
}
// TODO: remove this once we have refactored userspace proxy into the bind package
if runtime.GOOS == "ios" {
return []ice.CandidateType{ice.CandidateTypeHost, ice.CandidateTypeServerReflexive}
}

return []ice.CandidateType{ice.CandidateTypeHost, ice.CandidateTypeServerReflexive, ice.CandidateTypeRelay}
}

Expand Down
21 changes: 21 additions & 0 deletions client/internal/peer/nilcheck.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package peer

import (
"net"

log "github.com/sirupsen/logrus"
)

func remoteConnNil(log *log.Entry, conn net.Conn) bool {
if conn == nil {
log.Errorf("ice conn is nil")
return true
}

if conn.RemoteAddr() == nil {
log.Errorf("ICE remote address is nil")
return true
}

return false
}
Loading

0 comments on commit f0a40a7

Please sign in to comment.