mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-18 08:16:39 +00:00
[client,management] add netflow support to client and update management (#3414)
adds NetFlow functionality to track and log network traffic information between peers, with features including: - Flow logging for TCP, UDP, and ICMP traffic - Integration with connection tracking system - Resource ID tracking in NetFlow events - DNS and exit node collection configuration - Flow API and Redis cache in management - Memory-based flow storage implementation - Kernel conntrack counters and userspace counters - TCP state machine improvements for more accurate tracking - Migration from net.IP to netip.Addr in the userspace firewall
This commit is contained in:
@@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
s "github.com/netbirdio/netbird/management/server"
|
||||
"github.com/netbirdio/netbird/management/server/account"
|
||||
"github.com/netbirdio/netbird/management/server/activity"
|
||||
"github.com/netbirdio/netbird/management/server/groups"
|
||||
"github.com/netbirdio/netbird/management/server/networks/resources/types"
|
||||
@@ -31,13 +31,13 @@ type managerImpl struct {
|
||||
store store.Store
|
||||
permissionsManager permissions.Manager
|
||||
groupsManager groups.Manager
|
||||
accountManager s.AccountManager
|
||||
accountManager account.Manager
|
||||
}
|
||||
|
||||
type mockManager struct {
|
||||
}
|
||||
|
||||
func NewManager(store store.Store, permissionsManager permissions.Manager, groupsManager groups.Manager, accountManager s.AccountManager) Manager {
|
||||
func NewManager(store store.Store, permissionsManager permissions.Manager, groupsManager groups.Manager, accountManager account.Manager) Manager {
|
||||
return &managerImpl{
|
||||
store: store,
|
||||
permissionsManager: permissionsManager,
|
||||
|
||||
@@ -20,9 +20,9 @@ import (
|
||||
type NetworkResourceType string
|
||||
|
||||
const (
|
||||
host NetworkResourceType = "host"
|
||||
subnet NetworkResourceType = "subnet"
|
||||
domain NetworkResourceType = "domain"
|
||||
Host NetworkResourceType = "host"
|
||||
Subnet NetworkResourceType = "subnet"
|
||||
Domain NetworkResourceType = "domain"
|
||||
)
|
||||
|
||||
func (p NetworkResourceType) String() string {
|
||||
@@ -66,7 +66,7 @@ func NewNetworkResource(accountID, networkID, name, description, address string,
|
||||
|
||||
func (n *NetworkResource) ToAPIResponse(groups []api.GroupMinimum) *api.NetworkResource {
|
||||
addr := n.Prefix.String()
|
||||
if n.Type == domain {
|
||||
if n.Type == Domain {
|
||||
addr = n.Domain
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ func (n *NetworkResource) ToRoute(peer *nbpeer.Peer, router *routerTypes.Network
|
||||
AccessControlGroups: nil,
|
||||
}
|
||||
|
||||
if n.Type == host || n.Type == subnet {
|
||||
if n.Type == Host || n.Type == Subnet {
|
||||
r.Network = n.Prefix
|
||||
|
||||
r.NetworkType = route.IPv4Network
|
||||
@@ -134,7 +134,7 @@ func (n *NetworkResource) ToRoute(peer *nbpeer.Peer, router *routerTypes.Network
|
||||
}
|
||||
}
|
||||
|
||||
if n.Type == domain {
|
||||
if n.Type == Domain {
|
||||
domainList, err := nbDomain.FromStringList([]string{n.Domain})
|
||||
if err != nil {
|
||||
return nil
|
||||
@@ -157,18 +157,18 @@ func (n *NetworkResource) EventMeta(network *networkTypes.Network) map[string]an
|
||||
func GetResourceType(address string) (NetworkResourceType, string, netip.Prefix, error) {
|
||||
if prefix, err := netip.ParsePrefix(address); err == nil {
|
||||
if prefix.Bits() == 32 || prefix.Bits() == 128 {
|
||||
return host, "", prefix, nil
|
||||
return Host, "", prefix, nil
|
||||
}
|
||||
return subnet, "", prefix, nil
|
||||
return Subnet, "", prefix, nil
|
||||
}
|
||||
|
||||
if ip, err := netip.ParseAddr(address); err == nil {
|
||||
return host, "", netip.PrefixFrom(ip, ip.BitLen()), nil
|
||||
return Host, "", netip.PrefixFrom(ip, ip.BitLen()), nil
|
||||
}
|
||||
|
||||
domainRegex := regexp.MustCompile(`^(\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$`)
|
||||
if domainRegex.MatchString(address) {
|
||||
return domain, address, netip.Prefix{}, nil
|
||||
return Domain, address, netip.Prefix{}, nil
|
||||
}
|
||||
|
||||
return "", "", netip.Prefix{}, errors.New("not a valid host, subnet, or domain")
|
||||
|
||||
@@ -14,15 +14,15 @@ func TestGetResourceType(t *testing.T) {
|
||||
expectedPrefix netip.Prefix
|
||||
}{
|
||||
// Valid host IPs
|
||||
{"1.1.1.1", host, false, "", netip.MustParsePrefix("1.1.1.1/32")},
|
||||
{"1.1.1.1/32", host, false, "", netip.MustParsePrefix("1.1.1.1/32")},
|
||||
{"1.1.1.1", Host, false, "", netip.MustParsePrefix("1.1.1.1/32")},
|
||||
{"1.1.1.1/32", Host, false, "", netip.MustParsePrefix("1.1.1.1/32")},
|
||||
// Valid subnets
|
||||
{"192.168.1.0/24", subnet, false, "", netip.MustParsePrefix("192.168.1.0/24")},
|
||||
{"10.0.0.0/16", subnet, false, "", netip.MustParsePrefix("10.0.0.0/16")},
|
||||
{"192.168.1.0/24", Subnet, false, "", netip.MustParsePrefix("192.168.1.0/24")},
|
||||
{"10.0.0.0/16", Subnet, false, "", netip.MustParsePrefix("10.0.0.0/16")},
|
||||
// Valid domains
|
||||
{"example.com", domain, false, "example.com", netip.Prefix{}},
|
||||
{"*.example.com", domain, false, "*.example.com", netip.Prefix{}},
|
||||
{"sub.example.com", domain, false, "sub.example.com", netip.Prefix{}},
|
||||
{"example.com", Domain, false, "example.com", netip.Prefix{}},
|
||||
{"*.example.com", Domain, false, "*.example.com", netip.Prefix{}},
|
||||
{"sub.example.com", Domain, false, "sub.example.com", netip.Prefix{}},
|
||||
// Invalid inputs
|
||||
{"invalid", "", true, "", netip.Prefix{}},
|
||||
{"1.1.1.1/abc", "", true, "", netip.Prefix{}},
|
||||
@@ -32,7 +32,7 @@ func TestGetResourceType(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.input, func(t *testing.T) {
|
||||
result, domain, prefix, err := GetResourceType(tt.input)
|
||||
|
||||
|
||||
if result != tt.expectedType {
|
||||
t.Errorf("Expected type %v, got %v", tt.expectedType, result)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user