6 Commits

Author SHA1 Message Date
rustdesk
6f18a97644 v1.1.12 2024-10-07 16:21:36 +08:00
XLion
3b386b6b54 feat: Publish container images to GitHub ghcr.io (#473)
* ghcr

* fix name

* ghcr

* ghcr

* ghcr

* ghcr

* ghcr

* ghcr update action

* ghcr update action

* ghcr update action

* ghcr update action

* ghcr update action

* ghcr update action

* ghcr classic

* ghcr classic

* ghcr: better naming and tidy up

* ghcr classic fix chmod

* tidy up

* tidy up

* if-no-files-found: error
2024-09-30 08:46:35 +08:00
Fionera
b37033d92c docs: the servers are by comma instead of colon (#462) 2024-09-28 23:34:47 +08:00
XLion
b7bab80bfe Bump S6 overlay and fix env warnings (#472) 2024-09-28 23:33:47 +08:00
Dominik Hassler
041a603173 add illumos support (#433) 2024-06-29 22:25:47 +08:00
rustdesk
e40994d62e remove useless KEY_FOR_API 2024-05-26 21:43:13 +08:00
11 changed files with 390 additions and 30 deletions

329
.github/workflows/ghcr.yml vendored Normal file
View 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

2
Cargo.lock generated
View File

@@ -779,7 +779,7 @@ dependencies = [
[[package]]
name = "hbbs"
version = "1.1.11-1"
version = "1.1.12"
dependencies = [
"async-speed-limit",
"async-trait",

View File

@@ -1,6 +1,6 @@
[package]
name = "hbbs"
version = "1.1.11-1"
version = "1.1.12"
authors = ["rustdesk <info@rustdesk.com>"]
edition = "2021"
build = "build.rs"

4
debian/changelog vendored
View File

@@ -1,3 +1,7 @@
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

View File

@@ -1,6 +1,6 @@
FROM busybox:stable
ARG S6_OVERLAY_VERSION=3.1.1.2
ARG S6_OVERLAY_VERSION=3.2.0.0
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-${S6_ARCH}.tar.xz /tmp
@@ -12,8 +12,8 @@ RUN \
COPY rootfs /
ENV RELAY relay.example.com
ENV ENCRYPTED_ONLY 0
ENV RELAY=relay.example.com
ENV ENCRYPTED_ONLY=0
EXPOSE 21115 21116 21116/udp 21117 21118 21119

View File

@@ -62,10 +62,11 @@ fn new_socket(addr: std::net::SocketAddr, reuse: bool) -> Result<TcpSocket, std:
std::net::SocketAddr::V6(..) => TcpSocket::new_v6()?,
};
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,
// though may introduce nondeterministic behavior
#[cfg(unix)]
// though may introduce nondeterministic behavior.
// illumos has no support for SO_REUSEPORT
#[cfg(all(unix, not(target_os = "illumos")))]
socket.set_reuseport(true)?;
socket.set_reuseaddr(true)?;
}
@@ -263,10 +264,11 @@ pub async fn new_listener<T: ToSocketAddrs>(addr: T, reuse: bool) -> ResultType<
pub async fn listen_any(port: u16, reuse: bool) -> ResultType<TcpListener> {
if let Ok(mut socket) = TcpSocket::new_v6() {
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,
// though may introduce nondeterministic behavior
#[cfg(unix)]
// 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();
}

View File

@@ -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),
}?;
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,
// though may introduce nondeterministic behavior
#[cfg(unix)]
// though may introduce nondeterministic behavior.
// illumos has no support for SO_REUSEPORT
#[cfg(all(unix, not(target_os = "illumos")))]
socket.set_reuse_port(true)?;
socket.set_reuse_address(true)?;
}

View File

@@ -17,9 +17,9 @@ fn main() -> ResultType<()> {
"-c --config=[FILE] +takes_value 'Sets a custom config file'
-p, --port=[NUMBER(default={RENDEZVOUS_PORT})] 'Sets the listening port'
-s, --serial=[NUMBER(default=0)] 'Sets configure update serial number'
-R, --rendezvous-servers=[HOSTS] 'Sets rendezvous servers, separated 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'
-r, --relay-servers=[HOST] 'Sets the default relay servers, separated 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'
, --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'",

View File

@@ -392,19 +392,30 @@ async fn handle_connection(
async fn make_pair(
stream: TcpStream,
addr: SocketAddr,
mut addr: SocketAddr,
key: &str,
limiter: Limiter,
ws: bool,
) -> ResultType<()> {
if ws {
make_pair_(
tokio_tungstenite::accept_async(stream).await?,
addr,
key,
limiter,
)
.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?;
make_pair_(ws_stream, addr, key, limiter).await;
} else {
make_pair_(FramedStream::from(stream, addr), addr, key, limiter).await;
}

View File

@@ -1106,13 +1106,29 @@ impl RendezvousServer {
async fn handle_listener_inner(
&mut self,
stream: TcpStream,
addr: SocketAddr,
mut addr: SocketAddr,
key: &str,
ws: bool,
) -> ResultType<()> {
let mut sink;
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();
sink = Some(Sink::Ws(a));
while let Ok(Some(Ok(msg))) = timeout(30_000, b.next()).await {
@@ -1182,14 +1198,11 @@ impl RendezvousServer {
out_sk = sk;
if !key.is_empty() {
key = pk;
} else {
std::env::set_var("KEY_FOR_API", pk);
}
}
if !key.is_empty() {
log::info!("Key: {}", key);
std::env::set_var("KEY_FOR_API", key.clone());
}
(key, out_sk)
}

View File

@@ -15,7 +15,7 @@
!define PRODUCT_NAME "rustdesk_server"
!define PRODUCT_DESCRIPTION "Installer for ${PRODUCT_NAME}"
!define COPYRIGHT "Copyright © 2021"
!define VERSION "1.1.10"
!define VERSION "1.1.12"
VIProductVersion "${VERSION}.0"
VIAddVersionKey "ProductName" "${PRODUCT_NAME}"