From d793bcf5693f28bb90d3c01147d504f49b347419 Mon Sep 17 00:00:00 2001 From: lejianwen <84855512@qq.com> Date: Sun, 12 Jan 2025 19:17:53 +0800 Subject: [PATCH] docs: up readme --- README-EN.md | 354 +++++++++++++++++++++++++++++++++++++++++++++++++ README-ZH.md | 348 ------------------------------------------------ README.md | 287 ++++++++++++++++++++++----------------- img.png | Bin 0 -> 49462 bytes readme/api.png | Bin 0 -> 49462 bytes 5 files changed, 520 insertions(+), 469 deletions(-) create mode 100644 README-EN.md delete mode 100644 README-ZH.md create mode 100644 img.png create mode 100644 readme/api.png diff --git a/README-EN.md b/README-EN.md new file mode 100644 index 0000000..fdfa7b8 --- /dev/null +++ b/README-EN.md @@ -0,0 +1,354 @@ +

+ Manually • + Docker • + S6-overlay • + Keypair • + Debian • + Variables
+ [Deutsch] | [Nederlands] | [繁體中文] | [简体中文]
+

+ +# 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 want extra features, [RustDesk Server Pro](https://rustdesk.com/pricing.html) might suit you better. + +If you want to 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 to [Docker Hub](https://hub.docker.com/r/rustdesk) and [GitHub Container Registry](https://github.com/rustdesk?tab=packages&repo_name=rustdesk-server) on every GitHub release. We have 2 kind of images. + +### Classic image + +These images are built from scratch with two main binaries (`hbbs` and `hbbr`). They're available on [Docker Hub](https://hub.docker.com/r/rustdesk/rustdesk-server/) and [GitHub Container Registry](https://github.com/rustdesk/rustdesk-server/pkgs/container/rustdesk-server) with these architectures: + +* amd64 +* arm64v8 +* armv7 + +You could use `latest` tag or major version tag `1` with supported architectures: + +| Version | image:tag | +| ------------- | --------------------------------- | +| latest | `rustdesk/rustdesk-server:latest` | +| Major version | `rustdesk/rustdesk-server:1` | + + +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 +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 +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 (line 18 and line 33) if you need. + +(docker-compose credit goes to @lukebarone and @QuiGonLeong) + +> [!NOTE] +> The rustdesk/rustdesk-server:latest in China may be replaced with the latest version number on Docker Hub, such as `rustdesk-server:1.1.10-3`. Otherwise, the old version may be pulled due to image acceleration. + +> [!NOTE] +> If you are experiencing issues pulling from Docker Hub, try pulling from the [GitHub Container Registry](https://github.com/rustdesk/rustdesk-server/pkgs/container/rustdesk-server) instead. + +## S6-overlay based images + +These images are build against `busybox:stable` with the addition of the binaries (both `hbbs` and `hbbr`) 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/) and [GitHub Container Registry](https://github.com/rustdesk/rustdesk-server/pkgs/container/rustdesk-server) with these architectures: + +* amd64 +* i386 +* arm64v8 +* armv7 + +You could use `latest` tag or major version tag `1` with supported architectures: + +| Version | image:tag | +| ------------- | ------------------------------------ | +| latest | `rustdesk/rustdesk-server-s6:latest` | +| Major version | `rustdesk/rustdesk-server-s6:1` | + +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 cannot 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 24.04 LTS +- Ubuntu 22.04 LTS +- Ubuntu 20.04 LTS +- Ubuntu 18.04 LTS +- Debian 12 bookworm +- 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 | 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) | diff --git a/README-ZH.md b/README-ZH.md deleted file mode 100644 index 4f8c07b..0000000 --- a/README-ZH.md +++ /dev/null @@ -1,348 +0,0 @@ -

- 自行构建 • - Docker • - S6-overlay • - 密钥 • - Debian • - 环境参数
- [English] | [Deutsch] | [Nederlands] | [繁体中文]
-

