mirror of
https://github.com/rustdesk/rustdesk-server.git
synced 2026-03-06 20:13:12 +08:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f18a97644 | ||
|
|
3b386b6b54 | ||
|
|
b37033d92c | ||
|
|
b7bab80bfe | ||
|
|
041a603173 | ||
|
|
e40994d62e | ||
|
|
5078a1f797 | ||
|
|
a22dacce0c | ||
|
|
064c9e4bb4 | ||
|
|
3cf0f6560f | ||
|
|
c4c26dd6d7 | ||
|
|
4240c47244 | ||
|
|
6e91f41a10 | ||
|
|
1a7cee157c | ||
|
|
72641270f1 | ||
|
|
19f8d3a0f4 | ||
|
|
bac9548f86 | ||
|
|
79f0eb497b | ||
|
|
94ae51458c | ||
|
|
778c89efb1 |
22
.github/workflows/build.yaml
vendored
22
.github/workflows/build.yaml
vendored
@@ -173,12 +173,12 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
job:
|
job:
|
||||||
- { os: "linux", name: "amd64" }
|
- { os: "linux", name: "amd64", suffix: "" }
|
||||||
- { os: "linux", name: "arm64v8" }
|
- { os: "linux", name: "arm64v8", suffix: "" }
|
||||||
- { os: "linux", name: "armv7" }
|
- { os: "linux", name: "armv7", suffix: "" }
|
||||||
- { os: "linux", name: "i386" }
|
- { os: "linux", name: "i386", suffix: "" }
|
||||||
- { os: "linux", name: "amd64fb" }
|
- { os: "linux", name: "amd64fb", suffix: "" }
|
||||||
- { os: "windows", name: "x86_64" }
|
- { os: "windows", name: "x86_64", suffix: "-unsigned" }
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
@@ -195,13 +195,13 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
sudo apt update
|
sudo apt update
|
||||||
DEBIAN_FRONTEND=noninteractive sudo apt install -y zip
|
DEBIAN_FRONTEND=noninteractive sudo apt install -y zip
|
||||||
zip ${{ matrix.job.name }}/rustdesk-server-${{ matrix.job.os }}-${{ matrix.job.name }}.zip ${{ matrix.job.name }}/*
|
zip ${{ matrix.job.name }}/rustdesk-server-${{ matrix.job.os }}-${{ matrix.job.name }}${{ matrix.job.suffix }}.zip ${{ matrix.job.name }}/*
|
||||||
|
|
||||||
- name: Create Release (${{ matrix.job.os }} - (${{ matrix.job.name }})
|
- name: Create Release (${{ matrix.job.os }} - (${{ matrix.job.name }})
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
files: ${{ matrix.job.name }}/rustdesk-server-${{ matrix.job.os }}-${{ matrix.job.name }}.zip
|
files: ${{ matrix.job.name }}/rustdesk-server-${{ matrix.job.os }}-${{ matrix.job.name }}${{ matrix.job.suffix }}.zip
|
||||||
|
|
||||||
# docker build and push of single-arch images
|
# docker build and push of single-arch images
|
||||||
docker:
|
docker:
|
||||||
@@ -260,11 +260,12 @@ jobs:
|
|||||||
echo "MAJOR_TAG=$M" >> $GITHUB_ENV
|
echo "MAJOR_TAG=$M" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: "./docker"
|
context: "./docker"
|
||||||
platforms: ${{ matrix.job.docker_platform }}
|
platforms: ${{ matrix.job.docker_platform }}
|
||||||
push: true
|
push: true
|
||||||
|
provenance: false
|
||||||
build-args: |
|
build-args: |
|
||||||
S6_ARCH=${{ matrix.job.s6_platform }}
|
S6_ARCH=${{ matrix.job.s6_platform }}
|
||||||
tags: |
|
tags: |
|
||||||
@@ -380,11 +381,12 @@ jobs:
|
|||||||
echo "MAJOR_TAG=$M" >> $GITHUB_ENV
|
echo "MAJOR_TAG=$M" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: "./docker-classic"
|
context: "./docker-classic"
|
||||||
platforms: ${{ matrix.job.docker_platform }}
|
platforms: ${{ matrix.job.docker_platform }}
|
||||||
push: true
|
push: true
|
||||||
|
provenance: false
|
||||||
tags: |
|
tags: |
|
||||||
${{ secrets.DOCKER_IMAGE_CLASSIC }}:${{ env.LATEST_TAG }}-${{ matrix.job.name }}
|
${{ secrets.DOCKER_IMAGE_CLASSIC }}:${{ env.LATEST_TAG }}-${{ matrix.job.name }}
|
||||||
${{ secrets.DOCKER_IMAGE_CLASSIC }}:${{ env.GIT_TAG }}-${{ matrix.job.name }}
|
${{ secrets.DOCKER_IMAGE_CLASSIC }}:${{ env.GIT_TAG }}-${{ matrix.job.name }}
|
||||||
|
|||||||
329
.github/workflows/ghcr.yml
vendored
Normal file
329
.github/workflows/ghcr.yml
vendored
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
name: Build and publish to ghcr.io
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
- '[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
- 'v[0-9]+.[0-9]+.[0-9]+-[0-9]+'
|
||||||
|
- '[0-9]+.[0-9]+.[0-9]+-[0-9]+'
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
LATEST_TAG: latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write # So need to set "secrets.GITHUB_TOKEN"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
# Binary build
|
||||||
|
build:
|
||||||
|
name: Build - ${{ matrix.job.name }}
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
job:
|
||||||
|
- { name: "amd64", target: "x86_64-unknown-linux-musl" }
|
||||||
|
- { name: "arm64v8", target: "aarch64-unknown-linux-musl" }
|
||||||
|
- { name: "armv7", target: "armv7-unknown-linux-musleabihf" }
|
||||||
|
- { name: "i386", target: "i686-unknown-linux-musl" }
|
||||||
|
#- { name: "amd64fb", target: "x86_64-unknown-freebsd" }
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: dtolnay/rust-toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: "1.70.0"
|
||||||
|
targets: ${{ matrix.job.target }}
|
||||||
|
components: "rustfmt"
|
||||||
|
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
prefix-key: ${{ matrix.job.os }}
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: --release --all-features --target=${{ matrix.job.target }}
|
||||||
|
use-cross: true
|
||||||
|
|
||||||
|
- name: Exec chmod
|
||||||
|
run: chmod -v a+x target/${{ matrix.job.target }}/release/*
|
||||||
|
|
||||||
|
- name: Publish Artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: binaries-linux-${{ matrix.job.name }}
|
||||||
|
path: |
|
||||||
|
target/${{ matrix.job.target }}/release/hbbr
|
||||||
|
target/${{ matrix.job.target }}/release/hbbs
|
||||||
|
target/${{ matrix.job.target }}/release/rustdesk-utils
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
# Build and push single-arch Docker images to ghcr.io
|
||||||
|
create-s6-overlay-images:
|
||||||
|
name: Docker push - ${{ matrix.job.name }}
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
job:
|
||||||
|
- { name: "amd64", docker_platform: "linux/amd64", s6_platform: "x86_64" }
|
||||||
|
- { name: "arm64v8", docker_platform: "linux/arm64", s6_platform: "aarch64" }
|
||||||
|
- { name: "armv7", docker_platform: "linux/arm/v7", s6_platform: "armhf" }
|
||||||
|
- { name: "i386", docker_platform: "linux/386", s6_platform: "i686" }
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Download binaries
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: binaries-linux-${{ matrix.job.name }}
|
||||||
|
path: docker/rootfs/usr/bin
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Make binaries executable
|
||||||
|
run: chmod -v a+x docker/rootfs/usr/bin/*
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to GitHub Container Registry
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ghcr.io/${{ github.repository }}-s6
|
||||||
|
|
||||||
|
- name: Get git tag
|
||||||
|
id: vars
|
||||||
|
run: |
|
||||||
|
T=${GITHUB_REF#refs/*/}
|
||||||
|
M=${T%%.*}
|
||||||
|
echo "GIT_TAG=$T" >> $GITHUB_ENV
|
||||||
|
echo "MAJOR_TAG=$M" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: "./docker"
|
||||||
|
platforms: ${{ matrix.job.docker_platform }}
|
||||||
|
push: true
|
||||||
|
provenance: false
|
||||||
|
build-args: |
|
||||||
|
S6_ARCH=${{ matrix.job.s6_platform }}
|
||||||
|
tags: |
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.LATEST_TAG }}-${{ matrix.job.name }}
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.GIT_TAG }}-${{ matrix.job.name }}
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.MAJOR_TAG }}-${{ matrix.job.name }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
|
# Set up minifest and tag for pushed image
|
||||||
|
create-s6-overlay-images-manifest:
|
||||||
|
name: Manifest for s6-overlay images
|
||||||
|
needs: create-s6-overlay-images
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Log in to GitHub Container Registry
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get git tag
|
||||||
|
id: vars
|
||||||
|
run: |
|
||||||
|
T=${GITHUB_REF#refs/*/}
|
||||||
|
M=${T%%.*}
|
||||||
|
echo "GIT_TAG=$T" >> $GITHUB_ENV
|
||||||
|
echo "MAJOR_TAG=$M" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# Create and push manifest for :ve.rs.ion tag
|
||||||
|
- name: Create and push manifest (:ve.rs.ion)
|
||||||
|
uses: Noelware/docker-manifest-action@master
|
||||||
|
if: github.event_name != 'workflow_dispatch'
|
||||||
|
with:
|
||||||
|
base-image: ghcr.io/${{ github.repository }}-s6:${{ env.GIT_TAG }}
|
||||||
|
extra-images: |
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.GIT_TAG }}-amd64,
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.GIT_TAG }}-arm64v8,
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.GIT_TAG }}-armv7,
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.GIT_TAG }}-i386
|
||||||
|
push: true
|
||||||
|
|
||||||
|
# Create and push manifest for :major tag
|
||||||
|
- name: Create and push manifest (:major)
|
||||||
|
uses: Noelware/docker-manifest-action@master
|
||||||
|
with:
|
||||||
|
base-image: ghcr.io/${{ github.repository }}-s6:${{ env.MAJOR_TAG }}
|
||||||
|
extra-images: |
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.MAJOR_TAG }}-amd64,
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.MAJOR_TAG }}-arm64v8,
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.MAJOR_TAG }}-armv7,
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.MAJOR_TAG }}-i386
|
||||||
|
push: true
|
||||||
|
|
||||||
|
# Create and push manifest for :latest tag
|
||||||
|
- name: Create and push manifest (:latest)
|
||||||
|
uses: Noelware/docker-manifest-action@master
|
||||||
|
with:
|
||||||
|
base-image: ghcr.io/${{ github.repository }}-s6:${{ env.LATEST_TAG }}
|
||||||
|
extra-images: |
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.LATEST_TAG }}-amd64,
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.LATEST_TAG }}-arm64v8,
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.LATEST_TAG }}-armv7,
|
||||||
|
ghcr.io/${{ github.repository }}-s6:${{ env.LATEST_TAG }}-i386
|
||||||
|
push: true
|
||||||
|
|
||||||
|
# Build and push single-arch Docker images to ghcr.io
|
||||||
|
create-classic-images:
|
||||||
|
name: Docker push - ${{ matrix.job.name }}
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
job:
|
||||||
|
- { name: "amd64", docker_platform: "linux/amd64" }
|
||||||
|
- { name: "arm64v8", docker_platform: "linux/arm64" }
|
||||||
|
- { name: "armv7", docker_platform: "linux/arm/v7" }
|
||||||
|
- { name: "i386", docker_platform: "linux/386" }
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Download binaries
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: binaries-linux-${{ matrix.job.name }}
|
||||||
|
path: docker-classic
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Make binaries executable
|
||||||
|
run: chmod -v a+x docker-classic/*
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to GitHub Container Registry
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ghcr.io/${{ github.repository }}
|
||||||
|
|
||||||
|
- name: Get git tag
|
||||||
|
id: vars
|
||||||
|
run: |
|
||||||
|
T=${GITHUB_REF#refs/*/}
|
||||||
|
M=${T%%.*}
|
||||||
|
echo "GIT_TAG=$T" >> $GITHUB_ENV
|
||||||
|
echo "MAJOR_TAG=$M" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: "./docker-classic"
|
||||||
|
platforms: ${{ matrix.job.docker_platform }}
|
||||||
|
push: true
|
||||||
|
provenance: false
|
||||||
|
tags: |
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.LATEST_TAG }}-${{ matrix.job.name }}
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.GIT_TAG }}-${{ matrix.job.name }}
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.MAJOR_TAG }}-${{ matrix.job.name }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
|
# Set up minifest and tag for pushed image
|
||||||
|
create-classic-images-manifest:
|
||||||
|
name: Manifest for classic images
|
||||||
|
needs: create-classic-images
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Log in to GitHub Container Registry
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get git tag
|
||||||
|
id: vars
|
||||||
|
run: |
|
||||||
|
T=${GITHUB_REF#refs/*/}
|
||||||
|
M=${T%%.*}
|
||||||
|
echo "GIT_TAG=$T" >> $GITHUB_ENV
|
||||||
|
echo "MAJOR_TAG=$M" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# Create and push manifest for :ve.rs.ion tag
|
||||||
|
- name: Create and push manifest (:ve.rs.ion)
|
||||||
|
uses: Noelware/docker-manifest-action@master
|
||||||
|
if: github.event_name != 'workflow_dispatch'
|
||||||
|
with:
|
||||||
|
base-image: ghcr.io/${{ github.repository }}:${{ env.GIT_TAG }}
|
||||||
|
extra-images: |
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.GIT_TAG }}-amd64,
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.GIT_TAG }}-arm64v8,
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.GIT_TAG }}-armv7,
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.GIT_TAG }}-i386
|
||||||
|
push: true
|
||||||
|
|
||||||
|
# Create and push manifest for :major tag
|
||||||
|
- name: Create and push manifest (:major)
|
||||||
|
uses: Noelware/docker-manifest-action@master
|
||||||
|
with:
|
||||||
|
base-image: ghcr.io/${{ github.repository }}:${{ env.MAJOR_TAG }}
|
||||||
|
extra-images: |
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.MAJOR_TAG }}-amd64,
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.MAJOR_TAG }}-arm64v8,
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.MAJOR_TAG }}-armv7,
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.MAJOR_TAG }}-i386
|
||||||
|
push: true
|
||||||
|
|
||||||
|
# Create and push manifest for :latest tag
|
||||||
|
- name: Create and push manifest (:latest)
|
||||||
|
uses: Noelware/docker-manifest-action@master
|
||||||
|
with:
|
||||||
|
base-image: ghcr.io/${{ github.repository }}:${{ env.LATEST_TAG }}
|
||||||
|
extra-images: |
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.LATEST_TAG }}-amd64,
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.LATEST_TAG }}-arm64v8,
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.LATEST_TAG }}-armv7,
|
||||||
|
ghcr.io/${{ github.repository }}:${{ env.LATEST_TAG }}-i386
|
||||||
|
push: true
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,3 +9,4 @@ debian/debhelper-build-stamp
|
|||||||
src/version.rs
|
src/version.rs
|
||||||
db_v2.sqlite3
|
db_v2.sqlite3
|
||||||
test.*
|
test.*
|
||||||
|
.idea
|
||||||
|
|||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -779,7 +779,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hbbs"
|
name = "hbbs"
|
||||||
version = "1.1.10-2"
|
version = "1.1.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-speed-limit",
|
"async-speed-limit",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "hbbs"
|
name = "hbbs"
|
||||||
version = "1.1.10-2"
|
version = "1.1.12"
|
||||||
authors = ["rustdesk <info@rustdesk.com>"]
|
authors = ["rustdesk <info@rustdesk.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<a href="#ein-schlüsselpaar-erstellen">Schlüsselpaar</a> •
|
<a href="#ein-schlüsselpaar-erstellen">Schlüsselpaar</a> •
|
||||||
<a href="#debian-pakete">Debian-Pakete</a> •
|
<a href="#debian-pakete">Debian-Pakete</a> •
|
||||||
<a href="#umgebungsvariablen">Umgebungsvariablen</a><br>
|
<a href="#umgebungsvariablen">Umgebungsvariablen</a><br>
|
||||||
[<a href="README.md">English</a>] | [<a href="README-NL.md">Nederlands</a>]<br>
|
[<a href="README.md">English</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-TW.md">繁體中文</a>] | [<a href="README-ZH.md">简体中文</a>]<br>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# RustDesk Server-Programm
|
# RustDesk Server-Programm
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<a href="#hoe-maak-je-een-key-paar">Key paar</a> •
|
<a href="#hoe-maak-je-een-key-paar">Key paar</a> •
|
||||||
<a href="#deb-pakketten">Debian pakketten</a> •
|
<a href="#deb-pakketten">Debian pakketten</a> •
|
||||||
<a href="#env-variabelen">ENV variabelen</a><br>
|
<a href="#env-variabelen">ENV variabelen</a><br>
|
||||||
[<a href="README.md">English</a>] | [<a href="README-DE.md">Deutsch</a>]<br>
|
[<a href="README.md">English</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-TW.md">繁體中文</a>] | [<a href="README-ZH.md">简体中文</a>]<br>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# RustDesk Server Programa
|
# RustDesk Server Programa
|
||||||
|
|||||||
347
README-TW.md
Normal file
347
README-TW.md
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="#如何自行建置">自行建置</a> •
|
||||||
|
<a href="#Docker-映像檔">Docker</a> •
|
||||||
|
<a href="#基於-S6-overlay-的映象檔">S6-overlay</a> •
|
||||||
|
<a href="#如何建立金鑰對">金鑰對</a> •
|
||||||
|
<a href="#deb-套件">Debian</a> •
|
||||||
|
<a href="#ENV-環境參數">環境參數</a><br>
|
||||||
|
[<a href="README.md">English</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-ZH.md">简体中文</a>]<br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# RustDesk Server Program
|
||||||
|
|
||||||
|
[](https://github.com/rustdesk/rustdesk-server/actions/workflows/build.yaml)
|
||||||
|
|
||||||
|
[**下載**](https://github.com/rustdesk/rustdesk-server/releases)
|
||||||
|
|
||||||
|
[**說明文件**](https://rustdesk.com/docs/zh-tw/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 發布時自動生成並發布。我們有兩種映像檔。
|
||||||
|
|
||||||
|
### Classic 映像檔
|
||||||
|
|
||||||
|
這些映像檔是基於 `ubuntu-20.04` 建置的,僅添加了兩個主要的執行檔(`hbbr` 和 `hbbs`)。它們可在 [Docker Hub](https://hub.docker.com/r/rustdesk/rustdesk-server/) 上取得,帶有以下tags:
|
||||||
|
|
||||||
|
| 架構 | 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 <relay-server-ip[:port]>
|
||||||
|
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 <relay-server-ip[:port]>
|
||||||
|
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 名稱)。如果您為 `hbbr` 使用的端口不是 **21117**,則必須使用 **可選** 的 `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)。 它們在以及這些 tags 在 [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` |
|
||||||
|
|
||||||
|
強烈建議您使用 `multiarch` 映象檔 可以選擇使用 `major version` 或 `latest` tags。
|
||||||
|
|
||||||
|
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 的 Secret 管理
|
||||||
|
|
||||||
|
您可以將金鑰對保存在 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 環境參數
|
||||||
|
|
||||||
|
可以使用這些 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為單位) |
|
||||||
348
README-ZH.md
Normal file
348
README-ZH.md
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="#如何自行构建">自行构建</a> •
|
||||||
|
<a href="#Docker-镜像">Docker</a> •
|
||||||
|
<a href="#基于-S6-overlay-的镜像">S6-overlay</a> •
|
||||||
|
<a href="#如何创建密钥">密钥</a> •
|
||||||
|
<a href="#deb-套件">Debian</a> •
|
||||||
|
<a href="#ENV-环境参数">环境参数</a><br>
|
||||||
|
[<a href="README.md">English</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-TW.md">繁体中文</a>]<br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# RustDesk Server Program
|
||||||
|
|
||||||
|
[](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 <relay-server-ip[:port]>
|
||||||
|
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 <relay-server-ip[:port]>
|
||||||
|
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为单位) |
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<a href="#how-to-create-a-keypair">Keypair</a> •
|
<a href="#how-to-create-a-keypair">Keypair</a> •
|
||||||
<a href="#deb-packages">Debian</a> •
|
<a href="#deb-packages">Debian</a> •
|
||||||
<a href="#env-variables">Variables</a><br>
|
<a href="#env-variables">Variables</a><br>
|
||||||
[<a href="README-DE.md">Deutsch</a>] | [<a href="README-NL.md">Nederlands</a>]<br>
|
[<a href="README-DE.md">Deutsch</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-TW.md">繁體中文</a>] | [<a href="README-ZH.md">简体中文</a>]<br>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# RustDesk Server Program
|
# RustDesk Server Program
|
||||||
@@ -114,6 +114,9 @@ Edit line 16 to point to your relay server (the one listening on port 21117). Yo
|
|||||||
|
|
||||||
(docker-compose credit goes to @lukebarone and @QuiGonLeong)
|
(docker-compose credit goes to @lukebarone and @QuiGonLeong)
|
||||||
|
|
||||||
|
|
||||||
|
> Note that here, the rustdesk/rustdesk-server:latest in China may be replaced with the latest version number on dockerhub, such as rustdesk-server:1.1.10-3. Otherwise, the old version may be pulled due to image acceleration.
|
||||||
|
|
||||||
## S6-overlay based images
|
## 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:
|
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:
|
||||||
@@ -341,7 +344,7 @@ You can specify the variables as usual or use an `.env` file.
|
|||||||
| KEY | hbbs/hbbr | if set force the use of a specific key, if set to **"_"** force the use of any key |
|
| 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) |
|
| LIMIT_SPEED | hbbr | speed limit (in Mb/s) |
|
||||||
| PORT | hbbs/hbbr | listening port (21116 for hbbs - 21117 for hbbr) |
|
| 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) |
|
| 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) |
|
| RUST_LOG | all | set debug level (error\|warn\|info\|debug\|trace) |
|
||||||
| SINGLE_BANDWIDTH | hbbr | max bandwidth for a single connection (in Mb/s) |
|
| SINGLE_BANDWIDTH | hbbr | max bandwidth for a single connection (in Mb/s) |
|
||||||
| TOTAL_BANDWIDTH | hbbr | max total bandwidth (in Mb/s) |
|
| TOTAL_BANDWIDTH | hbbr | max total bandwidth (in Mb/s) |
|
||||||
|
|||||||
BIN
db_v2.sqlite3
BIN
db_v2.sqlite3
Binary file not shown.
14
debian/changelog
vendored
14
debian/changelog
vendored
@@ -1,3 +1,17 @@
|
|||||||
|
rustdesk-server (1.1.12) UNRELEASED; urgency=medium
|
||||||
|
* WS real ip
|
||||||
|
* Bump s6-overlay to v3.2.0.0 and fix env warnings
|
||||||
|
|
||||||
|
rustdesk-server (1.1.11-1) UNRELEASED; urgency=medium
|
||||||
|
* set reuse port to make restart friendly
|
||||||
|
* revert hbbr `-k` to not ruin back-compatibility
|
||||||
|
|
||||||
|
rustdesk-server (1.1.11) UNRELEASED; urgency=medium
|
||||||
|
* change -k to default '-', so you need not to set -k any more
|
||||||
|
|
||||||
|
rustdesk-server (1.1.10-3) UNRELEASED; urgency=medium
|
||||||
|
* fix on -2
|
||||||
|
|
||||||
rustdesk-server (1.1.10-2) UNRELEASED; urgency=medium
|
rustdesk-server (1.1.10-2) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* fix hangup signal exit when run with nohup
|
* fix hangup signal exit when run with nohup
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
FROM busybox:stable
|
FROM busybox:stable
|
||||||
|
|
||||||
ARG S6_OVERLAY_VERSION=3.1.1.2
|
ARG S6_OVERLAY_VERSION=3.2.0.0
|
||||||
ARG S6_ARCH=x86_64
|
ARG S6_ARCH=x86_64
|
||||||
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp
|
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp
|
||||||
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz /tmp
|
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_ARCH}.tar.xz /tmp
|
||||||
@@ -12,8 +12,8 @@ RUN \
|
|||||||
|
|
||||||
COPY rootfs /
|
COPY rootfs /
|
||||||
|
|
||||||
ENV RELAY relay.example.com
|
ENV RELAY=relay.example.com
|
||||||
ENV ENCRYPTED_ONLY 0
|
ENV ENCRYPTED_ONLY=0
|
||||||
|
|
||||||
EXPOSE 21115 21116 21116/udp 21117 21118 21119
|
EXPOSE 21115 21116 21116/udp 21117 21118 21119
|
||||||
|
|
||||||
|
|||||||
@@ -62,10 +62,11 @@ fn new_socket(addr: std::net::SocketAddr, reuse: bool) -> Result<TcpSocket, std:
|
|||||||
std::net::SocketAddr::V6(..) => TcpSocket::new_v6()?,
|
std::net::SocketAddr::V6(..) => TcpSocket::new_v6()?,
|
||||||
};
|
};
|
||||||
if reuse {
|
if reuse {
|
||||||
// windows has no reuse_port, but it's reuse_address
|
// windows has no reuse_port, but its reuse_address
|
||||||
// almost equals to unix's reuse_port + reuse_address,
|
// almost equals to unix's reuse_port + reuse_address,
|
||||||
// though may introduce nondeterministic behavior
|
// though may introduce nondeterministic behavior.
|
||||||
#[cfg(unix)]
|
// illumos has no support for SO_REUSEPORT
|
||||||
|
#[cfg(all(unix, not(target_os = "illumos")))]
|
||||||
socket.set_reuseport(true)?;
|
socket.set_reuseport(true)?;
|
||||||
socket.set_reuseaddr(true)?;
|
socket.set_reuseaddr(true)?;
|
||||||
}
|
}
|
||||||
@@ -260,8 +261,17 @@ pub async fn new_listener<T: ToSocketAddrs>(addr: T, reuse: bool) -> ResultType<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn listen_any(port: u16) -> ResultType<TcpListener> {
|
pub async fn listen_any(port: u16, reuse: bool) -> ResultType<TcpListener> {
|
||||||
if let Ok(mut socket) = TcpSocket::new_v6() {
|
if let Ok(mut socket) = TcpSocket::new_v6() {
|
||||||
|
if reuse {
|
||||||
|
// windows has no reuse_port, but its reuse_address
|
||||||
|
// almost equals to unix's reuse_port + reuse_address,
|
||||||
|
// though may introduce nondeterministic behavior.
|
||||||
|
// illumos has no support for SO_REUSEPORT
|
||||||
|
#[cfg(all(unix, not(target_os = "illumos")))]
|
||||||
|
socket.set_reuseport(true).ok();
|
||||||
|
socket.set_reuseaddr(true).ok();
|
||||||
|
}
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
use std::os::unix::io::{FromRawFd, IntoRawFd};
|
use std::os::unix::io::{FromRawFd, IntoRawFd};
|
||||||
|
|||||||
@@ -20,10 +20,11 @@ fn new_socket(addr: SocketAddr, reuse: bool, buf_size: usize) -> Result<Socket,
|
|||||||
SocketAddr::V6(..) => Socket::new(Domain::ipv6(), Type::dgram(), None),
|
SocketAddr::V6(..) => Socket::new(Domain::ipv6(), Type::dgram(), None),
|
||||||
}?;
|
}?;
|
||||||
if reuse {
|
if reuse {
|
||||||
// windows has no reuse_port, but it's reuse_address
|
// windows has no reuse_port, but its reuse_address
|
||||||
// almost equals to unix's reuse_port + reuse_address,
|
// almost equals to unix's reuse_port + reuse_address,
|
||||||
// though may introduce nondeterministic behavior
|
// though may introduce nondeterministic behavior.
|
||||||
#[cfg(unix)]
|
// illumos has no support for SO_REUSEPORT
|
||||||
|
#[cfg(all(unix, not(target_os = "illumos")))]
|
||||||
socket.set_reuse_port(true)?;
|
socket.set_reuse_port(true)?;
|
||||||
socket.set_reuse_address(true)?;
|
socket.set_reuse_address(true)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#
|
#
|
||||||
# rustdesk_hbbs_enable (bool): Set to NO by default.
|
# rustdesk_hbbs_enable (bool): Set to NO by default.
|
||||||
# Set it to YES to enable rustdesk_hbbs.
|
# Set it to YES to enable rustdesk_hbbs.
|
||||||
|
# rustdesk_hbbs_ip (string): Set IP address/hostname of relay server to use
|
||||||
|
# Defaults to "127.0.0.1", please replace with your server hostname/IP.
|
||||||
# rustdesk_hbbs_args (string): Set extra arguments to pass to rustdesk_hbbs
|
# rustdesk_hbbs_args (string): Set extra arguments to pass to rustdesk_hbbs
|
||||||
# Default is "-r ${rustdesk_hbbs_ip} -k _".
|
# Default is "-r ${rustdesk_hbbs_ip} -k _".
|
||||||
# rustdesk_hbbs_user (string): Set user that rustdesk_hbbs will run under
|
# rustdesk_hbbs_user (string): Set user that rustdesk_hbbs will run under
|
||||||
|
|||||||
@@ -113,13 +113,18 @@ pub fn gen_sk(wait: u64) -> (String, Option<sign::SecretKey>) {
|
|||||||
if let Ok(mut file) = std::fs::File::open(sk_file) {
|
if let Ok(mut file) = std::fs::File::open(sk_file) {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
if file.read_to_string(&mut contents).is_ok() {
|
if file.read_to_string(&mut contents).is_ok() {
|
||||||
let sk = base64::decode(&contents).unwrap_or_default();
|
let contents = contents.trim();
|
||||||
|
let sk = base64::decode(contents).unwrap_or_default();
|
||||||
if sk.len() == sign::SECRETKEYBYTES {
|
if sk.len() == sign::SECRETKEYBYTES {
|
||||||
let mut tmp = [0u8; sign::SECRETKEYBYTES];
|
let mut tmp = [0u8; sign::SECRETKEYBYTES];
|
||||||
tmp[..].copy_from_slice(&sk);
|
tmp[..].copy_from_slice(&sk);
|
||||||
let pk = base64::encode(&tmp[sign::SECRETKEYBYTES / 2..]);
|
let pk = base64::encode(&tmp[sign::SECRETKEYBYTES / 2..]);
|
||||||
log::info!("Private key comes from {}", sk_file);
|
log::info!("Private key comes from {}", sk_file);
|
||||||
return (pk, Some(sign::SecretKey(tmp)));
|
return (pk, Some(sign::SecretKey(tmp)));
|
||||||
|
} else {
|
||||||
|
// don't use log here, since it is async
|
||||||
|
println!("Fatal error: malformed private key in {sk_file}.");
|
||||||
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ fn main() -> ResultType<()> {
|
|||||||
"-c --config=[FILE] +takes_value 'Sets a custom config file'
|
"-c --config=[FILE] +takes_value 'Sets a custom config file'
|
||||||
-p, --port=[NUMBER(default={RENDEZVOUS_PORT})] 'Sets the listening port'
|
-p, --port=[NUMBER(default={RENDEZVOUS_PORT})] 'Sets the listening port'
|
||||||
-s, --serial=[NUMBER(default=0)] 'Sets configure update serial number'
|
-s, --serial=[NUMBER(default=0)] 'Sets configure update serial number'
|
||||||
-R, --rendezvous-servers=[HOSTS] 'Sets rendezvous servers, seperated by colon'
|
-R, --rendezvous-servers=[HOSTS] 'Sets rendezvous servers, separated by comma'
|
||||||
-u, --software-url=[URL] 'Sets download url of RustDesk software of newest version'
|
-u, --software-url=[URL] 'Sets download url of RustDesk software of newest version'
|
||||||
-r, --relay-servers=[HOST] 'Sets the default relay servers, seperated by colon'
|
-r, --relay-servers=[HOST] 'Sets the default relay servers, separated by comma'
|
||||||
-M, --rmem=[NUMBER(default={RMEM})] 'Sets UDP recv buffer size, set system rmem_max first, e.g., sudo sysctl -w net.core.rmem_max=52428800. vi /etc/sysctl.conf, net.core.rmem_max=52428800, sudo sysctl –p'
|
-M, --rmem=[NUMBER(default={RMEM})] 'Sets UDP recv buffer size, set system rmem_max first, e.g., sudo sysctl -w net.core.rmem_max=52428800. vi /etc/sysctl.conf, net.core.rmem_max=52428800, sudo sysctl –p'
|
||||||
, --mask=[MASK] 'Determine if the connection comes from LAN, e.g. 192.168.0.0/16'
|
, --mask=[MASK] 'Determine if the connection comes from LAN, e.g. 192.168.0.0/16'
|
||||||
-k, --key=[KEY] 'Only allow the client with the same key'",
|
-k, --key=[KEY] 'Only allow the client with the same key'",
|
||||||
@@ -31,6 +31,6 @@ fn main() -> ResultType<()> {
|
|||||||
}
|
}
|
||||||
let rmem = get_arg("rmem").parse::<usize>().unwrap_or(RMEM);
|
let rmem = get_arg("rmem").parse::<usize>().unwrap_or(RMEM);
|
||||||
let serial: i32 = get_arg("serial").parse().unwrap_or(0);
|
let serial: i32 = get_arg("serial").parse().unwrap_or(0);
|
||||||
RendezvousServer::start(port, serial, &get_arg("key"), rmem)?;
|
RendezvousServer::start(port, serial, &get_arg_or("key", "-".to_owned()), rmem)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ pub async fn start(port: &str, key: &str) -> ResultType<()> {
|
|||||||
let main_task = async move {
|
let main_task = async move {
|
||||||
loop {
|
loop {
|
||||||
log::info!("Start");
|
log::info!("Start");
|
||||||
io_loop(listen_any(port).await?, listen_any(port2).await?, &key).await;
|
io_loop(listen_any(port, true).await?, listen_any(port2, true).await?, &key).await;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let listen_signal = crate::common::listen_signal();
|
let listen_signal = crate::common::listen_signal();
|
||||||
@@ -392,19 +392,30 @@ async fn handle_connection(
|
|||||||
|
|
||||||
async fn make_pair(
|
async fn make_pair(
|
||||||
stream: TcpStream,
|
stream: TcpStream,
|
||||||
addr: SocketAddr,
|
mut addr: SocketAddr,
|
||||||
key: &str,
|
key: &str,
|
||||||
limiter: Limiter,
|
limiter: Limiter,
|
||||||
ws: bool,
|
ws: bool,
|
||||||
) -> ResultType<()> {
|
) -> ResultType<()> {
|
||||||
if ws {
|
if ws {
|
||||||
make_pair_(
|
use tokio_tungstenite::tungstenite::handshake::server::{Request, Response};
|
||||||
tokio_tungstenite::accept_async(stream).await?,
|
let callback = |req: &Request, response: Response| {
|
||||||
addr,
|
let headers = req.headers();
|
||||||
key,
|
let real_ip = headers
|
||||||
limiter,
|
.get("X-Real-IP")
|
||||||
)
|
.or_else(|| headers.get("X-Forwarded-For"))
|
||||||
.await;
|
.and_then(|header_value| header_value.to_str().ok());
|
||||||
|
if let Some(ip) = real_ip {
|
||||||
|
if ip.contains('.') {
|
||||||
|
addr = format!("{ip}:0").parse().unwrap_or(addr);
|
||||||
|
} else {
|
||||||
|
addr = format!("[{ip}]:0").parse().unwrap_or(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(response)
|
||||||
|
};
|
||||||
|
let ws_stream = tokio_tungstenite::accept_hdr_async(stream, callback).await?;
|
||||||
|
make_pair_(ws_stream, addr, key, limiter).await;
|
||||||
} else {
|
} else {
|
||||||
make_pair_(FramedStream::from(stream, addr), addr, key, limiter).await;
|
make_pair_(FramedStream::from(stream, addr), addr, key, limiter).await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1106,13 +1106,29 @@ impl RendezvousServer {
|
|||||||
async fn handle_listener_inner(
|
async fn handle_listener_inner(
|
||||||
&mut self,
|
&mut self,
|
||||||
stream: TcpStream,
|
stream: TcpStream,
|
||||||
addr: SocketAddr,
|
mut addr: SocketAddr,
|
||||||
key: &str,
|
key: &str,
|
||||||
ws: bool,
|
ws: bool,
|
||||||
) -> ResultType<()> {
|
) -> ResultType<()> {
|
||||||
let mut sink;
|
let mut sink;
|
||||||
if ws {
|
if ws {
|
||||||
let ws_stream = tokio_tungstenite::accept_async(stream).await?;
|
use tokio_tungstenite::tungstenite::handshake::server::{Request, Response};
|
||||||
|
let callback = |req: &Request, response: Response| {
|
||||||
|
let headers = req.headers();
|
||||||
|
let real_ip = headers
|
||||||
|
.get("X-Real-IP")
|
||||||
|
.or_else(|| headers.get("X-Forwarded-For"))
|
||||||
|
.and_then(|header_value| header_value.to_str().ok());
|
||||||
|
if let Some(ip) = real_ip {
|
||||||
|
if ip.contains('.') {
|
||||||
|
addr = format!("{ip}:0").parse().unwrap_or(addr);
|
||||||
|
} else {
|
||||||
|
addr = format!("[{ip}]:0").parse().unwrap_or(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(response)
|
||||||
|
};
|
||||||
|
let ws_stream = tokio_tungstenite::accept_hdr_async(stream, callback).await?;
|
||||||
let (a, mut b) = ws_stream.split();
|
let (a, mut b) = ws_stream.split();
|
||||||
sink = Some(Sink::Ws(a));
|
sink = Some(Sink::Ws(a));
|
||||||
while let Ok(Some(Ok(msg))) = timeout(30_000, b.next()).await {
|
while let Ok(Some(Ok(msg))) = timeout(30_000, b.next()).await {
|
||||||
@@ -1174,9 +1190,6 @@ impl RendezvousServer {
|
|||||||
let mut tmp = [0u8; sign::SECRETKEYBYTES];
|
let mut tmp = [0u8; sign::SECRETKEYBYTES];
|
||||||
tmp[..].copy_from_slice(&sk);
|
tmp[..].copy_from_slice(&sk);
|
||||||
out_sk = Some(sign::SecretKey(tmp));
|
out_sk = Some(sign::SecretKey(tmp));
|
||||||
} else {
|
|
||||||
log::error!("Malformed private key");
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1185,14 +1198,11 @@ impl RendezvousServer {
|
|||||||
out_sk = sk;
|
out_sk = sk;
|
||||||
if !key.is_empty() {
|
if !key.is_empty() {
|
||||||
key = pk;
|
key = pk;
|
||||||
} else {
|
|
||||||
std::env::set_var("KEY_FOR_API", pk);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !key.is_empty() {
|
if !key.is_empty() {
|
||||||
log::info!("Key: {}", key);
|
log::info!("Key: {}", key);
|
||||||
std::env::set_var("KEY_FOR_API", key.clone());
|
|
||||||
}
|
}
|
||||||
(key, out_sk)
|
(key, out_sk)
|
||||||
}
|
}
|
||||||
@@ -1297,19 +1307,19 @@ async fn send_rk_res(
|
|||||||
|
|
||||||
async fn create_udp_listener(port: i32, rmem: usize) -> ResultType<FramedSocket> {
|
async fn create_udp_listener(port: i32, rmem: usize) -> ResultType<FramedSocket> {
|
||||||
let addr = SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port as _);
|
let addr = SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port as _);
|
||||||
if let Ok(s) = FramedSocket::new_reuse(&addr, false, rmem).await {
|
if let Ok(s) = FramedSocket::new_reuse(&addr, true, rmem).await {
|
||||||
log::debug!("listen on udp {:?}", s.local_addr());
|
log::debug!("listen on udp {:?}", s.local_addr());
|
||||||
return Ok(s);
|
return Ok(s);
|
||||||
}
|
}
|
||||||
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), port as _);
|
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), port as _);
|
||||||
let s = FramedSocket::new_reuse(&addr, false, rmem).await?;
|
let s = FramedSocket::new_reuse(&addr, true, rmem).await?;
|
||||||
log::debug!("listen on udp {:?}", s.local_addr());
|
log::debug!("listen on udp {:?}", s.local_addr());
|
||||||
Ok(s)
|
Ok(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
async fn create_tcp_listener(port: i32) -> ResultType<TcpListener> {
|
async fn create_tcp_listener(port: i32) -> ResultType<TcpListener> {
|
||||||
let s = listen_any(port as _).await?;
|
let s = listen_any(port as _, true).await?;
|
||||||
log::debug!("listen on tcp {:?}", s.local_addr());
|
log::debug!("listen on tcp {:?}", s.local_addr());
|
||||||
Ok(s)
|
Ok(s)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
!define PRODUCT_NAME "rustdesk_server"
|
!define PRODUCT_NAME "rustdesk_server"
|
||||||
!define PRODUCT_DESCRIPTION "Installer for ${PRODUCT_NAME}"
|
!define PRODUCT_DESCRIPTION "Installer for ${PRODUCT_NAME}"
|
||||||
!define COPYRIGHT "Copyright © 2021"
|
!define COPYRIGHT "Copyright © 2021"
|
||||||
!define VERSION "1.1.10"
|
!define VERSION "1.1.12"
|
||||||
|
|
||||||
VIProductVersion "${VERSION}.0"
|
VIProductVersion "${VERSION}.0"
|
||||||
VIAddVersionKey "ProductName" "${PRODUCT_NAME}"
|
VIAddVersionKey "ProductName" "${PRODUCT_NAME}"
|
||||||
|
|||||||
Reference in New Issue
Block a user