- install.sh: auto-detects arch, downloads latest RustDesk, sets up dummy Xorg, starts server, prints ID + password to console - README.md: rewritten as universal installer guide - Supports: x86_64, aarch64, armv7l - Works on: Intel iGPU, AMD, NVIDIA, CPU-only, VPS vps-rustdesk-server branch contains archived VPS relay solution
240 lines
7.4 KiB
Bash
Executable File
240 lines
7.4 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
#######################################
|
|
# RDtop — One-Command RustDesk Headless Installer
|
|
# Works on any Linux (Intel iGPU, AMD, NVIDIA, CPU-only, VPS)
|
|
# Usage: curl -fsSL https://git.softuniq.eu/NW/RDtop/raw/branch/main/install.sh | sudo bash
|
|
#######################################
|
|
|
|
ARCH=$(uname -m)
|
|
case "$ARCH" in
|
|
x86_64) RUSTDESK_ARCH="x86_64"; DEB_ARCH="amd64" ;;
|
|
aarch64) RUSTDESK_ARCH="aarch64"; DEB_ARCH="arm64" ;;
|
|
armv7l) RUSTDESK_ARCH="armv7"; DEB_ARCH="armhf" ;;
|
|
*) echo "ERROR: Unsupported architecture: $ARCH"; exit 1 ;;
|
|
esac
|
|
|
|
RUSTDESK_VERSION="1.4.6"
|
|
RUSTDESK_URL="https://github.com/rustdesk/rustdesk/releases/download/${RUSTDESK_VERSION}/rustdesk-${RUSTDESK_VERSION}-${RUSTDESK_ARCH}.deb"
|
|
TMP_DEB="/tmp/rustdesk-${RUSTDESK_VERSION}-${DEB_ARCH}.deb"
|
|
LOG="/tmp/rdtop-install.log"
|
|
|
|
log() { echo "[$(date '+%F %T')] $1" | tee -a "$LOG"; }
|
|
|
|
echo ""
|
|
echo "============================================"
|
|
echo " RDtop — RustDesk Headless Installer"
|
|
echo " Arch: $ARCH | Package: ${RUSTDESK_ARCH}.deb"
|
|
echo "============================================"
|
|
echo ""
|
|
|
|
# --- 1. Install dependencies ---
|
|
log "[1/6] Installing dependencies..."
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get update -qq >/dev/null 2>&1 || true
|
|
apt-get install -y -qq curl wget xserver-xorg-core xserver-xorg-video-dummy >/dev/null 2>&1 || true
|
|
apt-get install -y -qq libva2 libvdpau1 >/dev/null 2>&1 || true
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
dnf install -y curl wget xorg-x11-server-Xorg xorg-x11-drv-dummy >/dev/null 2>&1 || true
|
|
elif command -v pacman >/dev/null 2>&1; then
|
|
pacman -Sy --noconfirm curl wget xorg-server xf86-video-dummy >/dev/null 2>&1 || true
|
|
else
|
|
log "WARNING: Unknown package manager. Trying to continue..."
|
|
fi
|
|
|
|
# --- 2. Detect display environment ---
|
|
log "[2/6] Detecting display environment..."
|
|
HAS_DISPLAY=false
|
|
HAS_XORG=false
|
|
|
|
if [ -n "${DISPLAY:-}" ] && xdpyinfo >/dev/null 2>&1; then
|
|
HAS_DISPLAY=true
|
|
log " Active display detected: $DISPLAY"
|
|
fi
|
|
|
|
if pgrep -x "Xorg" >/dev/null 2>&1 || pgrep -x "X" >/dev/null 2>&1; then
|
|
HAS_XORG=true
|
|
log " Xorg already running"
|
|
fi
|
|
|
|
# --- 3. Setup dummy driver if headless ---
|
|
log "[3/6] Setting up dummy driver..."
|
|
mkdir -p /etc/X11/xorg.conf.d/
|
|
|
|
# Remove conflicting configs
|
|
rm -f /etc/X11/xorg.conf.d/20-intel-virtual.conf 2>/dev/null || true
|
|
rm -f /etc/X11/xorg.conf.d/90-fallback.conf 2>/dev/null || true
|
|
|
|
# Create dummy config (works for both host and VPS)
|
|
cat > /etc/X11/xorg.conf.d/20-dummy-headless.conf <<'XORG'
|
|
Section "Device"
|
|
Identifier "DummyHeadless"
|
|
Driver "dummy"
|
|
VideoRam 256000
|
|
EndSection
|
|
|
|
Section "Monitor"
|
|
Identifier "DummyMonitor"
|
|
HorizSync 28-80
|
|
VertRefresh 48-75
|
|
EndSection
|
|
|
|
Section "Screen"
|
|
Identifier "DummyScreen"
|
|
Device "DummyHeadless"
|
|
Monitor "DummyMonitor"
|
|
DefaultDepth 24
|
|
SubSection "Display"
|
|
Depth 24
|
|
Modes "1920x1080" "1280x720"
|
|
EndSubSection
|
|
EndSection
|
|
XORG
|
|
chmod 644 /etc/X11/xorg.conf.d/20-dummy-headless.conf
|
|
|
|
# --- 4. Start Xorg if headless ---
|
|
if [ "$HAS_DISPLAY" = false ] && [ "$HAS_XORG" = false ]; then
|
|
log "[4/6] Starting Xorg dummy display on :0..."
|
|
# Ensure no stale locks
|
|
rm -f /tmp/.X11-unix/X0 /tmp/.X0-lock 2>/dev/null || true
|
|
mkdir -p /tmp/.X11-unix
|
|
chmod 1777 /tmp/.X11-unix
|
|
|
|
# Start Xorg with dummy config
|
|
if [ "$EUID" -eq 0 ]; then
|
|
nohup Xorg :0 -config /etc/X11/xorg.conf.d/20-dummy-headless.conf -nolisten tcp >/tmp/xorg-dummy.log 2>&1 &
|
|
else
|
|
log " WARNING: Not root, trying xvfb-run fallback..."
|
|
apt-get install -y -qq xvfb >/dev/null 2>&1 || true
|
|
fi
|
|
sleep 3
|
|
|
|
# Verify
|
|
if [ -S /tmp/.X11-unix/X0 ]; then
|
|
log " Xorg dummy display :0 created"
|
|
else
|
|
log " WARNING: Xorg socket not found, trying Xvfb..."
|
|
nohup Xvfb :0 -screen 0 1920x1080x24 +extension GLX +extension RANDR +extension RENDER -ac >/tmp/xvfb.log 2>&1 &
|
|
sleep 2
|
|
fi
|
|
|
|
# Setup xauth for root
|
|
if [ "$EUID" -eq 0 ]; then
|
|
xauth -f /root/.Xauthority add :0 . $(mcookie) 2>/dev/null || true
|
|
chmod 600 /root/.Xauthority 2>/dev/null || true
|
|
fi
|
|
else
|
|
log "[4/6] Existing display detected, skipping Xorg startup"
|
|
fi
|
|
|
|
export DISPLAY=:0
|
|
export XAUTHORITY="${XAUTHORITY:-/root/.Xauthority}"
|
|
|
|
# --- 5. Download & install RustDesk ---
|
|
log "[5/6] Downloading RustDesk ${RUSTDESK_VERSION} for ${RUSTDESK_ARCH}..."
|
|
|
|
if command -v curl >/dev/null 2>&1; then
|
|
curl -fsSL -o "$TMP_DEB" "$RUSTDESK_URL" 2>&1 || true
|
|
elif command -v wget >/dev/null 2>&1; then
|
|
wget -q -O "$TMP_DEB" "$RUSTDESK_URL" 2>&1 || true
|
|
fi
|
|
|
|
if [ ! -f "$TMP_DEB" ] || [ ! -s "$TMP_DEB" ]; then
|
|
log "ERROR: Failed to download RustDesk .deb"
|
|
log "URL: $RUSTDESK_URL"
|
|
log "Trying to install from repository..."
|
|
apt-get install -y -qq rustdesk 2>/dev/null || true
|
|
fi
|
|
|
|
if [ -f "$TMP_DEB" ] && [ -s "$TMP_DEB" ]; then
|
|
log " Installing from downloaded .deb..."
|
|
dpkg -i "$TMP_DEB" >/dev/null 2>&1 || apt-get install -f -y -qq >/dev/null 2>&1 || true
|
|
rm -f "$TMP_DEB"
|
|
fi
|
|
|
|
# Verify installation
|
|
if [ ! -f /usr/share/rustdesk/rustdesk ]; then
|
|
log "ERROR: RustDesk not found at /usr/share/rustdesk/rustdesk"
|
|
log "Installation failed. Check /tmp/rdtop-install.log"
|
|
exit 1
|
|
fi
|
|
|
|
# --- 6. Start RustDesk & output credentials ---
|
|
log "[6/6] Starting RustDesk server..."
|
|
|
|
# Create config dir
|
|
mkdir -p ~/.config/rustdesk
|
|
|
|
# Write initial config with public rendezvous (for stable ID)
|
|
cat > ~/.config/rustdesk/RustDesk2.toml <<'EOF'
|
|
rendezvous_server = 'rs-ny.rustdesk.com:21116'
|
|
nat_type = 1
|
|
serial = 0
|
|
unlock_pin = ''
|
|
|
|
[options]
|
|
local-ip-addr = 'auto'
|
|
EOF
|
|
chmod 600 ~/.config/rustdesk/RustDesk2.toml
|
|
|
|
# Start server
|
|
pkill -f "/usr/share/rustdesk/rustdesk" 2>/dev/null || true
|
|
sleep 1
|
|
|
|
export DISPLAY=:0
|
|
export XAUTHORITY=/root/.Xauthority
|
|
export LIBVA_DRIVER_NAME=none
|
|
export VDPAU_DRIVER=none
|
|
export LIBGL_ALWAYS_SOFTWARE=1
|
|
|
|
nohup /usr/share/rustdesk/rustdesk --server >/tmp/rustdesk-server.log 2>&1 &
|
|
sleep 5
|
|
|
|
# Get credentials
|
|
RUSTDESK_ID=$(/usr/share/rustdesk/rustdesk --get-id 2>/dev/null || echo "N/A")
|
|
|
|
# Read or set password
|
|
RUSTDESK_PASS=""
|
|
if [ -f ~/.config/rustdesk/RustDesk.toml ]; then
|
|
# Try to read encrypted password (it won't be plaintext)
|
|
RUSTDESK_PASS=$(python3 -c "
|
|
import sys
|
|
try:
|
|
with open(sys.argv[1]) as f:
|
|
for line in f:
|
|
if 'password' in line and '=' in line:
|
|
parts = line.split('=')
|
|
if len(parts) > 1:
|
|
print(parts[1].strip().strip(\"'\"))
|
|
break
|
|
except: pass
|
|
" ~/.config/rustdesk/RustDesk.toml 2>/dev/null || true)
|
|
fi
|
|
|
|
if [ -z "$RUSTDESK_PASS" ]; then
|
|
RUSTDESK_PASS="<генерируется RustDesk — посмотрите в GUI>"
|
|
fi
|
|
|
|
# Summary
|
|
echo ""
|
|
echo "============================================"
|
|
echo " RustDesk Ready!"
|
|
echo "============================================"
|
|
echo ""
|
|
printf " %-12s %s\n" "ID:" "$RUSTDESK_ID"
|
|
printf " %-12s %s\n" "Password:" "$RUSTDESK_PASS"
|
|
printf " %-12s %s\n" "Display:" ":0 (1920x1080 dummy)"
|
|
printf " %-12s %s\n" "Version:" "$RUSTDESK_VERSION"
|
|
printf " %-12s %s\n" "Arch:" "$ARCH"
|
|
echo ""
|
|
echo " Connect: rustdesk $RUSTDESK_ID"
|
|
echo " Logs: /tmp/rdtop-install.log"
|
|
echo " RustDesk: /tmp/rustdesk-server.log"
|
|
echo " Xorg: /tmp/xorg-dummy.log"
|
|
echo ""
|
|
echo "============================================"
|
|
|
|
log "Installation complete. ID: $RUSTDESK_ID"
|