- -# 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) - -[**下载**](https://github.com/rustdesk/rustdesk-server/releases) - -[**说明文件**](https://rustdesk.com/docs/zh-cn/self-host/) - -[**FAQ**](https://github.com/rustdesk/rustdesk/wiki/FAQ) - -自行搭建属于你的RustDesk服务器,所有的一切都是免费且开源的 - -## 如何自行构建 - -```bash -cargo build --release -``` - -执行后会在target/release目录下生成三个对应平台的可执行程序 - -- hbbs - RustDesk ID/会和服务器 -- hbbr - RustDesk 中继服务器 -- rustdesk-utils - RustDesk 命令行工具 - -您可以在 [releases](https://github.com/rustdesk/rustdesk-server/releases) 页面中找到最新的服务端软件。 - -如果您需要额外的功能支持,[RustDesk 专业版服务器](https://rustdesk.com/pricing.html) 获取更适合您。 - -如果您想开发自己的服务器,[rustdesk-server-demo](https://github.com/rustdesk/rustdesk-server-demo) 应该会比直接使用这个仓库更简单快捷。 - -## Docker 镜像 - -Docker镜像会在每次 GitHub 发布新的release版本时自动构建。我们提供两种类型的镜像。 - -### Classic 传统镜像 - -这个类型的镜像是基于 `ubuntu-20.04` 进行构建,镜像仅包含两个主要的可执行程序(`hbbr` 和 `hbbs`)。它们可以通过以下tag在 [Docker Hub](https://hub.docker.com/r/rustdesk/rustdesk-server/) 上获得: - -| 架构 | image:tag | -|---------| ----------------------------------------- | -| amd64 | `rustdesk/rustdesk-server:latest` | -| arm64v8 | `rustdesk/rustdesk-server:latest-arm64v8` | - -您可以使用以下命令,直接通过 ``docker run`` 來启动这些镜像: - -```bash -docker run --name hbbs --net=host -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbs -r -docker run --name hbbr --net=host -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbr -``` - -或不使用 `--net=host` 参数启动, 但这样 P2P 直连功能将无法工作。 - -对于使用了 SELinux 的系统,您需要将 ``/root`` 替换为 ``/root:z``,以保证容器的正常运行。或者,也可以通过添加参数 ``--security-opt label=disable`` 来完全禁用 SELinux 容器隔离。 - -```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 -docker run --name hbbr -p 21117:21117 -p 21119:21119 -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbr -``` - -`relay-server-ip` 参数是运行这些容器的服务器的 IP 地址(或 DNS 名称)。如果你不想使用 **21117** 作为 `hbbr` 的服务端口,可使用可选参数 `port` 进行指定。 - -您也可以使用 docker-compose 进行构建,以下为配置示例: - -```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 -``` - -编辑第16行来指定你的中继服务器 (默认端口监听在 21117 的那一个)。 如果需要的话,您也可以编辑 volume 信息 (第 18 和 33 行)。 - -(感谢 @lukebarone 和 @QuiGonLeong 协助提供的 docker-compose 配置示例) - -## 基于 S6-overlay 的镜像 - -> 这些镜像是针对 `busybox:stable` 构建的,并添加了可执行程序(hbbr 和 hbbs)以及 [S6-overlay](https://github.com/just-containers/s6-overlay)。 它们可以使用以下tag在 [Docker hub](https://hub.docker.com/r/rustdesk/rustdesk-server-s6/) 上获取: - - -| 架構 | 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` | - -强烈建议您使用`major version` 或 `latest` tag 的 `multiarch` 架构的镜像。 - -S6-overlay 在此处作为监控程序,用以保证两个进程的运行,因此使用此镜像,您无需运行两个容器。 - -您可以使用 `docker run` 命令直接启动镜像,如下: - -```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 -``` - -或刪去 `--net=host` 参数, 但 P2P 直连功能将无法工作。 - -```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 -``` - -或着您也可以使用 docker-compose 文件: - -```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 -``` - -对于此容器镜像,除了在下面的环境变量部分指定的变量之外,您还可以使用以下`环境变量` - -| 环境变量 | 是否可选 | 描述 | -|----------------|------|--------------------------| -| RELAY | 否 | 运行此容器的宿主机的 IP 地址/ DNS 名称 | -| ENCRYPTED_ONLY | 是 | 如果设置为 **"1"**,将不接受未加密的连接。 | -| KEY_PUB | 是 | 密钥对中的公钥(Public Key) | -| KEY_PRIV | 是 | 密钥对中的私钥(Private Key) | - -### 基于 S6-overlay 镜像的密钥管理 - -您可以将密钥对保存在 Docker volume 中,但我们建议不要将密钥写入文件系統中;因此,我们提供了一些方案。 - -在容器启动时,会检查密钥对是否存在(`/data/id_ed25519.pub` 和 `/data/id_ed25519`),如果其中一個密钥不存在,则会从环境变量或 Docker Secret 中重新生成它。 -然后检查密钥对的可用性:如果公钥和私钥不匹配,容器将停止运行。 -如果您未提供密钥,`hbbs` 将会在默认位置生成一个。 - -#### 使用 ENV 存储密钥对 - -您可以使用 Docker 环境变量來存储密钥。如下: - -```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 -``` - -#### 使用 Docker Secret 來保存密钥对 - -您还可以使用 Docker Secret 來保存密钥。 -如果您使用 **docker-compose** 或 **docker swarm**,推荐您使用。 -只需按照以下示例操作: - -```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 -``` - -## 如何生成密钥对 - -加密需要一对密钥;您可以按照前面所述提供它,但需要一个工具去生成密钥对。 - -您可以使用以下命令生成一对密钥: - -```bash -/usr/bin/rustdesk-utils genkeypair -``` - -如果您沒有(或不想)在系统上安装 `rustdesk-utils` 套件,您可以使用 Docker 执行相同的命令: - -```bash -docker run --rm --entrypoint /usr/bin/rustdesk-utils rustdesk/rustdesk-server-s6:latest genkeypair -``` - -运行后的输出内容如下: - -```text -Public Key: 8BLLhtzUBU/XKAH4mep3p+IX4DSApe7qbAwNH9nv4yA= -Secret Key: egAVd44u33ZEUIDTtksGcHeVeAwywarEdHmf99KM5ajwEsuG3NQFT9coAfiZ6nen4hfgNICl7upsDA0f2e/jIA== -``` - -## .deb 套件 - -每个可执行文件都有单独的 .deb 套件可供使用,您可以在 [releases](https://github.com/rustdesk/rustdesk-server/releases) 页面中找到它們。 -這些套件适用于以下发行版: - -- Ubuntu 22.04 LTS -- Ubuntu 20.04 LTS -- Ubuntu 18.04 LTS -- Debian 11 bullseye -- Debian 10 buster - -## ENV 环境变量 - -可以使用这些`环境变量`参数來配置 hbbs 和 hbbr。 -您可以像往常一样指定参数,或者使用 .env 文件。 - -| 参数 | 可执行文件 | 描述 | -|-----------------------|---------------|--------------------------------------------------| -| ALWAYS_USE_RELAY | hbbs | 如果设定为 **"Y"**,将关闭直接点对点连接功能 | -| DB_URL | hbbs | 数据库配置 | -| DOWNGRADE_START_CHECK | hbbr | 降级检查之前的延迟是啊尽(以秒为单位) | -| DOWNGRADE_THRESHOLD | hbbr | 降级检查的阈值(bit/ms) | -| KEY | hbbs/hbbr | 如果设置了此参数,将强制使用指定密钥对,如果设为 **"_"**,则强制使用任意密钥 | -| LIMIT_SPEED | hbbr | 速度限制(以Mb/s为单位) | -| PORT | hbbs/hbbr | 监听端口(hbbs为21116,hbbr为21117) | -| RELAY_SERVERS | hbbs | 运行hbbr的机器的IP地址/DNS名称(用逗号分隔) | -| RUST_LOG | all | 设置 debug level (error\|warn\|info\|debug\|trace) | -| SINGLE_BANDWIDTH | hbbr | 单个连接的最大带宽(以Mb/s为单位) | -| TOTAL_BANDWIDTH | hbbr | 最大总带宽(以Mb/s为单位) | \ No newline at end of file diff --git a/README.md b/README.md index fdfa7b8..eb553ac 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,123 @@ + +# 关于此分支 + + + +[![build](https://github.com/lejianwen/rustdesk-server/actions/workflows/build.yaml/badge.svg)](https://github.com/lejianwen/rustdesk-server/actions/workflows/build.yaml) + +- 解决当客户端登录了`Api`账号时链接超时的问题 +- s6镜像添加了`Api`支持,`Api`开源地址 https://github.com/lejianwen/rustdesk-api + +## docker镜像地址 + +- s6 镜像 [lejianwen/rustdesk-server-s6](https://hub.docker.com/r/lejianwen/rustdesk-server-s6) + +```yaml + networks: + rustdesk-net: + external: false + services: + rustdesk: + ports: + - 21114:21114 + - 21115:21115 + - 21116:21116 + - 21116:21116/udp + - 21117:21117 + - 21118:21118 + - 21119:21119 + image: lejianwen/rustdesk-server-s6:latest + environment: + - RELAY= + - ENCRYPTED_ONLY=1 + - TZ=Asia/Shanghai + - RUSTDESK_API_RUSTDESK_ID_SERVER= + - RUSTDESK_API_RUSTDESK_RELAY_SERVER= + - RUSTDESK_API_RUSTDESK_API_SERVER=http:// + volumes: + - /data/rustdesk/server:/data + - /data/rustdesk/api:/app/data #将数据库挂载 + - /data/rustdesk/server:/app/conf/data #挂载key文件到api容器,可以不用使用 RUSTDESK_API_RUSTDESK_KEY + networks: + - rustdesk-net + restart: unless-stopped + +``` + +- 普通镜像 [lejianwen/rustdesk-server](https://hub.docker.com/r/lejianwen/rustdesk-server) + +![Api.png](./readme/api.png) +

