# rustdesk-server Self-hosted [RustDesk Server Pro](https://rustdesk.com/docs/en/self-host/) (remote-desktop relay + rendezvous) for Sea Haven Industries, deployed to AWS via CDK. > Status: **scaffold** — not yet deployed. See [First deploy](#first-deploy). ## Architecture A single ARM64 EC2 instance runs RustDesk Server Pro (`hbbs` rendezvous/ID + `hbbr` relay) in Docker. Clients connect from anywhere over the public internet to a stable Elastic IP fronted by `rustdesk.seahaven.com`. ``` RustDesk clients (anywhere) │ TCP 21114-21119 / UDP 21116 ▼ Elastic IP ──► EC2 t4g.small (AL2023 arm64, SSM-managed) │ Docker: hbbs + hbbr (network_mode: host) ├─ /dev/xvda 20 GiB root (OS only, ephemeral) └─ /var/lib/rustdesk ◄── standalone EBS 20 GiB (RETAIN) key pair + sled DB Nightly DLM snapshots (retain 30, tag rustdesk-backup=true) ``` All durable state (the `id_ed25519` server key pair and the sled database) lives on a **standalone, RETAINed** EBS data volume, never an inline block device, so it survives instance replacement and stack deletion. See [RUNBOOK.md](RUNBOOK.md). ## Ports | Port | Proto | Purpose | Exposure | |---|---|---|---| | 21114 | TCP | Pro web console / API | **VPN/VPC only** (10.10.0.0/16, 10.20.0.0/16) | | 21115 | TCP | hbbs NAT type test | public | | 21116 | TCP + UDP | hbbs registration / hole punch / heartbeat | public | | 21117 | TCP | hbbr relay | public | | 21118 | TCP | hbbs web client (websocket) | public | | 21119 | TCP | hbbr web client (websocket) | public | Relay/rendezvous ports are public so clients connect from anywhere. The Pro admin console (21114) is restricted to the office VPN + VPC, so you administer the server and activate the Pro license over VPN. To take the relay VPN-only later, flip the `public` flags in `RUSTDESK_PORTS` in the stack. ## Resources - **EC2** `rustdesk-server` — AL2023 arm64, `t4g.small`, SSM-managed (no inbound SSH) - **EBS data volume** `rustdesk-data` — 20 GiB GP3, encrypted, `RemovalPolicy.RETAIN`, attached at `/dev/xvdf` - **Elastic IP** — stable public address, associated to the instance - **Security group** `rustdesk-server` — RustDesk ports above - **IAM role** `rustdesk-server-instance` — `AmazonSSMManagedInstanceCore` + `secretsmanager:GetSecretValue` on `rustdesk/*` - **DLM** `rustdesk-server-dlm` — nightly instance snapshots, retain 30 - **Route 53** A record `rustdesk.seahaven.com` → EIP ## Configuration ### Secrets (Secrets Manager) — created out of band | Secret | Contents | |---|---| | `rustdesk/server-key-pair` | `id_ed25519` private + `.pub` public key generated by `hbbs` on first boot (mirror up post-deploy so a replacement host keeps the same key) | | `rustdesk/pro-license` | RustDesk Server Pro license key | ### SSM parameters (non-secret) | Parameter | Purpose | |---|---| | `/rustdesk-server/relay-host` | Public hostname clients use (`rustdesk.seahaven.com`) | The pinned Docker image tag lives in `lib/rustdesk-server-stack.ts` (`RUSTDESK_IMAGE_TAG`). ## Deployment CI/CD runs through the reusable org workflows (`ci-typescript-cdk.yaml`, `cd-cdk.yaml`). Pushes to `main` deploy automatically. ```bash npm ci npx cdk diff npx cdk deploy ``` ## First deploy 1. Confirm a **public** subnet ID in `us-east-1a` and set `PUBLIC_SUBNET_ID` in `lib/rustdesk-server-stack.ts` (replace `subnet-REPLACE_ME`). 2. Verify/pin `RUSTDESK_IMAGE_TAG`. 3. Create the OIDC deploy role `githubdeploy-rustdesk-server` and the repo secret `AWS_DEPLOY_ROLE_ARN`. 4. `cdk deploy` (or push to `main`). The instance boots, pulls the images, and `hbbs` generates the key pair on the empty data volume. 5. SSM in, read `/var/lib/rustdesk/id_ed25519{,.pub}`, store into `rustdesk/server-key-pair`. 6. Over the office VPN, open `http://rustdesk.seahaven.com:21114`, activate the Pro license, create users (the console is not reachable off-VPN). 7. Point a test client at `rustdesk.seahaven.com` + the public key; confirm a session relays. ## Operations See [RUNBOOK.md](RUNBOOK.md) for key rotation, restore-from-snapshot, and instance replacement.