feat: add RustDesk Server scripts (hbbs+hbbr native, systemd, UFW)

- install-rustdesk-server.sh: download & install hbbs/hbbr from GitHub releases
- rustdesk-hbbs.service: systemd unit for ID-server (ports 21115-21116)
- rustdesk-hbbr.service: systemd unit for relay (port 21117)
- open-rustdesk-ports.sh: idempotent UFW port opening
- README.md: deployment instructions

Generated by orchestrator in APAW worktree, applied to VPS 2.59.219.61
This commit is contained in:
Orchestrator
2026-05-15 23:50:39 +01:00
parent 554aa6008d
commit 3f49556cd7
5 changed files with 236 additions and 0 deletions

56
scripts/README.md Normal file
View File

@@ -0,0 +1,56 @@
# RustDesk Server — Нативная установка на VPS
## Файлы
| Файл | Назначение |
|------|------------|
| `install-rustdesk-server.sh` | Скачивает и устанавливает hbbs + hbbr |
| `rustdesk-hbbs.service` | systemd unit для ID-сервера |
| `rustdesk-hbbr.service` | systemd unit для relay |
| `open-rustdesk-ports.sh` | Открывает порты в UFW |
## Быстрый старт
```bash
# 1. Скопируй файлы на VPS
scp install-rustdesk-server.sh \
rustdesk-hbbs.service \
rustdesk-hbbr.service \
open-rustdesk-ports.sh \
root@2.59.219.61:/root/
# 2. Зайди на VPS
ssh root@2.59.219.61
# 3. Запусти
chmod +x install-rustdesk-server.sh open-rustdesk-ports.sh
./open-rustdesk-ports.sh
./install-rustdesk-server.sh
```
## Порты
| Порт | Протокол | Назначение |
|------|----------|------------|
| 21115 | TCP | NAT type detection |
| 21116 | TCP + UDP | ID registration / hole punching |
| 21117 | TCP | Relay |
| 21118 | TCP | Web console (опционально) |
| 21119 | TCP | Web console HTTPS (опционально) |
## Проверка
```bash
systemctl status rustdesk-hbbs rustdesk-hbbr
ss -tlnp | grep -E '21115|21116|21117'
journalctl -u rustdesk-hbbs -f
cat /var/lib/rustdesk-server/id_ed25519.pub
```
## Настройка клиента
1. Открой RustDesk на VPS
2. Нажми «Настройки сети» → «ID-сервер»
3. Вставь IP VPS и порт: `2.59.219.61:21116`
4. Вставь ключ из `/var/lib/rustdesk-server/id_ed25519.pub`
5. Готово — ID теперь локальный и постоянный

View File

@@ -0,0 +1,95 @@
#!/usr/bin/env bash
set -euo pipefail
# RustDesk Server Native Installer (hbbs + hbbr)
# Debian 12 / x86_64 / static musl binaries from GitHub releases
# Idempotent
VERSION="1.1.15"
ARCH="amd64"
ZIP_URL="https://github.com/rustdesk/rustdesk-server/releases/download/${VERSION}/rustdesk-server-linux-${ARCH}.zip"
INSTALL_DIR="/usr/local/bin"
DATA_DIR="/var/lib/rustdesk-server"
CONFIG_DIR="/etc/rustdesk-server"
SERVICE_DIR="/etc/systemd/system"
TMP_DIR=$(mktemp -d)
trap 'rm -rf "$TMP_DIR"' EXIT
log() {
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')] $*"
}
need_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
log "Installing: $1"
apt-get update -qq
apt-get install -y -qq "$1"
fi
}
log "=== RustDesk Server Install ==="
log "Version: $VERSION"
log "Arch: $ARCH"
need_cmd curl
need_cmd unzip
log "Downloading release $VERSION..."
curl -fsSL -o "$TMP_DIR/rustdesk-server.zip" "$ZIP_URL"
log "Extracting..."
unzip -q -o "$TMP_DIR/rustdesk-server.zip" -d "$TMP_DIR"
log "Installing binaries to $INSTALL_DIR..."
install -m 755 "$TMP_DIR/$ARCH/hbbs" "$INSTALL_DIR/hbbs"
install -m 755 "$TMP_DIR/$ARCH/hbbr" "$INSTALL_DIR/hbbr"
install -m 755 "$TMP_DIR/$ARCH/rustdesk-utils" "$INSTALL_DIR/rustdesk-utils"
log "Creating directories..."
mkdir -p "$DATA_DIR" "$CONFIG_DIR"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for service in rustdesk-hbbs.service rustdesk-hbbr.service; do
src="$SCRIPT_DIR/$service"
dst="$SERVICE_DIR/$service"
if [ -f "$src" ]; then
cp -f "$src" "$dst"
chmod 644 "$dst"
log "Installed: $dst"
else
log "WARNING: $src not found — ensure systemd unit files are in the same directory."
fi
done
log "Reloading systemd..."
systemctl daemon-reload
log "Enabling services..."
systemctl enable rustdesk-hbbs.service || true
systemctl enable rustdesk-hbbr.service || true
log "Starting services..."
systemctl restart rustdesk-hbbs.service || true
systemctl restart rustdesk-hbbr.service || true
sleep 2
log "=== Status ==="
systemctl status rustdesk-hbbs.service --no-pager || true
systemctl status rustdesk-hbbr.service --no-pager || true
PUB_KEY="$DATA_DIR/id_ed25519.pub"
if [ -f "$PUB_KEY" ]; then
log "=== Server Public Key ==="
cat "$PUB_KEY"
else
log "Public key not found yet. It will be generated on first successful hbbs start."
fi
log "=== Listening Ports ==="
ss -tlnp | grep -E '21115|21116|21117' || true
log "=== Done ==="

39
scripts/open-rustdesk-ports.sh Executable file
View File

@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail
log() {
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')] $*"
}
if ! command -v ufw >/dev/null 2>&1; then
log "UFW not installed. Installing..."
apt-get update -qq
apt-get install -y -qq ufw
fi
UFW_STATUS=$(ufw status numbered 2>/dev/null || true)
open_port() {
local port=$1
local proto=${2:-tcp}
local rule="$port/$proto"
if echo "$UFW_STATUS" | grep -q "$rule"; then
log "Already open: $rule"
else
log "Opening: $rule"
ufw allow "$rule"
fi
}
log "=== Opening RustDesk Server ports ==="
open_port 21115 tcp
open_port 21116 tcp
open_port 21116 udp
open_port 21117 tcp
open_port 21118 tcp
open_port 21119 tcp
log "=== UFW status ==="
ufw status verbose
log "=== Done ==="

View File

@@ -0,0 +1,23 @@
[Unit]
Description=RustDesk Server (hbbr — relay)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/hbbr
WorkingDirectory=/var/lib/rustdesk-server
Restart=on-failure
RestartSec=5s
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/rustdesk-server
StandardOutput=journal
StandardError=journal
SyslogIdentifier=rustdesk-hbbr
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,23 @@
[Unit]
Description=RustDesk Server (hbbs — ID / NAT relay)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/hbbs
WorkingDirectory=/var/lib/rustdesk-server
Restart=on-failure
RestartSec=5s
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/rustdesk-server
StandardOutput=journal
StandardError=journal
SyslogIdentifier=rustdesk-hbbs
[Install]
WantedBy=multi-user.target