Files
BetterDesk/docs/important/betterdesk-enrollment.md
UNITRONIX cef2ab7c8e fix(signal): close shared-NAT RelayResponse gaps and add opt-in initiator
Correlate RelayResponse via pending UUID/initiator store and panel CIDRs;
stop FindByIP ticket misdelivery. Opt-in ALLOW_SHARED_NAT_INITIATOR for
stock multi-device CGNAT without peer identity inheritance.

Refs #399

Thanks: INSOLVE (Honorary); Marco Jakobs (@jacotec); MyNameisStitch (@MyNameisStitch); Redspin (@playerumpknow)
2026-09-03 21:25:50 +02:00

3.4 KiB

BetterDesk Enrollment

  • Signal-mode Managed enrollment must create pending_device_<peerID> in server_config and deny registration until operator approval; Locked mode must deny without creating pending requests.
  • Outbound session initiation (PunchHoleRequest / RequestRelay) requires an authorized initiator (#302 / #327):
    • Authorization sources (first match wins): same Secure TCP session after RegisterPk (tcpSessionPeerID), or a BetterDesk opaque client login token on the punch/relay message, or panel signal-proxy CIDR (Web Remote), or a live registered peer with exact ip:port match (FindByAddr), or PunchHole udp_port uniquely matching a live peer at this public IP (#399 CGNAT hint), or exactly one live peer at the same public IP (safe IP fallback for stock clients that PunchHole on a new TCP port). Multiple live peers at that IP refuse with initiator_ambiguous_same_nat so a pending client behind the same NAT cannot inherit an approved peer's identity — unless ALLOW_SHARED_NAT_INITIATOR / -allow-shared-nat-initiator is enabled (default off), which authorizes synthetic id shared-nat-initiator without inheriting any peer identity.
    • Managed / locked: initiator must also exist as an approved peer in the DB (GetPeer); pending_device_<id> alone is never enough (also rejected if that pending key still exists). Synthetic panel / shared-NAT initiators skip the peer-row check (operator opt-in / panel auth).
    • Panel Web Remote exception: PunchHole/RequestRelay from PANEL_SIGNAL_PROXY_CIDRS (default loopback 127.0.0.0/8,::1/128) are accepted without a peer registration. The Node panel authenticates the operator (or guest) at /ws/rendezvous upgrade before TCP is bridged to hbbs. Split panel↔Go installs must set the console container/host CIDR. Synthetic initiator id in audit logs: panel-web-remote. Do not list office/CGNAT public /32 ranges here as a shared-NAT workaround — prefer ALLOW_SHARED_NAT_INITIATOR (#399).
    • Shared-NAT opt-in (#399): ALLOW_SHARED_NAT_INITIATOR=Y authorizes outbound punch/relay from multi-peer public IPs as shared-nat-initiator when stronger identity is unavailable. Device passwords still gate control sessions. RelayResponse forwarding correlates via pending UUID / exact socket_addr (not FindByIP misdelivery). Keep SAME_NAT_RELAY enabled (default) for same-site pairs; disabling it with several live peers on one IP logs a warning.
    • Viewer-only (#327 / #375): TCP RegisterPk keeps the punch connection alive and binds tcpSessionPeerID; stock clients may also send a login token when the OS service is stopped. In managed mode, viewer-only mobiles that never send RegisterPeer/RegisterPk are still placed in the enrollment queue from (1) a successful /api/login (or TFA/OIDC session issue) with a non-empty client ID, and/or (2) a PunchHole/RequestRelay rejected with a valid opaque login token whose ClientID has no approved peer. Locked mode does not queue. IP/address-only initiator resolution never invents queue entries. Operator approval is still required before outbound sessions work. Stock RustDesk may show “ID does not exist” for this refusal (PunchHoleResponse_ID_NOT_EXIST) — that message often means the initiator is not approved, not that the target ID is missing.
  • Commit references for GitHub issues should use Refs #N (not Fixes) when the user wants the issue left open.