Merge branch 'main' into feature/remote-debug-clean

# Conflicts:
#	client/cmd/testutil_test.go
#	client/internal/engine_test.go
#	client/server/server.go
#	client/server/server_test.go
#	client/status/status.go
#	go.mod
#	go.sum
#	management/internals/server/boot.go
#	management/internals/server/modules.go
#	management/internals/shared/grpc/server.go
#	management/server/account.go
#	management/server/account/manager.go
#	management/server/account_test.go
#	management/server/dns_test.go
#	management/server/http/testing/testing_tools/channel/channel.go
#	management/server/management_proto_test.go
#	management/server/management_test.go
#	management/server/nameserver_test.go
#	management/server/peer_test.go
#	management/server/route_test.go
#	shared/management/client/client_test.go
#	shared/management/proto/management.pb.go
This commit is contained in:
Zoltán Papp
2025-11-18 18:30:48 +01:00
240 changed files with 22880 additions and 5597 deletions
+88 -2
View File
@@ -85,6 +85,18 @@ type NsServerGroupStateOutput struct {
Error string `json:"error" yaml:"error"`
}
type SSHSessionOutput struct {
Username string `json:"username" yaml:"username"`
RemoteAddress string `json:"remoteAddress" yaml:"remoteAddress"`
Command string `json:"command" yaml:"command"`
JWTUsername string `json:"jwtUsername,omitempty" yaml:"jwtUsername,omitempty"`
}
type SSHServerStateOutput struct {
Enabled bool `json:"enabled" yaml:"enabled"`
Sessions []SSHSessionOutput `json:"sessions" yaml:"sessions"`
}
type OutputOverview struct {
Peers PeersStateOutput `json:"peers" yaml:"peers"`
CliVersion string `json:"cliVersion" yaml:"cliVersion"`
@@ -104,6 +116,7 @@ type OutputOverview struct {
Events []SystemEventOutput `json:"events" yaml:"events"`
LazyConnectionEnabled bool `json:"lazyConnectionEnabled" yaml:"lazyConnectionEnabled"`
ProfileName string `json:"profileName" yaml:"profileName"`
SSHServerState SSHServerStateOutput `json:"sshServer" yaml:"sshServer"`
}
func ConvertToStatusOutputOverview(pbFullStatus *proto.FullStatus, anon bool, daemonVersion string, statusFilter string, prefixNamesFilter []string, prefixNamesFilterMap map[string]struct{}, ipsFilter map[string]struct{}, connectionTypeFilter string, profName string) OutputOverview {
@@ -122,6 +135,7 @@ func ConvertToStatusOutputOverview(pbFullStatus *proto.FullStatus, anon bool, da
}
relayOverview := mapRelays(pbFullStatus.GetRelays())
sshServerOverview := mapSSHServer(pbFullStatus.GetSshServerState())
peersOverview := mapPeers(pbFullStatus.GetPeers(), statusFilter, prefixNamesFilter, prefixNamesFilterMap, ipsFilter, connectionTypeFilter)
overview := OutputOverview{
@@ -143,6 +157,7 @@ func ConvertToStatusOutputOverview(pbFullStatus *proto.FullStatus, anon bool, da
Events: mapEvents(pbFullStatus.GetEvents()),
LazyConnectionEnabled: pbFullStatus.GetLazyConnectionEnabled(),
ProfileName: profName,
SSHServerState: sshServerOverview,
}
if anon {
@@ -192,6 +207,30 @@ func mapNSGroups(servers []*proto.NSGroupState) []NsServerGroupStateOutput {
return mappedNSGroups
}
func mapSSHServer(sshServerState *proto.SSHServerState) SSHServerStateOutput {
if sshServerState == nil {
return SSHServerStateOutput{
Enabled: false,
Sessions: []SSHSessionOutput{},
}
}
sessions := make([]SSHSessionOutput, 0, len(sshServerState.GetSessions()))
for _, session := range sshServerState.GetSessions() {
sessions = append(sessions, SSHSessionOutput{
Username: session.GetUsername(),
RemoteAddress: session.GetRemoteAddress(),
Command: session.GetCommand(),
JWTUsername: session.GetJwtUsername(),
})
}
return SSHServerStateOutput{
Enabled: sshServerState.GetEnabled(),
Sessions: sessions,
}
}
func mapPeers(
peers []*proto.PeerState,
statusFilter string,
@@ -302,7 +341,7 @@ func ParseToYAML(overview OutputOverview) (string, error) {
return string(yamlBytes), nil
}
func ParseGeneralSummary(overview OutputOverview, showURL bool, showRelays bool, showNameServers bool) string {
func ParseGeneralSummary(overview OutputOverview, showURL bool, showRelays bool, showNameServers bool, showSSHSessions bool) string {
var managementConnString string
if overview.ManagementState.Connected {
managementConnString = "Connected"
@@ -407,6 +446,41 @@ func ParseGeneralSummary(overview OutputOverview, showURL bool, showRelays bool,
lazyConnectionEnabledStatus = "true"
}
sshServerStatus := "Disabled"
if overview.SSHServerState.Enabled {
sessionCount := len(overview.SSHServerState.Sessions)
if sessionCount > 0 {
sessionWord := "session"
if sessionCount > 1 {
sessionWord = "sessions"
}
sshServerStatus = fmt.Sprintf("Enabled (%d active %s)", sessionCount, sessionWord)
} else {
sshServerStatus = "Enabled"
}
if showSSHSessions && sessionCount > 0 {
for _, session := range overview.SSHServerState.Sessions {
var sessionDisplay string
if session.JWTUsername != "" {
sessionDisplay = fmt.Sprintf("[%s@%s -> %s] %s",
session.JWTUsername,
session.RemoteAddress,
session.Username,
session.Command,
)
} else {
sessionDisplay = fmt.Sprintf("[%s@%s] %s",
session.Username,
session.RemoteAddress,
session.Command,
)
}
sshServerStatus += "\n " + sessionDisplay
}
}
}
peersCountString := fmt.Sprintf("%d/%d Connected", overview.Peers.Connected, overview.Peers.Total)
goos := runtime.GOOS
@@ -430,6 +504,7 @@ func ParseGeneralSummary(overview OutputOverview, showURL bool, showRelays bool,
"Interface type: %s\n"+
"Quantum resistance: %s\n"+
"Lazy connection: %s\n"+
"SSH Server: %s\n"+
"Networks: %s\n"+
"Forwarding rules: %d\n"+
"Peers count: %s\n",
@@ -446,6 +521,7 @@ func ParseGeneralSummary(overview OutputOverview, showURL bool, showRelays bool,
interfaceTypeString,
rosenpassEnabledStatus,
lazyConnectionEnabledStatus,
sshServerStatus,
networks,
overview.NumberOfForwardingRules,
peersCountString,
@@ -456,7 +532,7 @@ func ParseGeneralSummary(overview OutputOverview, showURL bool, showRelays bool,
func ParseToFullDetailSummary(overview OutputOverview) string {
parsedPeersString := parsePeers(overview.Peers, overview.RosenpassEnabled, overview.RosenpassPermissive)
parsedEventsString := parseEvents(overview.Events)
summary := ParseGeneralSummary(overview, true, true, true)
summary := ParseGeneralSummary(overview, true, true, true, true)
return fmt.Sprintf(
"Peers detail:"+
@@ -519,6 +595,7 @@ func ToProtoFullStatus(fullStatus peer.FullStatus) *proto.FullStatus {
RosenpassEnabled: peerState.RosenpassEnabled,
Networks: maps.Keys(peerState.GetRoutes()),
Latency: durationpb.New(peerState.Latency),
SshHostKey: peerState.SSHHostKey,
}
pbFullStatus.Peers = append(pbFullStatus.Peers, pbPeerState)
}
@@ -835,4 +912,13 @@ func anonymizeOverview(a *anonymize.Anonymizer, overview *OutputOverview) {
event.Metadata[k] = a.AnonymizeString(v)
}
}
for i, session := range overview.SSHServerState.Sessions {
if host, port, err := net.SplitHostPort(session.RemoteAddress); err == nil {
overview.SSHServerState.Sessions[i].RemoteAddress = fmt.Sprintf("%s:%s", a.AnonymizeIPString(host), port)
} else {
overview.SSHServerState.Sessions[i].RemoteAddress = a.AnonymizeIPString(session.RemoteAddress)
}
overview.SSHServerState.Sessions[i].Command = a.AnonymizeString(session.Command)
}
}
+15 -2
View File
@@ -231,6 +231,10 @@ var overview = OutputOverview{
Networks: []string{
"10.10.0.0/24",
},
SSHServerState: SSHServerStateOutput{
Enabled: false,
Sessions: []SSHSessionOutput{},
},
}
func TestConversionFromFullStatusToOutputOverview(t *testing.T) {
@@ -385,7 +389,11 @@ func TestParsingToJSON(t *testing.T) {
],
"events": [],
"lazyConnectionEnabled": false,
"profileName":""
"profileName":"",
"sshServer":{
"enabled":false,
"sessions":[]
}
}`
// @formatter:on
@@ -488,6 +496,9 @@ dnsServers:
events: []
lazyConnectionEnabled: false
profileName: ""
sshServer:
enabled: false
sessions: []
`
assert.Equal(t, expectedYAML, yaml)
@@ -554,6 +565,7 @@ NetBird IP: 192.168.178.100/16
Interface type: Kernel
Quantum resistance: false
Lazy connection: false
SSH Server: Disabled
Networks: 10.10.0.0/24
Forwarding rules: 0
Peers count: 2/2 Connected
@@ -563,7 +575,7 @@ Peers count: 2/2 Connected
}
func TestParsingToShortVersion(t *testing.T) {
shortVersion := ParseGeneralSummary(overview, false, false, false)
shortVersion := ParseGeneralSummary(overview, false, false, false, false)
expectedString := fmt.Sprintf("OS: %s/%s", runtime.GOOS, runtime.GOARCH) + `
Daemon version: 0.14.1
@@ -578,6 +590,7 @@ NetBird IP: 192.168.178.100/16
Interface type: Kernel
Quantum resistance: false
Lazy connection: false
SSH Server: Disabled
Networks: 10.10.0.0/24
Forwarding rules: 0
Peers count: 2/2 Connected