Add embedded VNC server with JWT auth, DXGI capture, and dashboard integration

This commit is contained in:
Viktor Liu
2026-04-14 12:31:00 +02:00
parent 3098f48b25
commit b754df1171
85 changed files with 10457 additions and 2011 deletions

View File

@@ -184,6 +184,25 @@ func (h *handler) updateAccountRequestSettings(req api.PutApiAccountsAccountIdJS
PeerExposeGroups: req.Settings.PeerExposeGroups,
}
if req.Settings.RecordingEnabled != nil {
returnSettings.RecordingEnabled = *req.Settings.RecordingEnabled
}
if req.Settings.RecordingGroups != nil {
returnSettings.RecordingGroups = *req.Settings.RecordingGroups
}
if req.Settings.RecordingMaxSessions != nil {
returnSettings.RecordingMaxSessions = int32(*req.Settings.RecordingMaxSessions)
}
if req.Settings.RecordingMaxTotalSizeMb != nil {
returnSettings.RecordingMaxTotalSizeMB = int64(*req.Settings.RecordingMaxTotalSizeMb)
}
if req.Settings.RecordingInputEnabled != nil {
returnSettings.RecordingInputEnabled = req.Settings.RecordingInputEnabled
}
if req.Settings.RecordingEncryptionKey != nil {
returnSettings.RecordingEncryptionKey = *req.Settings.RecordingEncryptionKey
}
if req.Settings.Extra != nil {
returnSettings.Extra = &types.ExtraSettings{
PeerApprovalEnabled: req.Settings.Extra.PeerApprovalEnabled,
@@ -348,6 +367,12 @@ func toAccountResponse(accountID string, settings *types.Settings, meta *types.A
RoutingPeerDnsResolutionEnabled: &settings.RoutingPeerDNSResolutionEnabled,
PeerExposeEnabled: settings.PeerExposeEnabled,
PeerExposeGroups: settings.PeerExposeGroups,
RecordingEnabled: &settings.RecordingEnabled,
RecordingGroups: &settings.RecordingGroups,
RecordingMaxSessions: toIntPtr(settings.RecordingMaxSessions),
RecordingMaxTotalSizeMb: &settings.RecordingMaxTotalSizeMB,
RecordingInputEnabled: settings.RecordingInputEnabled,
RecordingEncryptionKey: &settings.RecordingEncryptionKey,
LazyConnectionEnabled: &settings.LazyConnectionEnabled,
DnsDomain: &settings.DNSDomain,
AutoUpdateVersion: &settings.AutoUpdateVersion,
@@ -386,3 +411,8 @@ func toAccountResponse(accountID string, settings *types.Settings, meta *types.A
Onboarding: apiOnboarding,
}
}
func toIntPtr(v int32) *int {
i := int(v)
return &i
}

View File

@@ -487,7 +487,7 @@ func (h *Handler) CreateTemporaryAccess(w http.ResponseWriter, r *http.Request)
PortRanges: []types.RulePortRange{portRange},
}},
}
if protocol == types.PolicyRuleProtocolNetbirdSSH {
if protocol == types.PolicyRuleProtocolNetbirdSSH || protocol == types.PolicyRuleProtocolNetbirdVNC {
policy.Rules[0].AuthorizedUser = userAuth.UserId
}
@@ -581,6 +581,8 @@ func toSinglePeerResponse(peer *nbpeer.Peer, groupsInfo []api.GroupMinimum, dnsD
RosenpassEnabled: &peer.Meta.Flags.RosenpassEnabled,
RosenpassPermissive: &peer.Meta.Flags.RosenpassPermissive,
ServerSshAllowed: &peer.Meta.Flags.ServerSSHAllowed,
ServerVncAllowed: &peer.Meta.Flags.ServerVNCAllowed,
DisableVncAuth: &peer.Meta.Flags.DisableVNCAuth,
},
}
@@ -635,6 +637,8 @@ func toPeerListItemResponse(peer *nbpeer.Peer, groupsInfo []api.GroupMinimum, dn
RosenpassEnabled: &peer.Meta.Flags.RosenpassEnabled,
RosenpassPermissive: &peer.Meta.Flags.RosenpassPermissive,
ServerSshAllowed: &peer.Meta.Flags.ServerSSHAllowed,
ServerVncAllowed: &peer.Meta.Flags.ServerVNCAllowed,
DisableVncAuth: &peer.Meta.Flags.DisableVNCAuth,
},
}
}

View File

@@ -223,6 +223,8 @@ func (h *handler) savePolicy(w http.ResponseWriter, r *http.Request, accountID s
pr.Protocol = types.PolicyRuleProtocolICMP
case api.PolicyRuleUpdateProtocolNetbirdSsh:
pr.Protocol = types.PolicyRuleProtocolNetbirdSSH
case api.PolicyRuleUpdateProtocolNetbirdVnc:
pr.Protocol = types.PolicyRuleProtocolNetbirdVNC
default:
util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "unknown protocol type: %v", rule.Protocol), w)
return
@@ -256,7 +258,8 @@ func (h *handler) savePolicy(w http.ResponseWriter, r *http.Request, accountID s
}
}
if pr.Protocol == types.PolicyRuleProtocolNetbirdSSH && rule.AuthorizedGroups != nil && len(*rule.AuthorizedGroups) != 0 {
isNetBirdService := pr.Protocol == types.PolicyRuleProtocolNetbirdSSH || pr.Protocol == types.PolicyRuleProtocolNetbirdVNC
if isNetBirdService && rule.AuthorizedGroups != nil && len(*rule.AuthorizedGroups) != 0 {
for _, sourceGroupID := range pr.Sources {
_, ok := (*rule.AuthorizedGroups)[sourceGroupID]
if !ok {