Help us shape the future of Go! Take the 2026 Go Developer Survey

rdpanel

module
v0.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2026 License: MIT

README

RD Panel

RD Panel — API server and admin panel for RustDesk. Self-hosted, compatible with official RustDesk clients, shipped as one container together with hbbs/hbbr. Formerly rustdesk-panel.

Not affiliated with or endorsed by RustDesk / Purslane Ltd. "RustDesk" is used only to describe compatibility.

release ci image license

A Go backend + React UI for RustDesk, and a drop-in replacement for lejianwen/rustdesk-api and the lejianwen/rustdesk-server-s6 image:

  • official RustDesk clients (1.3–1.5) keep working against the same API URL;
  • users, tokens, devices and address books migrate with one command, without re-login.

Dashboard

Contents

Features

  • Client API (/api/*), wire-compatible with RustDesk 1.3–1.5:
    • password and OIDC login, heartbeat/sysinfo;
    • address books (legacy and personal/shared);
    • audit (connections, files, alarms, session notes);
    • deploy and switch-grant, custom-client deployment presets;
    • every endpoint has a contract test; audited against 1.4.6, 1.5.0 and master (compat notes).
  • Admin panel:
    • devices with live online status from hbbs (pushed over SSE);
    • users and groups, unified address books with sharing and coloured tags;
    • browser web client: connect to devices from the panel, no install (rdweb, end-to-end verified and encrypted);
    • connection access control (ACL) enforced by hbbs before a connection starts, with control roles that restrict sessions on RustDesk 1.4.5+ devices (how);
    • client MDM strategies with heartbeat push (security presets, group and device overrides);
    • "Install client" with the official clients preconfigured for this server, and opt-in public share links (/s/<token>) that give anyone the same without an account (share links);
    • audit logs, identity providers, hbbs/hbbr control;
    • English and Russian, light and dark themes, mobile layout.
  • Sign-in & Directory:
    • password, TOTP 2FA with recovery codes, passkeys (WebAuthn) for the panel;
    • LDAP / Active Directory integration with auto-provisioning, group mapping and periodic background sync;
    • e-mailed sign-in codes (panel and RustDesk client), password reset by e-mail;
    • OIDC (GitHub, Google, any OIDC provider) for both the panel and the RustDesk client;
    • the public client API and the admin panel can live on different hosts (e.g. panel only on a VPN/tailnet).
  • Server control & Routing:
    • relay servers, GeoIP and CIDR prefix routing, dynamic STUN fetch;
    • opt-in, token-authenticated panel federation to see peer panels' relays;
    • always-use-relay, must-login, IP blocker, block/blacklists, bandwidth;
    • opt-in keepalive for TCP/WebSocket clients;
    • a reconciler stores the desired state and re-applies it after hbbs/hbbr restarts.
  • Secure defaults: hashed tokens, AEAD-encrypted secrets at rest, argon2id passwords, PKCE, CSRF-protected cookie sessions, strict CSP, login rate limiting, trusted-proxy-only client IPs, no account linking by unverified e-mail.
  • Ops:
    • single static binary, SQLite (WAL), /healthz, Prometheus /metrics, JSON logs;
    • multi-arch image (amd64/arm64, ~48 MB, ~15–30 MB RAM for the whole stack);
    • Helm chart.

Screenshots

Devices Devices, dark
Devices with live presence Dark theme
Device details Address books
Device details Address books with sharing and tags
Users Groups
Users Groups
Audit Logins
Connection audit Login audit
Server Server settings
hbbs/hbbr status and control Panel settings
Identity providers Profile
OIDC identity providers Profile, 2FA
Login Mobile
Sign-in Mobile layout
More

Server console My devices My sessions User details Russian UI

Quick start (Docker)

mkdir -p /opt/rustdesk && cd /opt/rustdesk
curl -fsSL https://raw.githubusercontent.com/bropines/rdpanel/main/deploy/compose.example.yml -o compose.yml
curl -fsSL https://raw.githubusercontent.com/bropines/rdpanel/main/deploy/rdpanel.env.example -o rdpanel.env
chmod 600 rdpanel.env && $EDITOR rdpanel.env        # at least RELAY and RDPANEL_PUBLIC_URL
docker compose up -d
docker compose exec rustdesk rdpanel user create --admin admin

Then:

  1. Put a TLS reverse proxy in front of the panel (example).

  2. Configure RustDesk clients:

    client field value
    ID server <host>
    Relay server <host>
    API server RDPANEL_PUBLIC_URL
    Key contents of data/id_ed25519.pub

Image: ghcr.io/bropines/rdpanel — :X.Y.Z, :X.Y, :latest for releases, :edge for main. hbbs/hbbr are built from the rdpanel branch of bropines/rustdesk-server (upstream 1.1.16 + the lejianwen API/login patches + hardening and keepalive fixes).

Documentation

guide for
docs/deploy.md full Docker guide: reverse proxy, split public/internal hosts, passkeys, e-mail, WebSocket clients, image tags, building the image
docs/configuration.md every RDPANEL_* setting with its YAML key and default
deploy/helm/rdpanel Kubernetes (Helm chart)
docs/api.md admin API for scripts: personal API tokens, curl examples; interactive docs (Swagger UI) at /api/v1/docs on the admin host
docs/web-client.md browser remote desktop client: proxy requirements, who can use it, security model
docs/install-client.md, docs/share-links.md preconfigured client downloads; public share links for people without an account
docs/acl-policy.md declarative Access Policy (Tailscale-style HuJSON), roles, test assertions and GitOps workflow
docs/oidc.md single sign-on: Authentik, Keycloak, Pocket ID, GitHub, Google
docs/monitoring.md metrics, Grafana dashboard, alert rules
docs/relay-agents.md extra relays on other hosts (relay agents)
docs/webrtc.md WebRTC for RustDesk 1.5+: hbbs signaling, ICE/TURN servers pushed to clients, coturn
docs/migration.md coming from lejianwen/rustdesk-api
docs/schema.md database schema

Coming from lejianwen/rustdesk-api? Keep the same RUSTDESK_API_JWT_KEY and hbbs key pair, then run rdpanel migrate-legacy --from rustdeskapi.db --dry-run.

Building from source

Requirements: Go 1.26+, Node 20.19+ (only to build the UI).

make web build                      # builds web/dist, then bin/rdpanel with the UI embedded
export RDPANEL_DATA_DIR=./data
export RUSTDESK_API_JWT_KEY='...'   # the same value hbbs uses for MUST_LOGIN
./bin/rdpanel user create --admin admin   # prompts for the password
./bin/rdpanel serve                       # http://localhost:21114

Without make web the binary still builds and serves a placeholder page instead of the UI.

UI development
command what it does
rdpanel serve + cd web && npm run dev Vite dev server; proxies /api to the backend
npm run dev:mock no backend: the whole admin API from an in-memory dataset (Mock Service Worker; sign in as admin/admin, TOTP 123456)
npm run build:mock mock build to web/dist-mock (never embedded)
npm run e2e, npm run screenshots Playwright against the mock build
End-to-end against the real backend
  1. make web build && scripts/e2e-server.sh starts bin/rdpanel on :31114 with a fresh database, an admin and demo data seeded through the client API (scripts/seed-demo). Add HBB_BIN=<dir with hbbs, hbbr> for live hbbs/hbbr.
  2. cd web && npm run e2e:real runs web/e2e/real (set E2E_HBBS=1 with hbbs).
  3. npm run screenshots:real refreshes docs/screenshots/.

Commands

command purpose
rdpanel serve run the HTTP server (graceful shutdown on SIGINT/SIGTERM)
rdpanel user create [--admin] [--password-stdin] [--email E] [--display-name N] <username> create a user; password from the terminal prompt or stdin, never logged
rdpanel user reset-password [--password-stdin] <username> set a new password and revoke all of the user's sessions/tokens
rdpanel migrate-legacy --from <rustdeskapi.db> [--dry-run] [--report F] [--force] import a lejianwen/rustdesk-api v2.7 database (users, passwords, OAuth links, address books, devices, tokens, audit)
rdpanel config print effective configuration, secrets redacted
rdpanel version build information

HTTP surface

path description
/api/* RustDesk client API
/api/v1/admin/* panel JSON API (contract: api/openapi.yaml)
/api/v1/events Server-Sent Events (presence, audit)
/s/* public share link pages (RDPANEL_SHARE_LINKS_ENABLED, share-links.md)
/healthz liveness + DB ping
/metrics Prometheus metrics (restricted by RDPANEL_METRICS_ALLOW)
/* embedded single-page app

Settings: docs/configuration.md. Metrics, Grafana dashboard, alert rules, a Prometheus + Grafana compose example and the Helm PrometheusRule / dashboard options: docs/monitoring.md.

Development

make test     # go vet + go test -race + web tests
make lint     # go vet + staticcheck + web typecheck/lint
make gen      # regenerate web/src/api/schema.d.ts from api/openapi.yaml
# the database-backed Go suites on PostgreSQL (the role needs CREATEDB):
RDPANEL_TEST_PG_DSN='postgres://postgres:pw@127.0.0.1:5432/postgres?sslmode=disable' go test ./...

Layout: cmd/rdpanel (entry point), internal/{app,config,db,store,auth,crypto,httpx,web,...}, web/ (React + Vite), api/openapi.yaml, docs/ (schema and research notes). The database schema is documented in docs/schema.md.

License

The panel is MIT — see LICENSE and NOTICE. The hbbs/hbbr binaries bundled in the container image are AGPL-3.0 (source: bropines/rustdesk-server). RD Panel is an independent project, not affiliated with or endorsed by RustDesk / Purslane Ltd.

Directories

Path Synopsis
Package api embeds the admin API contract (openapi.yaml) so the server can serve it to signed-in panel users at /api/v1/openapi.{yaml,json}.
Package api embeds the admin API contract (openapi.yaml) so the server can serve it to signed-in panel users at /api/v1/openapi.{yaml,json}.
cmd
rdpanel command
Command rdpanel is the RustDesk API server and admin panel.
Command rdpanel is the RustDesk API server and admin panel.
internal
adminapi
Package adminapi implements the panel JSON API mounted at /api/v1/admin: cookie sessions (auth_tokens kind=web) or personal API tokens (Bearer rdp_..., api_tokens.go), CSRF double-submit (X-CSRF-Token) for cookie sessions, TOTP, OIDC panel login and CRUD for users, groups, devices, address books, audit, identity providers, server control and settings.
Package adminapi implements the panel JSON API mounted at /api/v1/admin: cookie sessions (auth_tokens kind=web) or personal API tokens (Bearer rdp_..., api_tokens.go), CSRF double-submit (X-CSRF-Token) for cookie sessions, TOTP, OIDC panel login and CRUD for users, groups, devices, address books, audit, identity providers, server control and settings.
agent
Package agent implements `rdpanel agent`: it runs next to (as the parent of) hbbr on a relay host, enrolls with the central panel using a one-time token, keeps an outbound ed25519-authenticated WebSocket session to <panel>/agent/v1/connect, persists the desired hbbr config it receives, applies it through hbbr's loopback admin channel (the hbbr half of the panel's reconciler, unchanged) and reports status.
Package agent implements `rdpanel agent`: it runs next to (as the parent of) hbbr on a relay host, enrolls with the central panel using a one-time token, keeps an outbound ed25519-authenticated WebSocket session to <panel>/agent/v1/connect, persists the desired hbbr config it receives, applies it through hbbr's loopback admin channel (the hbbr half of the panel's reconciler, unchanged) and reports status.
app
Package app wires configuration, storage, auth primitives and HTTP handlers into a runnable server, and implements the rdpanel command line.
Package app wires configuration, storage, auth primitives and HTTP handlers into a runnable server, and implements the rdpanel command line.
auth
Package auth implements credential primitives: password hashing and verification (argon2id, bcrypt, legacy rustdesk-api md5), client JWTs, opaque session tokens, TOTP, recovery codes and login rate limiting.
Package auth implements credential primitives: password hashing and verification (argon2id, bcrypt, legacy rustdesk-api md5), client JWTs, opaque session tokens, TOTP, recovery codes and login rate limiting.
authz
Package authz decides whether a RustDesk connection may start and which control permissions the controlled device applies to it, from the connection rules and control roles (docs/acl-policy.md).
Package authz decides whether a RustDesk connection may start and which control permissions the controlled device applies to it, from the connection rules and control roles (docs/acl-policy.md).
buildinfo
Package buildinfo exposes version metadata injected at link time:
Package buildinfo exposes version metadata injected at link time:
clientapi
Package clientapi implements the RustDesk client wire API mounted at /api (login, logout, currentUser, address books, accessible users/peers, heartbeat, sysinfo, audit, device provisioning).
Package clientapi implements the RustDesk client wire API mounted at /api (login, logout, currentUser, address books, accessible users/peers, heartbeat, sysinfo, audit, device provisioning).
clientdl
Package clientdl offers the official RustDesk clients set up for this server.
Package clientdl offers the official RustDesk clients set up for this server.
clientopts
Package clientopts holds the RustDesk client options the panel pushes to every device through the heartbeat "strategy" (config_options), currently the WebRTC ones: ice-servers (STUN/TURN for the WebRTC transport of RustDesk 1.5+) and allow-webrtc-congestion-control.
Package clientopts holds the RustDesk client options the panel pushes to every device through the heartbeat "strategy" (config_options), currently the WebRTC ones: ice-servers (STUN/TURN for the WebRTC transport of RustDesk 1.5+) and allow-webrtc-congestion-control.
config
Package config loads and validates rdpanel configuration.
Package config loads and validates rdpanel configuration.
crypto
Package crypto provides authenticated encryption for secrets at rest, key file management, random tokens and token hashing.
Package crypto provides authenticated encryption for secrets at rest, key file management, random tokens and token hashing.
db
Package db opens the panel database (SQLite by default, or PostgreSQL), applies embedded goose migrations and provides transaction helpers shared by the repositories in internal/store.
Package db opens the panel database (SQLite by default, or PostgreSQL), applies embedded goose migrations and provides transaction helpers shared by the repositories in internal/store.
db/dbtest
Package dbtest opens panel databases for tests: a SQLite file in the test's temporary directory by default, or a fresh PostgreSQL database when RDPANEL_TEST_PG_DSN is set, so the same suites run on both engines (CI runs the PostgreSQL pass against a postgres service container).
Package dbtest opens panel databases for tests: a SQLite file in the test's temporary directory by default, or a fresh PostgreSQL database when RDPANEL_TEST_PG_DSN is set, so the same suites run on both engines (CI runs the PostgreSQL pass against a postgres service container).
events
Package events is the in-process pub/sub for presence, device, audit and hbbs health events, exposed to the panel as Server-Sent Events at /api/v1/events.
Package events is the in-process pub/sub for presence, device, audit and hbbs health events, exposed to the panel as Server-Sent Events at /api/v1/events.
hbbs/control
Package control is a typed client for the hbbs/hbbr loopback admin channels (docs/research/hbbs-integration.md §1).
Package control is a typed client for the hbbs/hbbr loopback admin channels (docs/research/hbbs-integration.md §1).
hbbs/hbbstest
Package hbbstest provides test doubles for hbbs/hbbr.
Package hbbstest provides test doubles for hbbs/hbbr.
hbbs/presence
Package presence polls hbbs for the online state of every known device.
Package presence polls hbbs for the online state of every known device.
hbbs/reconcile
Package reconcile keeps hbbs/hbbr runtime settings in line with the desired state stored in the panel database (server_settings).
Package reconcile keeps hbbs/hbbr runtime settings in line with the desired state stored in the panel database (server_settings).
hbbs/relaystats
Package relaystats exports hbbr relay activity as Prometheus gauges.
Package relaystats exports hbbr relay activity as Prometheus gauges.
hbbs/wire
Package wire hand-encodes the tiny subset of the hbbs rendezvous protocol the panel needs: the length-prefixed TCP framing used by hbbs/hbbr and the RendezvousMessage envelope carrying OnlineRequest / OnlineResponse / KeyExchange.
Package wire hand-encodes the tiny subset of the hbbs rendezvous protocol the panel needs: the length-prefixed TCP framing used by hbbs/hbbr and the RendezvousMessage envelope carrying OnlineRequest / OnlineResponse / KeyExchange.
httpx
Package httpx contains HTTP middleware and helpers shared by every API surface: client IP resolution, request logging, panic recovery, metrics and JSON error responses.
Package httpx contains HTTP middleware and helpers shared by every API surface: client IP resolution, request logging, panic recovery, metrics and JSON error responses.
legacy
Package legacy imports a lejianwen/rustdesk-api v2.7 SQLite database (`rustdeskapi.db`) into the RD Panel schema.
Package legacy imports a lejianwen/rustdesk-api v2.7 SQLite database (`rustdeskapi.db`) into the RD Panel schema.
loginlog
Package loginlog is a minimal writer for the login_events table used by the panel login and the OIDC flows (stream B1).
Package loginlog is a minimal writer for the login_events table used by the panel login and the OIDC flows (stream B1).
logs
Package logs keeps recent log lines of hbbs, hbbr and rdpanel in memory for the panel's Server -> Logs page (GET /api/v1/admin/server/logs*).
Package logs keeps recent log lines of hbbs, hbbr and rdpanel in memory for the panel's Server -> Logs page (GET /api/v1/admin/server/logs*).
mail
Package mail sends the panel's transactional e-mails (address verification, sign-in codes, password reset, test message) over SMTP with net/smtp: implicit TLS, STARTTLS or plain, PLAIN/LOGIN authentication, and multipart/alternative (text + minimal HTML) bodies.
Package mail sends the panel's transactional e-mails (address verification, sign-in codes, password reset, test message) over SMTP with net/smtp: implicit TLS, STARTTLS or plain, PLAIN/LOGIN authentication, and multipart/alternative (text + minimal HTML) bodies.
mail/mailtest
Package mailtest is an in-process fake SMTP server for tests: it speaks enough ESMTP (EHLO, STARTTLS, AUTH PLAIN/LOGIN, MAIL, RCPT, DATA) for net/smtp and records every accepted message.
Package mailtest is an in-process fake SMTP server for tests: it speaks enough ESMTP (EHLO, STARTTLS, AUTH PLAIN/LOGIN, MAIL, RCPT, DATA) for net/smtp and records every accepted message.
mailauth
Package mailauth implements the e-mail based account features on top of internal/mail: the effective SMTP configuration (environment/config file, or the panel settings with an AEAD-sealed password), address verification codes, the e-mail second factor (panel login and the RustDesk client /api/login "email_check" step) and password reset links.
Package mailauth implements the e-mail based account features on top of internal/mail: the effective SMTP configuration (environment/config file, or the panel settings with an AEAD-sealed password), address verification codes, the e-mail second factor (panel login and the RustDesk client /api/login "email_check" step) and password reset links.
metrics
Package metrics holds the panel's business counters (logins, client tokens, client audit records) and the build-info gauge.
Package metrics holds the panel's business counters (logins, client tokens, client audit records) and the build-info gauge.
oidc
Package oidc implements login with external identity providers (GitHub, Google, generic OpenID Connect with discovery) for both the RustDesk client (/api/oidc/*, polling) and the panel (cookie session), plus linking identities to existing accounts.
Package oidc implements login with external identity providers (GitHub, Google, generic OpenID Connect with discovery) for both the RustDesk client (/api/oidc/*, polling) and the panel (cookie session), plus linking identities to existing accounts.
oidc/oidctest
Package oidctest provides fake identity providers (generic OIDC with discovery + signed ID tokens, and GitHub) for tests.
Package oidctest provides fake identity providers (generic OIDC with discovery + signed ID tokens, and GitHub) for tests.
relays
Package relays manages hbbr relays for hbbs: the co-located relay, static (unmanaged) relays and remote relay agents (`rdpanel agent`).
Package relays manages hbbr relays for hbbs: the co-located relay, static (unmanaged) relays and remote relay agents (`rdpanel agent`).
relays/agentproto
Package agentproto is the wire protocol between `rdpanel agent` (on a relay host, next to hbbr) and the panel's agent hub (/agent/v1/*).
Package agentproto is the wire protocol between `rdpanel agent` (on a relay host, next to hbbr) and the panel's agent hub (/agent/v1/*).
store
Package store holds typed repositories over the panel database.
Package store holds typed repositories over the panel database.
updatecheck
Package updatecheck looks up the latest RD Panel release on GitHub for the About page.
Package updatecheck looks up the latest RD Panel release on GitHub for the About page.
web
Package web serves the embedded single-page app and sets security headers.
Package web serves the embedded single-page app and sets security headers.
websessions
Package websessions remembers which panel user a browser (web client) session belongs to.
Package websessions remembers which panel user a browser (web client) session belongs to.
scripts
seed-demo command
Command seed-demo fills a running rdpanel with realistic demo data through its public APIs: users and groups through the admin API, devices, heartbeats, logins, address books and audit records through the RustDesk client API (exactly what real clients send).
Command seed-demo fills a running rdpanel with realistic demo data through its public APIs: users and groups through the admin API, devices, heartbeats, logins, address books and audit records through the RustDesk client API (exactly what real clients send).
wsclient command
Command wsclient reproduces a RustDesk client in WebSocket/TCP rendezvous mode against a real hbbs and prints its online timeline, to check hbbs' TCP_KEEPALIVE option (bropines/rustdesk-server >= 393f872).
Command wsclient reproduces a RustDesk client in WebSocket/TCP rendezvous mode against a real hbbs and prints its online timeline, to check hbbs' TCP_KEEPALIVE option (bropines/rustdesk-server >= 393f872).
Package web embeds the built React SPA (web/dist, produced by `npm run build`).
Package web embeds the built React SPA (web/dist, produced by `npm run build`).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL