rustdesk-server/README.md
2023-01-08 11:31:13 +08:00

336 lines
11 KiB
Markdown

# RustDesk Server Program
[![build](https://github.com/rustdesk/rustdesk-server/actions/workflows/build.yaml/badge.svg)](https://github.com/rustdesk/rustdesk-server/actions/workflows/build.yaml)
[**Download**](https://github.com/rustdesk/rustdesk-server/releases)
[**Manual**](https://rustdesk.com/docs/en/self-host/)
[**FAQ**](https://github.com/rustdesk/rustdesk/wiki/FAQ)
Self-host your own RustDesk server, it is free and open source.
## How to build manually
```bash
cargo build --release
```
Three executables will be generated in target/release.
- hbbs - RustDesk ID/Rendezvous server
- hbbr - RustDesk relay server
- rustdesk-utils - RustDesk CLI utilities
You can find updated binaries on the [releases](https://github.com/rustdesk/rustdesk-server/releases) page.
If you wanna develop your own server, [rustdesk-server-demo](https://github.com/rustdesk/rustdesk-server-demo) might be a better and simpler start for you than this repo.
## Docker images
Docker images are automatically generated and published on every github release. We have 2 kind of images.
### Classic image
These images are build against `ubuntu-20.04` with the only addition of the main binaries (`hbbr` and `hbbs`). They're available on [Docker hub](https://hub.docker.com/r/rustdesk/rustdesk-server/) with these tags:
| architecture | image:tag |
| --- | --- |
| amd64 | `rustdesk/rustdesk-server:latest` |
| arm64v8 | `rustdesk/rustdesk-server:latest-arm64v8` |
You can start these images directly with `docker run` with these commands:
```bash
docker run --name hbbs --net=host -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbs -r <relay-server-ip[:port]>
docker run --name hbbr --net=host -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbr
```
or without --net=host, but P2P direct connection can not work.
For systems using SELinux, replacing `/root` by `/root:z` is required for the containers to run correctly. Alternatively, SELinux container separation can be disabled completely adding the option `--security-opt label=disable`.
```bash
docker run --name hbbs -p 21115:21115 -p 21116:21116 -p 21116:21116/udp -p 21118:21118 -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbs -r <relay-server-ip[:port]>
docker run --name hbbr -p 21117:21117 -p 21119:21119 -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbr
```
The `relay-server-ip` parameter is the IP address (or dns name) of the server running these containers. The **optional** `port` parameter has to be used if you use a port different than **21117** for `hbbr`.
You can also use docker-compose, using this configuration as a template:
```yaml
version: '3'
networks:
rustdesk-net:
external: false
services:
hbbs:
container_name: hbbs
ports:
- 21115:21115
- 21116:21116
- 21116:21116/udp
- 21118:21118
image: rustdesk/rustdesk-server:latest
command: hbbs -r rustdesk.example.com:21117
volumes:
- ./data:/root
networks:
- rustdesk-net
depends_on:
- hbbr
restart: unless-stopped
hbbr:
container_name: hbbr
ports:
- 21117:21117
- 21119:21119
image: rustdesk/rustdesk-server:latest
command: hbbr
volumes:
- ./data:/root
networks:
- rustdesk-net
restart: unless-stopped
```
Edit line 16 to point to your relay server (the one listening on port 21117). You can also edit the volume lines (L18 and L33) if you need.
(docker-compose credit goes to @lukebarone and @QuiGonLeong)
## S6-overlay based images
These images are build against `busybox:stable` with the addition of the binaries (both hbbr and hbbs) and [S6-overlay](https://github.com/just-containers/s6-overlay). They're available on [Docker hub](https://hub.docker.com/r/rustdesk/rustdesk-server-s6/) with these tags:
| architecture | version | image:tag |
| --- | --- | --- |
| multiarch | latest | `rustdesk/rustdesk-server-s6:latest` |
| amd64 | latest | `rustdesk/rustdesk-server-s6:latest-amd64` |
| i386 | latest | `rustdesk/rustdesk-server-s6:latest-i386` |
| arm64v8 | latest | `rustdesk/rustdesk-server-s6:latest-arm64v8` |
| armv7 | latest | `rustdesk/rustdesk-server-s6:latest-armv7` |
| multiarch | 2 | `rustdesk/rustdesk-server-s6:2` |
| amd64 | 2 | `rustdesk/rustdesk-server-s6:2-amd64` |
| i386 | 2 | `rustdesk/rustdesk-server-s6:2-i386` |
| arm64v8 | 2 | `rustdesk/rustdesk-server-s6:2-arm64v8` |
| armv7 | 2 | `rustdesk/rustdesk-server-s6:2-armv7` |
| multiarch | 2.0.0 | `rustdesk/rustdesk-server-s6:2.0.0` |
| amd64 | 2.0.0 | `rustdesk/rustdesk-server-s6:2.0.0-amd64` |
| i386 | 2.0.0 | `rustdesk/rustdesk-server-s6:2.0.0-i386` |
| arm64v8 | 2.0.0 | `rustdesk/rustdesk-server-s6:2.0.0-arm64v8` |
| armv7 | 2.0.0 | `rustdesk/rustdesk-server-s6:2.0.0-armv7` |
You're strongly encuraged to use the `multiarch` image either with the `major version` or `latest` tag.
The S6-overlay acts as a supervisor and keeps both process running, so with this image there's no need to have two separate running containers.
You can start these images directly with `docker run` with this command:
```bash
docker run --name rustdesk-server \
--net=host \
-e "RELAY=rustdeskrelay.example.com" \
-e "ENCRYPTED_ONLY=1" \
-v "$PWD/data:/data" -d rustdesk/rustdesk-server-s6:latest
```
or without --net=host, but P2P direct connection can not work.
```bash
docker run --name rustdesk-server \
-p 21115:21115 -p 21116:21116 -p 21116:21116/udp \
-p 21117:21117 -p 21118:21118 -p 21119:21119 \
-e "RELAY=rustdeskrelay.example.com" \
-e "ENCRYPTED_ONLY=1" \
-v "$PWD/data:/data" -d rustdesk/rustdesk-server-s6:latest
```
Or you can use a docker-compose file:
```yaml
version: '3'
services:
rustdesk-server:
container_name: rustdesk-server
ports:
- 21115:21115
- 21116:21116
- 21116:21116/udp
- 21117:21117
- 21118:21118
- 21119:21119
image: rustdesk/rustdesk-server-s6:latest
environment:
- "RELAY=rustdesk.example.com:21117"
- "ENCRYPTED_ONLY=1"
volumes:
- ./data:/data
restart: unless-stopped
```
For this container image, you can use these environment variables, **in addition** to the ones specified in the following **ENV variables** section:
| variable | optional | description |
| --- | --- | --- |
| RELAY | no | the IP address/DNS name of the machine running this container |
| ENCRYPTED_ONLY | yes | if set to **"1"** unencrypted connection will not be accepted |
| KEY_PUB | yes | public part of the key pair |
| KEY_PRIV | yes | private part of the key pair |
### Secret management in S6-overlay based images
You can obviously keep the key pair in a docker volume, but the best practices tells you to not write the keys on the filesystem; so we provide a couple of options.
On container startup, the presence of the keypair is checked (`/data/id_ed25519.pub` and `/data/id_ed25519`) and if one of these keys doesn't exist, it's recreated from ENV variables or docker secrets.
Then the validity of the keypair is checked: if public and private keys doesn't match, the container will stop.
If you provide no keys, `hbbs` will generate one for you, and it'll place it in the default location.
#### Use ENV to store the key pair
You can use docker environment variables to store the keys. Just follow this examples:
```bash
docker run --name rustdesk-server \
--net=host \
-e "RELAY=rustdeskrelay.example.com" \
-e "ENCRYPTED_ONLY=1" \
-e "DB_URL=/db/db_v2.sqlite3" \
-e "KEY_PRIV=FR2j78IxfwJNR+HjLluQ2Nh7eEryEeIZCwiQDPVe+PaITKyShphHAsPLn7So0OqRs92nGvSRdFJnE2MSyrKTIQ==" \
-e "KEY_PUB=iEyskoaYRwLDy5+0qNDqkbPdpxr0kXRSZxNjEsqykyE=" \
-v "$PWD/db:/db" -d rustdesk/rustdesk-server-s6:latest
```
```yaml
version: '3'
services:
rustdesk-server:
container_name: rustdesk-server
ports:
- 21115:21115
- 21116:21116
- 21116:21116/udp
- 21117:21117
- 21118:21118
- 21119:21119
image: rustdesk/rustdesk-server-s6:latest
environment:
- "RELAY=rustdesk.example.com:21117"
- "ENCRYPTED_ONLY=1"
- "DB_URL=/db/db_v2.sqlite3"
- "KEY_PRIV=FR2j78IxfwJNR+HjLluQ2Nh7eEryEeIZCwiQDPVe+PaITKyShphHAsPLn7So0OqRs92nGvSRdFJnE2MSyrKTIQ=="
- "KEY_PUB=iEyskoaYRwLDy5+0qNDqkbPdpxr0kXRSZxNjEsqykyE="
volumes:
- ./db:/db
restart: unless-stopped
```
#### Use Docker secrets to store the key pair
You can alternatively use docker secrets to store the keys.
This is useful if you're using **docker-compose** or **docker swarm**.
Just follow this examples:
```bash
cat secrets/id_ed25519.pub | docker secret create key_pub -
cat secrets/id_ed25519 | docker secret create key_priv -
docker service create --name rustdesk-server \
--secret key_priv --secret key_pub \
--net=host \
-e "RELAY=rustdeskrelay.example.com" \
-e "ENCRYPTED_ONLY=1" \
-e "DB_URL=/db/db_v2.sqlite3" \
--mount "type=bind,source=$PWD/db,destination=/db" \
rustdesk/rustdesk-server-s6:latest
```
```yaml
version: '3'
services:
rustdesk-server:
container_name: rustdesk-server
ports:
- 21115:21115
- 21116:21116
- 21116:21116/udp
- 21117:21117
- 21118:21118
- 21119:21119
image: rustdesk/rustdesk-server-s6:latest
environment:
- "RELAY=rustdesk.example.com:21117"
- "ENCRYPTED_ONLY=1"
- "DB_URL=/db/db_v2.sqlite3"
volumes:
- ./db:/db
restart: unless-stopped
secrets:
- key_pub
- key_priv
secrets:
key_pub:
file: secrets/id_ed25519.pub
key_priv:
file: secrets/id_ed25519
```
## How to create a keypair
A keypair is needed for encryption; you can provide it, as explained before, but you need a way to create one.
You can use this command to generate a keypair:
```bash
/usr/bin/rustdesk-utils genkeypair
```
If you don't have (or don't want) the `rustdesk-utils` package installed on your system, you can invoke the same command with docker:
```bash
docker run --rm --entrypoint /usr/bin/rustdesk-utils rustdesk/rustdesk-server-s6:latest genkeypair
```
The output will be something like this:
```text
Public Key: 8BLLhtzUBU/XKAH4mep3p+IX4DSApe7qbAwNH9nv4yA=
Secret Key: egAVd44u33ZEUIDTtksGcHeVeAwywarEdHmf99KM5ajwEsuG3NQFT9coAfiZ6nen4hfgNICl7upsDA0f2e/jIA==
```
## .deb packages
Separate .deb packages are available for each binary, you can find them in the [releases](https://github.com/rustdesk/rustdesk-server/releases).
These packages are meant for the following distributions:
- Ubuntu 22.04 LTS
- Ubuntu 20.04 LTS
- Ubuntu 18.04 LTS
- Debian 11 bullseye
- Debian 10 buster
## ENV variables
hbbs and hbbr can be configured using these ENV variables.
You can specify the variables as usual or use an `.env` file.
| variable | binary | description |
| --- | --- | --- |
| ALWAYS_USE_RELAY | hbbs | if set to **"Y"** disallows direct peer connection |
| DB_URL | hbbs | path for database file |
| DOWNGRADE_START_CHECK | hbbr | delay (in seconds) before downgrade check |
| DOWNGRADE_THRESHOLD | hbbr | threshold of downgrade check (bit/ms) |
| KEY | hbbs/hbbr | if set force the use of a specific key, if set to **"_"** force the use of any key |
| LIMIT_SPEED | hbbr | speed limit (in Mb/s) |
| PORT | hbbs/hbbr | listening port (21116 for hbbs - 21117 for hbbr) |
| RELAY_SERVERS | hbbs | IP address/DNS name of the machines running hbbr (separated by comma) |
| RUST_LOG | all | set debug level (error\|warn\|info\|debug\|trace) |
| SINGLE_BANDWIDTH | hbbr | max bandwidth for a single connection (in Mb/s) |
| TOTAL_BANDWIDTH | hbbr | max total bandwidth (in Mb/s) |