From 2bbe0f3f094b02dc17f560a4fbdea765dce2ba7a Mon Sep 17 00:00:00 2001 From: Viktor Liu <17948409+lixmal@users.noreply.github.com> Date: Sat, 22 Mar 2025 11:56:00 +0100 Subject: [PATCH 1/8] [client] Don't permanently fail on flow grpc shutdown (#3557) --- flow/client/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow/client/client.go b/flow/client/client.go index 582407ed5..f4e9aee39 100644 --- a/flow/client/client.go +++ b/flow/client/client.go @@ -95,7 +95,7 @@ func (c *GRPCClient) Receive(ctx context.Context, interval time.Duration, msgHan func (c *GRPCClient) establishStreamAndReceive(ctx context.Context, msgHandler func(msg *proto.FlowEventAck) error) error { if c.clientConn.GetState() == connectivity.Shutdown { - return backoff.Permanent(errors.New("connection to flow receiver has been shut down")) + return errors.New("connection to flow receiver has been shut down") } stream, err := c.realClient.Events(ctx, grpc.WaitForReady(true)) From 99b41543b8ba4f5edf23dd959c1c6502cc996ca7 Mon Sep 17 00:00:00 2001 From: Viktor Liu <17948409+lixmal@users.noreply.github.com> Date: Sat, 22 Mar 2025 18:51:48 +0100 Subject: [PATCH 2/8] [client] Fix flows for embedded listeners (#3564) --- client/firewall/uspfilter/uspfilter.go | 7 ++----- client/internal/netflow/manager.go | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/client/firewall/uspfilter/uspfilter.go b/client/firewall/uspfilter/uspfilter.go index 92da1b240..eb4438dbd 100644 --- a/client/firewall/uspfilter/uspfilter.go +++ b/client/firewall/uspfilter/uspfilter.go @@ -710,21 +710,18 @@ func (m *Manager) handleLocalTraffic(d *decoder, srcIP, dstIP netip.Addr, packet } // if running in netstack mode we need to pass this to the forwarder - if m.netstack { + if m.netstack && m.localForwarding { return m.handleNetstackLocalTraffic(packetData) } // track inbound packets to get the correct direction and session id for flows m.trackInbound(d, srcIP, dstIP, ruleID, size) + // pass to either native or virtual stack (to be picked up by listeners) return false } func (m *Manager) handleNetstackLocalTraffic(packetData []byte) bool { - if !m.localForwarding { - // pass to virtual tcp/ip stack to be picked up by listeners - return false - } fwd := m.forwarder.Load() if fwd == nil { diff --git a/client/internal/netflow/manager.go b/client/internal/netflow/manager.go index b9068774c..ce642b86a 100644 --- a/client/internal/netflow/manager.go +++ b/client/internal/netflow/manager.go @@ -198,7 +198,7 @@ func (m *Manager) receiveACKs(client *client.GRPCClient) { return nil } log.Tracef("received flow event ack: %s", id) - m.logger.DeleteEvents([]uuid.UUID{uuid.UUID(ack.EventId)}) + m.logger.DeleteEvents([]uuid.UUID{id}) return nil }) From 8b4c0c58e4f6043d740e4a2c471e5f7a2aed7f57 Mon Sep 17 00:00:00 2001 From: Maycon Santos Date: Sat, 22 Mar 2025 22:22:34 +0100 Subject: [PATCH 3/8] [client] Add initiator field to ack (#3563) added the new field and client handling --- flow/client/client.go | 11 +++- flow/proto/flow.pb.go | 128 +++++++++++++++++++++++------------------- flow/proto/flow.proto | 1 + 3 files changed, 80 insertions(+), 60 deletions(-) diff --git a/flow/client/client.go b/flow/client/client.go index f4e9aee39..2d3890ba5 100644 --- a/flow/client/client.go +++ b/flow/client/client.go @@ -83,7 +83,11 @@ func (c *GRPCClient) Close() error { func (c *GRPCClient) Receive(ctx context.Context, interval time.Duration, msgHandler func(msg *proto.FlowEventAck) error) error { backOff := defaultBackoff(ctx, interval) operation := func() error { - return c.establishStreamAndReceive(ctx, msgHandler) + err := c.establishStreamAndReceive(ctx, msgHandler) + if err != nil { + log.Errorf("receive failed: %v", err) + } + return err } if err := backoff.Retry(operation, backOff); err != nil { @@ -126,6 +130,11 @@ func (c *GRPCClient) receive(stream proto.FlowService_EventsClient, msgHandler f return fmt.Errorf("receive from stream: %w", err) } + if msg.IsInitiator { + log.Tracef("received initiator message from flow receiver") + continue + } + if err := msgHandler(msg); err != nil { return fmt.Errorf("handle message: %w", err) } diff --git a/flow/proto/flow.pb.go b/flow/proto/flow.pb.go index 8ad0708e5..04e6e3792 100644 --- a/flow/proto/flow.pb.go +++ b/flow/proto/flow.pb.go @@ -212,7 +212,8 @@ type FlowEventAck struct { unknownFields protoimpl.UnknownFields // Unique client event identifier that has been ack'ed - EventId []byte `protobuf:"bytes,1,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"` + EventId []byte `protobuf:"bytes,1,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"` + IsInitiator bool `protobuf:"varint,2,opt,name=isInitiator,proto3" json:"isInitiator,omitempty"` } func (x *FlowEventAck) Reset() { @@ -254,6 +255,13 @@ func (x *FlowEventAck) GetEventId() []byte { return nil } +func (x *FlowEventAck) GetIsInitiator() bool { + if x != nil { + return x.IsInitiator + } + return false +} + type FlowFields struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -584,66 +592,68 @@ var file_flow_proto_rawDesc = []byte{ 0x77, 0x2e, 0x46, 0x6c, 0x6f, 0x77, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x52, 0x0a, 0x66, 0x6c, 0x6f, 0x77, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, - 0x73, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x29, 0x0a, 0x0c, 0x46, 0x6c, + 0x73, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x4b, 0x0a, 0x0c, 0x46, 0x6c, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x9c, 0x04, 0x0a, 0x0a, 0x46, 0x6c, 0x6f, 0x77, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x1e, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x66, 0x6c, - 0x6f, 0x77, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, - 0x07, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x72, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x66, 0x6c, 0x6f, 0x77, - 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x70, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x70, 0x12, 0x17, - 0x0a, 0x07, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x06, 0x64, 0x65, 0x73, 0x74, 0x49, 0x70, 0x12, 0x2d, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x5f, - 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x66, 0x6c, 0x6f, - 0x77, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x08, 0x70, 0x6f, - 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x0a, 0x09, 0x69, 0x63, 0x6d, 0x70, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x66, 0x6c, 0x6f, 0x77, - 0x2e, 0x49, 0x43, 0x4d, 0x50, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x08, 0x69, 0x63, 0x6d, - 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, - 0x65, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x72, 0x78, 0x50, 0x61, 0x63, - 0x6b, 0x65, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, - 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, - 0x65, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, - 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x72, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x19, - 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x74, 0x5f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0e, 0x64, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, - 0x64, 0x42, 0x11, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, - 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x44, - 0x0a, 0x08, 0x49, 0x43, 0x4d, 0x50, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x63, - 0x6d, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x69, - 0x63, 0x6d, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x63, 0x6d, 0x70, 0x5f, - 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x69, 0x63, 0x6d, 0x70, - 0x43, 0x6f, 0x64, 0x65, 0x2a, 0x45, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0e, - 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x01, 0x12, 0x0c, - 0x0a, 0x08, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x3b, 0x0a, 0x09, 0x44, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x49, 0x52, 0x45, - 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, - 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, - 0x45, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x02, 0x32, 0x42, 0x0a, 0x0b, 0x46, 0x6c, 0x6f, 0x77, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x12, 0x0f, 0x2e, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x46, 0x6c, 0x6f, 0x77, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x1a, 0x12, 0x2e, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x46, 0x6c, 0x6f, 0x77, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x41, 0x63, 0x6b, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, 0x06, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x9c, 0x04, 0x0a, 0x0a, 0x46, 0x6c, 0x6f, 0x77, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, + 0x1e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, + 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x17, 0x0a, 0x07, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x66, 0x6c, + 0x6f, 0x77, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x70, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x70, + 0x12, 0x17, 0x0a, 0x07, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x06, 0x64, 0x65, 0x73, 0x74, 0x49, 0x70, 0x12, 0x2d, 0x0a, 0x09, 0x70, 0x6f, 0x72, + 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x66, + 0x6c, 0x6f, 0x77, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x08, + 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x0a, 0x09, 0x69, 0x63, 0x6d, 0x70, + 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x66, 0x6c, + 0x6f, 0x77, 0x2e, 0x49, 0x43, 0x4d, 0x50, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x08, 0x69, + 0x63, 0x6d, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x78, 0x5f, 0x70, 0x61, + 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x72, 0x78, 0x50, + 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, + 0x6b, 0x65, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x78, 0x50, 0x61, + 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x72, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x65, 0x73, + 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x64, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x49, 0x64, 0x42, 0x11, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, + 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, + 0x22, 0x44, 0x0a, 0x08, 0x49, 0x43, 0x4d, 0x50, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, + 0x69, 0x63, 0x6d, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x08, 0x69, 0x63, 0x6d, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x63, 0x6d, + 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x69, 0x63, + 0x6d, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x2a, 0x45, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, + 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, + 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x01, + 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x0d, + 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x3b, 0x0a, + 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x49, + 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, + 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x0a, + 0x0a, 0x06, 0x45, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x02, 0x32, 0x42, 0x0a, 0x0b, 0x46, 0x6c, + 0x6f, 0x77, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x12, 0x0f, 0x2e, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x46, 0x6c, 0x6f, 0x77, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x12, 0x2e, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x46, 0x6c, 0x6f, 0x77, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x6b, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, + 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/flow/proto/flow.proto b/flow/proto/flow.proto index 95003060d..ff5c50282 100644 --- a/flow/proto/flow.proto +++ b/flow/proto/flow.proto @@ -29,6 +29,7 @@ message FlowEvent { message FlowEventAck { // Unique client event identifier that has been ack'ed bytes event_id = 1; + bool isInitiator = 2; } message FlowFields { From 051a5a4adcdc5a1d43afd876a7891648ae55a709 Mon Sep 17 00:00:00 2001 From: Renat Galiev Date: Sun, 23 Mar 2025 05:14:42 +0700 Subject: [PATCH 4/8] [misc] chore: remove duplicate labels for services.relay in docker-compose.yml.tmpl.traefik (#3502) Signed-off-by: Renat Galiev --- infrastructure_files/docker-compose.yml.tmpl.traefik | 4 ---- 1 file changed, 4 deletions(-) diff --git a/infrastructure_files/docker-compose.yml.tmpl.traefik b/infrastructure_files/docker-compose.yml.tmpl.traefik index b62d15b7c..8cc3df309 100644 --- a/infrastructure_files/docker-compose.yml.tmpl.traefik +++ b/infrastructure_files/docker-compose.yml.tmpl.traefik @@ -71,10 +71,6 @@ services: - NB_AUTH_SECRET=$NETBIRD_RELAY_AUTH_SECRET # ports: # - $NETBIRD_RELAY_PORT:$NETBIRD_RELAY_PORT - labels: - - traefik.enable=true - - traefik.http.routers.netbird-relay.rule=Host(`$NETBIRD_DOMAIN`) && PathPrefix(`/relay`) - - traefik.http.services.netbird-relay.loadbalancer.server.port=33080 logging: driver: "json-file" options: From bd8f0c1ef3d05509506413dc63ee048eaeb32c3c Mon Sep 17 00:00:00 2001 From: Maycon Santos Date: Sun, 23 Mar 2025 13:46:09 +0100 Subject: [PATCH 5/8] [client] add profiling dumps to debug package (#3517) enhances debugging capabilities by adding support for goroutine, mutex, and block profiling while updating state dump tracking and refining test and release settings. - Adds pprof-based profiling for goroutine, mutex, and block profiles in the debug bundle. - Updates state dump functionality by incorporating new status and key fields. - Adjusts test validations and default flag/retention settings. --- .github/workflows/release.yml | 8 ++--- client/cmd/root.go | 2 +- client/internal/peer/conn.go | 4 +-- client/internal/peer/state_dump.go | 20 +++++++++--- client/internal/peer/wg_watcher_test.go | 4 +-- client/server/debug.go | 39 +++++++++++++++++++++++ management/server/store/sql_store.go | 4 +++ management/server/store/sql_store_test.go | 4 +++ 8 files changed, 71 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 919351f18..4806b5676 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -87,25 +87,25 @@ jobs: with: name: release path: dist/ - retention-days: 3 + retention-days: 7 - name: upload linux packages uses: actions/upload-artifact@v4 with: name: linux-packages path: dist/netbird_linux** - retention-days: 3 + retention-days: 7 - name: upload windows packages uses: actions/upload-artifact@v4 with: name: windows-packages path: dist/netbird_windows** - retention-days: 3 + retention-days: 7 - name: upload macos packages uses: actions/upload-artifact@v4 with: name: macos-packages path: dist/netbird_darwin** - retention-days: 3 + retention-days: 7 release_ui: runs-on: ubuntu-latest diff --git a/client/cmd/root.go b/client/cmd/root.go index f088192f1..baf444b99 100644 --- a/client/cmd/root.go +++ b/client/cmd/root.go @@ -180,7 +180,7 @@ func init() { upCmd.PersistentFlags().BoolVar(&serverSSHAllowed, serverSSHAllowedFlag, false, "Allow SSH server on peer. If enabled, the SSH server will be permitted") upCmd.PersistentFlags().BoolVar(&autoConnectDisabled, disableAutoConnectFlag, false, "Disables auto-connect feature. If enabled, then the client won't connect automatically when the service starts.") - debugCmd.PersistentFlags().BoolVarP(&debugSystemInfoFlag, systemInfoFlag, "S", false, "Adds system information to the debug bundle") + debugCmd.PersistentFlags().BoolVarP(&debugSystemInfoFlag, systemInfoFlag, "S", true, "Adds system information to the debug bundle") } // SetupCloseHandler handles SIGTERM signal and exits with success diff --git a/client/internal/peer/conn.go b/client/internal/peer/conn.go index 42f71ed2f..92723d606 100644 --- a/client/internal/peer/conn.go +++ b/client/internal/peer/conn.go @@ -140,7 +140,7 @@ func NewConn(engineCtx context.Context, config ConnConfig, statusRecorder *Statu statusRelay: NewAtomicConnStatus(), statusICE: NewAtomicConnStatus(), semaphore: semaphore, - dumpState: newStateDump(connLog), + dumpState: newStateDump(config.Key, connLog, statusRecorder), } ctrl := isController(config) @@ -258,7 +258,7 @@ func (conn *Conn) Close() { // doesn't block, discards the message if connection wasn't ready func (conn *Conn) OnRemoteAnswer(answer OfferAnswer) bool { conn.dumpState.RemoteAnswer() - conn.log.Infof("OnRemoteAnswer, status ICE: %s, status relay: %s", conn.statusICE, conn.statusRelay) + conn.log.Infof("OnRemoteAnswer, priority: %s, status ICE: %s, status relay: %s", conn.currentConnPriority, conn.statusICE, conn.statusRelay) return conn.handshaker.OnRemoteAnswer(answer) } diff --git a/client/internal/peer/state_dump.go b/client/internal/peer/state_dump.go index 9c148a850..81ca2ebfc 100644 --- a/client/internal/peer/state_dump.go +++ b/client/internal/peer/state_dump.go @@ -9,7 +9,9 @@ import ( ) type stateDump struct { - log *log.Entry + log *log.Entry + status *Status + key string sentOffer int remoteOffer int @@ -24,9 +26,11 @@ type stateDump struct { mu sync.Mutex } -func newStateDump(log *log.Entry) *stateDump { +func newStateDump(key string, log *log.Entry, statusRecorder *Status) *stateDump { return &stateDump{ - log: log, + log: log, + status: statusRecorder, + key: key, } } @@ -66,8 +70,14 @@ func (s *stateDump) dumpState() { s.mu.Lock() defer s.mu.Unlock() - s.log.Infof("Dump stat: SentOffer: %d, RemoteOffer: %d, RemoteAnswer: %d, RemoteCandidate: %d, P2PConnected: %d, SwitchToRelay: %d, WGCheckSuccess: %d, RelayConnected: %d, LocalProxies: %d", - s.sentOffer, s.remoteOffer, s.remoteAnswer, s.remoteCandidate, s.p2pConnected, s.switchToRelay, s.wgCheckSuccess, s.relayConnected, s.localProxies) + status := "unknown" + state, e := s.status.GetPeer(s.key) + if e == nil { + status = state.ConnStatus.String() + } + + s.log.Infof("Dump stat: Status: %s, SentOffer: %d, RemoteOffer: %d, RemoteAnswer: %d, RemoteCandidate: %d, P2PConnected: %d, SwitchToRelay: %d, WGCheckSuccess: %d, RelayConnected: %d, LocalProxies: %d", + status, s.sentOffer, s.remoteOffer, s.remoteAnswer, s.remoteCandidate, s.p2pConnected, s.switchToRelay, s.wgCheckSuccess, s.relayConnected, s.localProxies) } func (s *stateDump) RemoteAnswer() { diff --git a/client/internal/peer/wg_watcher_test.go b/client/internal/peer/wg_watcher_test.go index 473485941..dfd11e74f 100644 --- a/client/internal/peer/wg_watcher_test.go +++ b/client/internal/peer/wg_watcher_test.go @@ -43,7 +43,7 @@ func TestWGWatcher_EnableWgWatcher(t *testing.T) { mlog := log.WithField("peer", "tet") mocWgIface := &MocWgIface{} - watcher := NewWGWatcher(mlog, mocWgIface, "", newStateDump(mlog)) + watcher := NewWGWatcher(mlog, mocWgIface, "", newStateDump("peer", mlog, &Status{})) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -72,7 +72,7 @@ func TestWGWatcher_ReEnable(t *testing.T) { mlog := log.WithField("peer", "tet") mocWgIface := &MocWgIface{} - watcher := NewWGWatcher(mlog, mocWgIface, "", newStateDump(mlog)) + watcher := NewWGWatcher(mlog, mocWgIface, "", newStateDump("peer", mlog, &Status{})) ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/client/server/debug.go b/client/server/debug.go index 39a67c92c..bdb1f7543 100644 --- a/client/server/debug.go +++ b/client/server/debug.go @@ -17,6 +17,7 @@ import ( "os" "path/filepath" "runtime" + "runtime/pprof" "sort" "strings" "time" @@ -46,6 +47,9 @@ nftables.txt: Anonymized nftables rules with packet counters, if --system-info f config.txt: Anonymized configuration information of the NetBird client. network_map.json: Anonymized network map containing peer configurations, routes, DNS settings, and firewall rules. state.json: Anonymized client state dump containing netbird states. +mutex.prof: Mutex profiling information. +goroutine.prof: Goroutine profiling information. +block.prof: Block profiling information. Anonymization Process @@ -88,6 +92,14 @@ The state file follows the same anonymization rules as other files: - Domain names are consistently anonymized - Technical identifiers and non-sensitive data remain unchanged +Mutex, Goroutines, and Block Profiling Files +The goroutine, block, and mutex profiling files contains process information that might help the NetBird team diagnose performance issues. The information in these files don't contain personal data. +You can check each using the following go command: + +go tool pprof -http=:8088 mutex.prof + +This will open a web browser tab with the profiling information. + Routes For anonymized routes, the IP addresses are replaced as described above. The prefix length remains unchanged. Note that for prefixes, the anonymized IP might not be a network address, but the prefix length is still correct. @@ -188,6 +200,10 @@ func (s *Server) createArchive(bundlePath *os.File, req *proto.DebugBundleReques s.addSystemInfo(req, anonymizer, archive) } + if err := s.addProf(req, anonymizer, archive); err != nil { + log.Errorf("Failed to add goroutines rules to debug bundle: %v", err) + } + if err := s.addNetworkMap(req, anonymizer, archive); err != nil { return fmt.Errorf("add network map: %w", err) } @@ -310,6 +326,29 @@ func (s *Server) addCommonConfigFields(configContent *strings.Builder) { configContent.WriteString(fmt.Sprintf("BlockLANAccess: %v\n", s.config.BlockLANAccess)) } +func (s *Server) addProf(req *proto.DebugBundleRequest, anonymizer *anonymize.Anonymizer, archive *zip.Writer) error { + runtime.SetBlockProfileRate(1) + _ = runtime.SetMutexProfileFraction(1) + defer runtime.SetBlockProfileRate(0) + defer runtime.SetMutexProfileFraction(0) + + time.Sleep(5 * time.Second) + + for _, profile := range []string{"goroutine", "block", "mutex"} { + var buff []byte + myBuff := bytes.NewBuffer(buff) + err := pprof.Lookup(profile).WriteTo(myBuff, 0) + if err != nil { + return fmt.Errorf("write %s profile: %w", profile, err) + } + + if err := addFileToZip(archive, myBuff, profile+".prof"); err != nil { + return fmt.Errorf("add %s file to zip: %w", profile, err) + } + } + return nil +} + func (s *Server) addRoutes(req *proto.DebugBundleRequest, anonymizer *anonymize.Anonymizer, archive *zip.Writer) error { routes, err := systemops.GetRoutesFromTable() if err != nil { diff --git a/management/server/store/sql_store.go b/management/server/store/sql_store.go index cf6665665..01823c797 100644 --- a/management/server/store/sql_store.go +++ b/management/server/store/sql_store.go @@ -220,6 +220,10 @@ func generateAccountSQLTypes(account *types.Account) { account.SetupKeysG = append(account.SetupKeysG, *key) } + if len(account.SetupKeys) != len(account.SetupKeysG) { + log.Warnf("SetupKeysG length mismatch for account %s", account.Id) + } + for id, peer := range account.Peers { peer.ID = id account.PeersG = append(account.PeersG, *peer) diff --git a/management/server/store/sql_store_test.go b/management/server/store/sql_store_test.go index 54649c5c1..0d67ca719 100644 --- a/management/server/store/sql_store_test.go +++ b/management/server/store/sql_store_test.go @@ -148,6 +148,10 @@ func runLargeTest(t *testing.T, store Store) { account.NameServerGroups[nameserver.ID] = nameserver setupKey, _ := types.GenerateDefaultSetupKey() + _, exists := account.SetupKeys[setupKey.Key] + if exists { + t.Errorf("setup key already exists") + } account.SetupKeys[setupKey.Key] = setupKey } From 9cbcf7531fd4c3e2a4238e7b700e8719bcec2b63 Mon Sep 17 00:00:00 2001 From: Maycon Santos Date: Mon, 24 Mar 2025 00:56:51 +0100 Subject: [PATCH 6/8] [management] Fix invalid port range sync (#3571) We should not send port range when a port is set or when protocol is all or icmp --- management/server/policy.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/management/server/policy.go b/management/server/policy.go index bbc85f6ae..d222bba8a 100644 --- a/management/server/policy.go +++ b/management/server/policy.go @@ -255,15 +255,24 @@ func toProtocolFirewallRules(rules []*types.FirewallRule) []*proto.FirewallRule for i := range rules { rule := rules[i] - result[i] = &proto.FirewallRule{ + fwRule := &proto.FirewallRule{ PolicyID: []byte(rule.PolicyID), PeerIP: rule.PeerIP, Direction: getProtoDirection(rule.Direction), Action: getProtoAction(rule.Action), Protocol: getProtoProtocol(rule.Protocol), Port: rule.Port, - PortInfo: rule.PortRange.ToProto(), } + + if shouldUsePortRange(fwRule) { + fwRule.PortInfo = rule.PortRange.ToProto() + } + + result[i] = fwRule } return result } + +func shouldUsePortRange(rule *proto.FirewallRule) bool { + return rule.Port == "" && (rule.Protocol == proto.RuleProtocol_UDP || rule.Protocol == proto.RuleProtocol_TCP) +} From 80d1aa451634a5e15658a860b7dbce138f87e526 Mon Sep 17 00:00:00 2001 From: Pascal Fischer Date: Mon, 24 Mar 2025 17:55:21 +0100 Subject: [PATCH 7/8] export management config path --- management/cmd/management.go | 8 ++++---- management/cmd/root.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/management/cmd/management.go b/management/cmd/management.go index 1b2216932..42919df9e 100644 --- a/management/cmd/management.go +++ b/management/cmd/management.go @@ -101,9 +101,9 @@ var ( // detect whether user specified a port userPort := cmd.Flag("port").Changed - config, err = loadMgmtConfig(ctx, mgmtConfig) + config, err = loadMgmtConfig(ctx, MgmtConfig) if err != nil { - return fmt.Errorf("failed reading provided config file: %s: %v", mgmtConfig, err) + return fmt.Errorf("failed reading provided config file: %s: %v", MgmtConfig, err) } if cmd.Flag(idpSignKeyRefreshEnabledFlagName).Changed { @@ -183,7 +183,7 @@ var ( if config.DataStoreEncryptionKey != key { log.WithContext(ctx).Infof("update config with activity store key") config.DataStoreEncryptionKey = key - err := updateMgmtConfig(ctx, mgmtConfig, config) + err := updateMgmtConfig(ctx, MgmtConfig, config) if err != nil { return fmt.Errorf("failed to write out store encryption key: %s", err) } @@ -636,7 +636,7 @@ func handleRebrand(cmd *cobra.Command) error { } } } - if mgmtConfig == defaultMgmtConfig { + if MgmtConfig == defaultMgmtConfig { if migrateToNetbird(oldDefaultMgmtConfig, defaultMgmtConfig) { cmd.Printf("will copy Config dir %s and its content to %s\n", oldDefaultMgmtConfigDir, defaultMgmtConfigDir) err = cpDir(oldDefaultMgmtConfigDir, defaultMgmtConfigDir) diff --git a/management/cmd/root.go b/management/cmd/root.go index 86155a956..6d05c9563 100644 --- a/management/cmd/root.go +++ b/management/cmd/root.go @@ -19,7 +19,7 @@ const ( var ( dnsDomain string mgmtDataDir string - mgmtConfig string + MgmtConfig string logLevel string logFile string disableMetrics bool @@ -56,7 +56,7 @@ func init() { mgmtCmd.Flags().IntVar(&mgmtPort, "port", 80, "server port to listen on (defaults to 443 if TLS is enabled, 80 otherwise") mgmtCmd.Flags().IntVar(&mgmtMetricsPort, "metrics-port", 9090, "metrics endpoint http port. Metrics are accessible under host:metrics-port/metrics") mgmtCmd.Flags().StringVar(&mgmtDataDir, "datadir", defaultMgmtDataDir, "server data directory location") - mgmtCmd.Flags().StringVar(&mgmtConfig, "config", defaultMgmtConfig, "Netbird config file location. Config params specified via command line (e.g. datadir) have a precedence over configuration from this file") + mgmtCmd.Flags().StringVar(&MgmtConfig, "config", defaultMgmtConfig, "Netbird config file location. Config params specified via command line (e.g. datadir) have a precedence over configuration from this file") mgmtCmd.Flags().StringVar(&mgmtLetsencryptDomain, "letsencrypt-domain", "", "a domain to issue Let's Encrypt certificate for. Enables TLS using Let's Encrypt. Will fetch and renew certificate, and run the server with TLS") mgmtCmd.Flags().StringVar(&mgmtSingleAccModeDomain, "single-account-mode-domain", defaultSingleAccModeDomain, "Enables single account mode. This means that all the users will be under the same account grouped by the specified domain. If the installation has more than one account, the property is ineffective. Enabled by default with the default domain "+defaultSingleAccModeDomain) mgmtCmd.Flags().BoolVar(&disableSingleAccMode, "disable-single-account-mode", false, "If set to true, disables single account mode. The --single-account-mode-domain property will be ignored and every new user will have a separate NetBird account.") From dc8aac6549d0d48a8f9c3a5bc8183a147bd86e61 Mon Sep 17 00:00:00 2001 From: Maycon Santos Date: Mon, 24 Mar 2025 23:05:11 +0100 Subject: [PATCH 8/8] move relay config and management config path to types this helps avoid circular import cycle through all the code --- client/internal/engine_test.go | 2 +- management/cmd/management.go | 10 ++++++---- management/cmd/root.go | 4 ++-- management/server/config.go | 9 ++------- management/server/token_mgr.go | 5 +++-- management/server/token_mgr_test.go | 6 +++--- management/server/types/config.go | 13 +++++++++++++ 7 files changed, 30 insertions(+), 19 deletions(-) create mode 100644 management/server/types/config.go diff --git a/client/internal/engine_test.go b/client/internal/engine_test.go index 56fef43e1..ea27da517 100644 --- a/client/internal/engine_test.go +++ b/client/internal/engine_test.go @@ -1403,7 +1403,7 @@ func startManagement(t *testing.T, dataDir, testFile string) (*grpc.Server, stri config := &server.Config{ Stuns: []*server.Host{}, TURNConfig: &server.TURNConfig{}, - Relay: &server.Relay{ + Relay: &types.Relay{ Addresses: []string{"127.0.0.1:1234"}, CredentialsTTL: util.Duration{Duration: time.Hour}, Secret: "222222222222222222", diff --git a/management/cmd/management.go b/management/cmd/management.go index 42919df9e..fa2de73c0 100644 --- a/management/cmd/management.go +++ b/management/cmd/management.go @@ -34,7 +34,9 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip" "github.com/netbirdio/management-integrations/integrations" + "github.com/netbirdio/netbird/management/server/peers" + "github.com/netbirdio/netbird/management/server/types" "github.com/netbirdio/netbird/encryption" "github.com/netbirdio/netbird/formatter/hook" @@ -101,9 +103,9 @@ var ( // detect whether user specified a port userPort := cmd.Flag("port").Changed - config, err = loadMgmtConfig(ctx, MgmtConfig) + config, err = loadMgmtConfig(ctx, types.MgmtConfigPath) if err != nil { - return fmt.Errorf("failed reading provided config file: %s: %v", MgmtConfig, err) + return fmt.Errorf("failed reading provided config file: %s: %v", types.MgmtConfigPath, err) } if cmd.Flag(idpSignKeyRefreshEnabledFlagName).Changed { @@ -183,7 +185,7 @@ var ( if config.DataStoreEncryptionKey != key { log.WithContext(ctx).Infof("update config with activity store key") config.DataStoreEncryptionKey = key - err := updateMgmtConfig(ctx, MgmtConfig, config) + err := updateMgmtConfig(ctx, types.MgmtConfigPath, config) if err != nil { return fmt.Errorf("failed to write out store encryption key: %s", err) } @@ -636,7 +638,7 @@ func handleRebrand(cmd *cobra.Command) error { } } } - if MgmtConfig == defaultMgmtConfig { + if types.MgmtConfigPath == defaultMgmtConfig { if migrateToNetbird(oldDefaultMgmtConfig, defaultMgmtConfig) { cmd.Printf("will copy Config dir %s and its content to %s\n", oldDefaultMgmtConfigDir, defaultMgmtConfigDir) err = cpDir(oldDefaultMgmtConfigDir, defaultMgmtConfigDir) diff --git a/management/cmd/root.go b/management/cmd/root.go index 6d05c9563..31271a8c6 100644 --- a/management/cmd/root.go +++ b/management/cmd/root.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/cobra" + "github.com/netbirdio/netbird/management/server/types" "github.com/netbirdio/netbird/version" ) @@ -19,7 +20,6 @@ const ( var ( dnsDomain string mgmtDataDir string - MgmtConfig string logLevel string logFile string disableMetrics bool @@ -56,7 +56,7 @@ func init() { mgmtCmd.Flags().IntVar(&mgmtPort, "port", 80, "server port to listen on (defaults to 443 if TLS is enabled, 80 otherwise") mgmtCmd.Flags().IntVar(&mgmtMetricsPort, "metrics-port", 9090, "metrics endpoint http port. Metrics are accessible under host:metrics-port/metrics") mgmtCmd.Flags().StringVar(&mgmtDataDir, "datadir", defaultMgmtDataDir, "server data directory location") - mgmtCmd.Flags().StringVar(&MgmtConfig, "config", defaultMgmtConfig, "Netbird config file location. Config params specified via command line (e.g. datadir) have a precedence over configuration from this file") + mgmtCmd.Flags().StringVar(&types.MgmtConfigPath, "config", defaultMgmtConfig, "Netbird config file location. Config params specified via command line (e.g. datadir) have a precedence over configuration from this file") mgmtCmd.Flags().StringVar(&mgmtLetsencryptDomain, "letsencrypt-domain", "", "a domain to issue Let's Encrypt certificate for. Enables TLS using Let's Encrypt. Will fetch and renew certificate, and run the server with TLS") mgmtCmd.Flags().StringVar(&mgmtSingleAccModeDomain, "single-account-mode-domain", defaultSingleAccModeDomain, "Enables single account mode. This means that all the users will be under the same account grouped by the specified domain. If the installation has more than one account, the property is ineffective. Enabled by default with the default domain "+defaultSingleAccModeDomain) mgmtCmd.Flags().BoolVar(&disableSingleAccMode, "disable-single-account-mode", false, "If set to true, disables single account mode. The --single-account-mode-domain property will be ignored and every new user will have a separate NetBird account.") diff --git a/management/server/config.go b/management/server/config.go index ce2ff4d16..3dfd1316a 100644 --- a/management/server/config.go +++ b/management/server/config.go @@ -5,6 +5,7 @@ import ( "github.com/netbirdio/netbird/management/server/idp" "github.com/netbirdio/netbird/management/server/store" + "github.com/netbirdio/netbird/management/server/types" "github.com/netbirdio/netbird/util" ) @@ -34,7 +35,7 @@ const ( type Config struct { Stuns []*Host TURNConfig *TURNConfig - Relay *Relay + Relay *types.Relay Signal *Host Datadir string @@ -76,12 +77,6 @@ type TURNConfig struct { Turns []*Host } -type Relay struct { - Addresses []string - CredentialsTTL util.Duration - Secret string -} - // HttpServerConfig is a config of the HTTP Management service server type HttpServerConfig struct { LetsEncryptDomain string diff --git a/management/server/token_mgr.go b/management/server/token_mgr.go index f8238aa16..59441daa7 100644 --- a/management/server/token_mgr.go +++ b/management/server/token_mgr.go @@ -13,6 +13,7 @@ import ( "github.com/netbirdio/netbird/management/proto" "github.com/netbirdio/netbird/management/server/settings" + "github.com/netbirdio/netbird/management/server/types" auth "github.com/netbirdio/netbird/relay/auth/hmac" authv2 "github.com/netbirdio/netbird/relay/auth/hmac/v2" @@ -33,7 +34,7 @@ type SecretsManager interface { type TimeBasedAuthSecretsManager struct { mux sync.Mutex turnCfg *TURNConfig - relayCfg *Relay + relayCfg *types.Relay turnHmacToken *auth.TimedHMAC relayHmacToken *authv2.Generator updateManager *PeersUpdateManager @@ -44,7 +45,7 @@ type TimeBasedAuthSecretsManager struct { type Token auth.Token -func NewTimeBasedAuthSecretsManager(updateManager *PeersUpdateManager, turnCfg *TURNConfig, relayCfg *Relay, settingsManager settings.Manager) *TimeBasedAuthSecretsManager { +func NewTimeBasedAuthSecretsManager(updateManager *PeersUpdateManager, turnCfg *TURNConfig, relayCfg *types.Relay, settingsManager settings.Manager) *TimeBasedAuthSecretsManager { mgr := &TimeBasedAuthSecretsManager{ updateManager: updateManager, turnCfg: turnCfg, diff --git a/management/server/token_mgr_test.go b/management/server/token_mgr_test.go index c07e40418..d505e6910 100644 --- a/management/server/token_mgr_test.go +++ b/management/server/token_mgr_test.go @@ -31,7 +31,7 @@ func TestTimeBasedAuthSecretsManager_GenerateCredentials(t *testing.T) { secret := "some_secret" peersManager := NewPeersUpdateManager(nil) - rc := &Relay{ + rc := &types.Relay{ Addresses: []string{"localhost:0"}, CredentialsTTL: ttl, Secret: secret, @@ -81,7 +81,7 @@ func TestTimeBasedAuthSecretsManager_SetupRefresh(t *testing.T) { peer := "some_peer" updateChannel := peersManager.CreateChannel(context.Background(), peer) - rc := &Relay{ + rc := &types.Relay{ Addresses: []string{"localhost:0"}, CredentialsTTL: ttl, Secret: secret, @@ -184,7 +184,7 @@ func TestTimeBasedAuthSecretsManager_CancelRefresh(t *testing.T) { peersManager := NewPeersUpdateManager(nil) peer := "some_peer" - rc := &Relay{ + rc := &types.Relay{ Addresses: []string{"localhost:0"}, CredentialsTTL: ttl, Secret: secret, diff --git a/management/server/types/config.go b/management/server/types/config.go new file mode 100644 index 000000000..02143051a --- /dev/null +++ b/management/server/types/config.go @@ -0,0 +1,13 @@ +package types + +import "github.com/netbirdio/netbird/util" + +// MgmtConfigPath Config path of the Management service +var MgmtConfigPath string + +// Relay configuration type +type Relay struct { + Addresses []string + CredentialsTTL util.Duration + Secret string +}