- Manually • - Docker • - S6-overlay • - Keypair • - Debian • - Variables
- [Deutsch] | [Nederlands] | [繁體中文] | [简体中文]
+ 自行构建 • + Docker • + S6-overlay • + 密钥 • + Debian • + 环境参数
+ [English] | [Deutsch] | [Nederlands] | [繁体中文]

# 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/) +[**下载**](https://github.com/lejianwen/rustdesk-server/releases) -[**FAQ**](https://github.com/rustdesk/rustdesk/wiki/FAQ) +[**说明文件**](https://rustdesk.com/docs/zh-cn/self-host/) -Self-host your own RustDesk server, it is free and open source. +自行搭建属于你的RustDesk服务器,所有的一切都是免费且开源的 -## How to build manually +## 如何自行构建 ```bash cargo build --release ``` -Three executables will be generated in target/release. +执行后会在target/release目录下生成三个对应平台的可执行程序 -- hbbs - RustDesk ID/Rendezvous server -- hbbr - RustDesk relay server -- rustdesk-utils - RustDesk CLI utilities +- hbbs - RustDesk ID/会和服务器 +- hbbr - RustDesk 中继服务器 +- rustdesk-utils - RustDesk 命令行工具 -You can find updated binaries on the [Releases](https://github.com/rustdesk/rustdesk-server/releases) page. +您可以在 [releases](https://github.com/lejianwen/rustdesk-server/releases) 页面中找到最新的服务端软件。 -If you want extra features, [RustDesk Server Pro](https://rustdesk.com/pricing.html) might suit you better. +如果您需要额外的功能支持,[RustDesk 专业版服务器](https://rustdesk.com/pricing.html) 获取更适合您。 -If you want to 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. +如果您想开发自己的服务器,[rustdesk-server-demo](https://github.com/rustdesk/rustdesk-server-demo) 应该会比直接使用这个仓库更简单快捷。 -## Docker images +## Docker 镜像 -Docker images are automatically generated and published to [Docker Hub](https://hub.docker.com/r/rustdesk) and [GitHub Container Registry](https://github.com/rustdesk?tab=packages&repo_name=rustdesk-server) on every GitHub release. We have 2 kind of images. +Docker镜像会在每次 GitHub 发布新的release版本时自动构建。我们提供两种类型的镜像。 -### Classic image +### Classic 传统镜像 -These images are built from scratch with two main binaries (`hbbs` and `hbbr`). They're available on [Docker Hub](https://hub.docker.com/r/rustdesk/rustdesk-server/) and [GitHub Container Registry](https://github.com/rustdesk/rustdesk-server/pkgs/container/rustdesk-server) with these architectures: +这个类型的镜像是基于 `ubuntu-20.04` 进行构建,镜像仅包含两个主要的可执行程序(`hbbr` 和 `hbbs`)。它们可以通过以下tag在 [Docker Hub](https://hub.docker.com/r/lejianwen/rustdesk-server/) 上获得: -* amd64 -* arm64v8 -* armv7 +| 架构 | image:tag | +|---------| ----------------------------------------- | +| amd64 | `lejianwen/rustdesk-server:latest` | +| arm64v8 | `lejianwen/rustdesk-server:latest-arm64v8` | -You could use `latest` tag or major version tag `1` with supported architectures: - -| Version | image:tag | -| ------------- | --------------------------------- | -| latest | `rustdesk/rustdesk-server:latest` | -| Major version | `rustdesk/rustdesk-server:1` | - - -You can start these images directly with `docker run` with these commands: +您可以使用以下命令,直接通过 ``docker run`` 來启动这些镜像: ```bash -docker run --name hbbs --net=host -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbs -r -docker run --name hbbr --net=host -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbr +docker run --name hbbs --net=host -v "$PWD/data:/root" -d lejianwen/rustdesk-server:latest hbbs -r +docker run --name hbbr --net=host -v "$PWD/data:/root" -d lejianwen/rustdesk-server:latest hbbr ``` -or without `--net=host`, but P2P direct connection can not work. +或不使用 `--net=host` 参数启动, 但这样 P2P 直连功能将无法工作。 -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`. +对于使用了 SELinux 的系统,您需要将 ``/root`` 替换为 ``/root:z``,以保证容器的正常运行。或者,也可以通过添加参数 ``--security-opt label=disable`` 来完全禁用 SELinux 容器隔离。 ```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 -docker run --name hbbr -p 21117:21117 -p 21119:21119 -v "$PWD/data:/root" -d rustdesk/rustdesk-server:latest hbbr +docker run --name hbbs -p 21115:21115 -p 21116:21116 -p 21116:21116/udp -p 21118:21118 -v "$PWD/data:/root" -d lejianwen/rustdesk-server:latest hbbs -r +docker run --name hbbr -p 21117:21117 -p 21119:21119 -v "$PWD/data:/root" -d lejianwen/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`. +`relay-server-ip` 参数是运行这些容器的服务器的 IP 地址(或 DNS 名称)。如果你不想使用 **21117** 作为 `hbbr` 的服务端口,可使用可选参数 `port` 进行指定。 -You can also use docker-compose, using this configuration as a template: +您也可以使用 docker-compose 进行构建,以下为配置示例: ```yaml version: '3' @@ -93,7 +134,7 @@ services: - 21116:21116 - 21116:21116/udp - 21118:21118 - image: rustdesk/rustdesk-server:latest + image: lejianwen/rustdesk-server:latest command: hbbs -r rustdesk.example.com:21117 volumes: - ./data:/root @@ -108,7 +149,7 @@ services: ports: - 21117:21117 - 21119:21119 - image: rustdesk/rustdesk-server:latest + image: lejianwen/rustdesk-server:latest command: hbbr volumes: - ./data:/root @@ -117,45 +158,48 @@ services: 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 (line 18 and line 33) if you need. +编辑第16行来指定你的中继服务器 (默认端口监听在 21117 的那一个)。 如果需要的话,您也可以编辑 volume 信息 (第 18 和 33 行)。 -(docker-compose credit goes to @lukebarone and @QuiGonLeong) +(感谢 @lukebarone 和 @QuiGonLeong 协助提供的 docker-compose 配置示例) -> [!NOTE] -> The rustdesk/rustdesk-server:latest in China may be replaced with the latest version number on Docker Hub, such as `rustdesk-server:1.1.10-3`. Otherwise, the old version may be pulled due to image acceleration. +## 基于 S6-overlay 的镜像 -> [!NOTE] -> If you are experiencing issues pulling from Docker Hub, try pulling from the [GitHub Container Registry](https://github.com/rustdesk/rustdesk-server/pkgs/container/rustdesk-server) instead. +> 这些镜像是针对 `busybox:stable` 构建的,并添加了可执行程序(hbbr 和 hbbs)以及 [S6-overlay](https://github.com/just-containers/s6-overlay)。 它们可以使用以下tag在 [Docker hub](https://hub.docker.com/r/lejianwen/rustdesk-server-s6/) 上获取: -## S6-overlay based images -These images are build against `busybox:stable` with the addition of the binaries (both `hbbs` and `hbbr`) 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/) and [GitHub Container Registry](https://github.com/rustdesk/rustdesk-server/pkgs/container/rustdesk-server) with these architectures: +| 架構 | version | image:tag | +| --------- | ------- | -------------------------------------------- | +| multiarch | latest | `lejianwen/rustdesk-server-s6:latest` | +| amd64 | latest | `lejianwen/rustdesk-server-s6:latest-amd64` | +| i386 | latest | `lejianwen/rustdesk-server-s6:latest-i386` | +| arm64v8 | latest | `lejianwen/rustdesk-server-s6:latest-arm64v8` | +| armv7 | latest | `lejianwen/rustdesk-server-s6:latest-armv7` | +| multiarch | 2 | `lejianwen/rustdesk-server-s6:2` | +| amd64 | 2 | `lejianwen/rustdesk-server-s6:2-amd64` | +| i386 | 2 | `lejianwen/rustdesk-server-s6:2-i386` | +| arm64v8 | 2 | `lejianwen/rustdesk-server-s6:2-arm64v8` | +| armv7 | 2 | `lejianwen/rustdesk-server-s6:2-armv7` | +| multiarch | 2.0.0 | `lejianwen/rustdesk-server-s6:2.0.0` | +| amd64 | 2.0.0 | `lejianwen/rustdesk-server-s6:2.0.0-amd64` | +| i386 | 2.0.0 | `lejianwen/rustdesk-server-s6:2.0.0-i386` | +| arm64v8 | 2.0.0 | `lejianwen/rustdesk-server-s6:2.0.0-arm64v8` | +| armv7 | 2.0.0 | `lejianwen/rustdesk-server-s6:2.0.0-armv7` | -* amd64 -* i386 -* arm64v8 -* armv7 +强烈建议您使用`major version` 或 `latest` tag 的 `multiarch` 架构的镜像。 -You could use `latest` tag or major version tag `1` with supported architectures: +S6-overlay 在此处作为监控程序,用以保证两个进程的运行,因此使用此镜像,您无需运行两个容器。 -| Version | image:tag | -| ------------- | ------------------------------------ | -| latest | `rustdesk/rustdesk-server-s6:latest` | -| Major version | `rustdesk/rustdesk-server-s6:1` | - -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: +您可以使用 `docker run` 命令直接启动镜像,如下: ```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 + -v "$PWD/data:/data" -d lejianwen/rustdesk-server-s6:latest ``` -or without `--net=host`, but P2P direct connection cannot work. +或刪去 `--net=host` 参数, 但 P2P 直连功能将无法工作。 ```bash docker run --name rustdesk-server \ @@ -163,10 +207,10 @@ docker run --name rustdesk-server \ -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 + -v "$PWD/data:/data" -d lejianwen/rustdesk-server-s6:latest ``` -Or you can use a docker-compose file: +或着您也可以使用 docker-compose 文件: ```yaml version: '3' @@ -175,13 +219,14 @@ services: rustdesk-server: container_name: rustdesk-server ports: + - 21114:21114 - 21115:21115 - 21116:21116 - 21116:21116/udp - 21117:21117 - 21118:21118 - 21119:21119 - image: rustdesk/rustdesk-server-s6:latest + image: lejianwen/rustdesk-server-s6:latest environment: - "RELAY=rustdesk.example.com:21117" - "ENCRYPTED_ONLY=1" @@ -190,26 +235,26 @@ services: 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 | +| 环境变量 | 是否可选 | 描述 | +|----------------|------|--------------------------| +| RELAY | 否 | 运行此容器的宿主机的 IP 地址/ DNS 名称 | +| ENCRYPTED_ONLY | 是 | 如果设置为 **"1"**,将不接受未加密的连接。 | +| KEY_PUB | 是 | 密钥对中的公钥(Public Key) | +| KEY_PRIV | 是 | 密钥对中的私钥(Private Key) | -### Secret management in S6-overlay based images +### 基于 S6-overlay 镜像的密钥管理 -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. +您可以将密钥对保存在 Docker volume 中,但我们建议不要将密钥写入文件系統中;因此,我们提供了一些方案。 -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. +在容器启动时,会检查密钥对是否存在(`/data/id_ed25519.pub` 和 `/data/id_ed25519`),如果其中一個密钥不存在,则会从环境变量或 Docker Secret 中重新生成它。 +然后检查密钥对的可用性:如果公钥和私钥不匹配,容器将停止运行。 +如果您未提供密钥,`hbbs` 将会在默认位置生成一个。 -#### Use ENV to store the key pair +#### 使用 ENV 存储密钥对 -You can use docker environment variables to store the keys. Just follow this examples: +您可以使用 Docker 环境变量來存储密钥。如下: ```bash docker run --name rustdesk-server \ @@ -219,7 +264,7 @@ docker run --name rustdesk-server \ -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 + -v "$PWD/db:/db" -d lejianwen/rustdesk-server-s6:latest ``` ```yaml @@ -229,13 +274,14 @@ services: rustdesk-server: container_name: rustdesk-server ports: + - 21114:21114 - 21115:21115 - 21116:21116 - 21116:21116/udp - 21117:21117 - 21118:21118 - 21119:21119 - image: rustdesk/rustdesk-server-s6:latest + image: lejianwen/rustdesk-server-s6:latest environment: - "RELAY=rustdesk.example.com:21117" - "ENCRYPTED_ONLY=1" @@ -247,11 +293,11 @@ services: restart: unless-stopped ``` -#### Use Docker secrets to store the key pair +#### 使用 Docker Secret 來保存密钥对 -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: +您还可以使用 Docker Secret 來保存密钥。 +如果您使用 **docker-compose** 或 **docker swarm**,推荐您使用。 +只需按照以下示例操作: ```bash cat secrets/id_ed25519.pub | docker secret create key_pub - @@ -263,7 +309,7 @@ docker service create --name rustdesk-server \ -e "ENCRYPTED_ONLY=1" \ -e "DB_URL=/db/db_v2.sqlite3" \ --mount "type=bind,source=$PWD/db,destination=/db" \ - rustdesk/rustdesk-server-s6:latest + lejianwen/rustdesk-server-s6:latest ``` ```yaml @@ -273,13 +319,14 @@ services: rustdesk-server: container_name: rustdesk-server ports: + - 21114:21114 - 21115:21115 - 21116:21116 - 21116:21116/udp - 21117:21117 - 21118:21118 - 21119:21119 - image: rustdesk/rustdesk-server-s6:latest + image: lejianwen/rustdesk-server-s6:latest environment: - "RELAY=rustdesk.example.com:21117" - "ENCRYPTED_ONLY=1" @@ -298,57 +345,55 @@ secrets: 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: +如果您沒有(或不想)在系统上安装 `rustdesk-utils` 套件,您可以使用 Docker 执行相同的命令: ```bash -docker run --rm --entrypoint /usr/bin/rustdesk-utils rustdesk/rustdesk-server-s6:latest genkeypair +docker run --rm --entrypoint /usr/bin/rustdesk-utils lejianwen/rustdesk-server-s6:latest genkeypair ``` -The output will be something like this: +运行后的输出内容如下: ```text Public Key: 8BLLhtzUBU/XKAH4mep3p+IX4DSApe7qbAwNH9nv4yA= Secret Key: egAVd44u33ZEUIDTtksGcHeVeAwywarEdHmf99KM5ajwEsuG3NQFT9coAfiZ6nen4hfgNICl7upsDA0f2e/jIA== ``` -## .deb packages +## .deb 套件 -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: +每个可执行文件都有单独的 .deb 套件可供使用,您可以在 [releases](https://github.com/lejianwen/rustdesk-server/releases) 页面中找到它們。 +這些套件适用于以下发行版: -- Ubuntu 24.04 LTS - Ubuntu 22.04 LTS - Ubuntu 20.04 LTS - Ubuntu 18.04 LTS -- Debian 12 bookworm - Debian 11 bullseye - Debian 10 buster -## ENV variables +## ENV 环境变量 -`hbbs` and `hbbr` can be configured using these ENV variables. -You can specify the variables as usual or use an `.env` file. +可以使用这些`环境变量`参数來配置 hbbs 和 hbbr。 +您可以像往常一样指定参数,或者使用 .env 文件。 -| 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 | 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) | +| 参数 | 可执行文件 | 描述 | +|-----------------------|---------------|--------------------------------------------------| +| ALWAYS_USE_RELAY | hbbs | 如果设定为 **"Y"**,将关闭直接点对点连接功能 | +| DB_URL | hbbs | 数据库配置 | +| DOWNGRADE_START_CHECK | hbbr | 降级检查之前的延迟是啊尽(以秒为单位) | +| DOWNGRADE_THRESHOLD | hbbr | 降级检查的阈值(bit/ms) | +| KEY | hbbs/hbbr | 如果设置了此参数,将强制使用指定密钥对,如果设为 **"_"**,则强制使用任意密钥 | +| LIMIT_SPEED | hbbr | 速度限制(以Mb/s为单位) | +| PORT | hbbs/hbbr | 监听端口(hbbs为21116,hbbr为21117) | +| RELAY_SERVERS | hbbs | 运行hbbr的机器的IP地址/DNS名称(用逗号分隔) | +| RUST_LOG | all | 设置 debug level (error\|warn\|info\|debug\|trace) | +| SINGLE_BANDWIDTH | hbbr | 单个连接的最大带宽(以Mb/s为单位) | +| TOTAL_BANDWIDTH | hbbr | 最大总带宽(以Mb/s为单位) | \ No newline at end of file diff --git a/img.png b/img.png new file mode 100644 index 0000000000000000000000000000000000000000..adabf28bceb8b01fa6dc05403ae5955ed3898517 GIT binary patch literal 49462 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 V-&h(uHpgl0-R1s6`S-`p|6j4u)BFGc literal 0 HcmV?d00001 diff --git a/readme/api.png b/readme/api.png new file mode 100644 index 0000000000000000000000000000000000000000..adabf28bceb8b01fa6dc05403ae5955ed3898517 GIT binary patch literal 49462 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 V-&h(uHpgl0-R1s6`S-`p|6j4u)BFGc literal 0 HcmV?d00001