From 43e7b30f41d29fe2a6ffb21fc047268fd148037d Mon Sep 17 00:00:00 2001 From: Orchestrator Date: Sat, 16 May 2026 00:16:14 +0100 Subject: [PATCH] feat: add host setup scripts + configs for Intel Alder Lake-N - scripts/host/setup-host-rustdesk.sh: protect RustDesk ID on host - scripts/host/README-host.md: instructions for manual apply - configs/rustdesk2-host.toml.template: config template - configs/systemd/: systemd units for both VPS and host --- configs/rustdesk2-host.toml.template | 9 + configs/systemd/rustdesk-client-local.service | 17 ++ configs/systemd/rustdesk-hbbr.service | 23 ++ configs/systemd/rustdesk-hbbs.service | 23 ++ scripts/host/README-host.md | 146 ++++++++++++ scripts/host/setup-host-rustdesk.sh | 207 ++++++++++++++++++ 6 files changed, 425 insertions(+) create mode 100644 configs/rustdesk2-host.toml.template create mode 100644 configs/systemd/rustdesk-client-local.service create mode 100644 configs/systemd/rustdesk-hbbr.service create mode 100644 configs/systemd/rustdesk-hbbs.service create mode 100644 scripts/host/README-host.md create mode 100644 scripts/host/setup-host-rustdesk.sh diff --git a/configs/rustdesk2-host.toml.template b/configs/rustdesk2-host.toml.template new file mode 100644 index 0000000..14f842c --- /dev/null +++ b/configs/rustdesk2-host.toml.template @@ -0,0 +1,9 @@ +# RustDesk2.toml для хоста Intel Alder Lake-N +# Публичный сервер для стабильного ID +rendezvous_server = 'rs-ny.rustdesk.com:21116' +nat_type = 1 +serial = 0 +unlock_pin = '' + +[options] +local-ip-addr = '' diff --git a/configs/systemd/rustdesk-client-local.service b/configs/systemd/rustdesk-client-local.service new file mode 100644 index 0000000..df17376 --- /dev/null +++ b/configs/systemd/rustdesk-client-local.service @@ -0,0 +1,17 @@ +[Unit] +Description=RustDesk Client (local hbbs) +After=xorg-dummy.service network.target + +[Service] +Type=simple +User=root +Environment="DISPLAY=:0" +Environment="XAUTHORITY=/root/.Xauthority" +ExecStartPre=/root/write-rustdesk-config.sh +ExecStartPre=/bin/sleep 2 +ExecStart=/usr/share/rustdesk/rustdesk --server +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target diff --git a/configs/systemd/rustdesk-hbbr.service b/configs/systemd/rustdesk-hbbr.service new file mode 100644 index 0000000..eb0c684 --- /dev/null +++ b/configs/systemd/rustdesk-hbbr.service @@ -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 diff --git a/configs/systemd/rustdesk-hbbs.service b/configs/systemd/rustdesk-hbbs.service new file mode 100644 index 0000000..80ad370 --- /dev/null +++ b/configs/systemd/rustdesk-hbbs.service @@ -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 diff --git a/scripts/host/README-host.md b/scripts/host/README-host.md new file mode 100644 index 0000000..c868de0 --- /dev/null +++ b/scripts/host/README-host.md @@ -0,0 +1,146 @@ +# RustDesk Host Setup — README + +**Цель:** зафиксировать RustDesk ID на хосте Intel Alder Lake-N (Debian 12, GNOME headless, dummy-драйвер) и защитить конфиг от перезаписи. + +--- + +## Содержимое + +| Файл | Назначение | +|------|-----------| +| `setup-host-rustdesk.sh` | Основной скрипт: проверяет dummy Xorg, создаёт/защищает `RustDesk.toml`, создаёт `write-rustdesk-config.sh`, настраивает systemd-сервис | +| `write-rustdesk-config.sh` | Экстренный скрипт: снимает `chattr +i`, перезаписывает конфиг, ставит защиту обратно | +| `setup-host-rustdesk.log` | Лог, создаётся автоматически при запуске основного скрипта | + +--- + +## Как применить + +### Шаг 1: Скопировать файлы на хост + +**Вариант A: USB / вручную** +```bash +# На VPS (где вы сейчас) +# Файлы уже находятся в папке scripts/host/. Скопируйте их на USB и перенесите на хост. +# Или если есть любой файловый доступ — просто перенесите. +``` + +**Вариант B: scp (если есть любой сетевой доступ к хосту)** +```bash +# С хоста или откуда есть доступ: +scp setup-host-rustdesk.sh user@host-ip:/tmp/ +ssh user@host-ip "sudo bash /tmp/setup-host-rustdesk.sh" +``` + +**Вариант C: curl через временный HTTP-сервер** +```bash +# На промежуточной машине: +python3 -m http.server 8080 --directory /path/to/scripts/host/ + +# На хосте: +curl -O http://PROMO-IP:8080/setup-host-rustdesk.sh +sudo bash setup-host-rustdesk.sh +``` + +### Шаг 2: Запустить основной скрипт + +```bash +sudo bash setup-host-rustdesk.sh +``` + +Скрипт должен выполниться полностью без ошибок. + +--- + +## Что проверить после применения + +### 1. RustDesk ID +```bash +rustdesk --get-id +``` +Ожидаемый результат: 9-значный номер (например, `458564614` на VPS). На хосте будет **другой** ID — это нормально. Главное, чтобы он **не менялся после перезагрузки**. + +### 2. Конфиг защищён +```bash +lsattr /home/ИМЯПОЛЬЗОВАТЕЛЯ/.config/rustdesk/RustDesk.toml +``` +Ожидаемый результат: флаг `i` (immutable), например: +``` +---- i --------- /home/user/.config/rustdesk/RustDesk.toml +``` + +### 3. Сервис активен +```bash +systemctl is-active rustdesk-client-local +``` +Ожидаемый результат: `active` + +### 4. Dummy монитор работает +```bash +DISPLAY=:1 xrandr --listmonitors +``` +Ожидаемый результат: строка с `DUMMY0` + +--- + +## Что делать, если ID всё равно меняется + +### Вариант 1: RustDesk не успел сгенерировать ID перед chattr +Если ID меняется, скорее всего RustDesk создал новый файл конфигурации в другом месте или перезаписал его через другой процесс. + +**Проверьте:** +```bash +find / -name "RustDesk.toml" 2>/dev/null +``` +Если найдено несколько — значит RustDesk использует не тот. + +Правильный: `/home/ИМЯПОЛЬЗОВАТЕЛЯ/.config/rustdesk/RustDesk.toml` + +### Вариант 2: RustDesk запущен без DISPLAY +Для генерации ID RustDesk **должен** запуститься с GUI (даже dummy). Убедитесь, что `xorg-dummy.service` запущен **до** rustdesk-client-local: +```bash +systemctl status xorg-dummy +systemctl status rustdesk-client-local +``` +Если `xorg-dummy` неактивен — RustDesk может работать в CLI-режиме и генерировать новый ID каждый раз. + +### Вариант 3: Файл отсутствовал при первом запуске скрипта +Если вы увидели в логе: +``` +WARN: RustDesk.toml ОТСУТСТВУЕТ, и rustdesk --get-id не вернул ID. +``` +Нужно: +1. Запустить RustDesk вручную с GUI один раз (чтобы он создал конфиг) +2. Затем применить защиту: +```bash +sudo chattr -i /home/user/.config/rustdesk/RustDesk.toml # если уже ставили +sudo chattr +i /home/user/.config/rustdesk/RustDesk.toml # защитить +``` + +--- + +## Предупреждения + +⚠️ **chattr +i** блокирует **любую** запись в файл, в том числе от RustDesk. Это цель — зафиксировать ID. Но если нужно поменять сервер или другие настройки — используйте `write-rustdesk-config.sh`. + +⚠️ Скрипт полагается на то, что: +- `rustdesk` установлен и доступен в `/usr/bin/rustdesk` +- Пользователь, под которым работает GNOME, называется `user` (или задайте `USER=... USER_HOME=...` перед запуском) +- Dummy-драйвер уже сконфигурирован (из предыдущих сессий) + +⚠️ **Экстренный write-скрипт**: +```bash +sudo bash write-rustdesk-config.sh myusername +``` +Он временно снимает `chattr +i`, перезаписывает файл и ставит защиту обратно. + +--- + +## Логи + +Все действия основного скрипта пишутся в: +``` +./setup-host-rustdesk.log +``` + +При возникновении проблем — приложите этот файл. diff --git a/scripts/host/setup-host-rustdesk.sh b/scripts/host/setup-host-rustdesk.sh new file mode 100644 index 0000000..9ebc0cd --- /dev/null +++ b/scripts/host/setup-host-rustdesk.sh @@ -0,0 +1,207 @@ +#!/usr/bin/env bash +set -euo pipefail + +####################################### +# setup-host-rustdesk.sh +# Защита RustDesk ID на хосте Intel Alder Lake-N +# Запускать от root +####################################### + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +LOG="$SCRIPT_DIR/setup-host-rustdesk.log" +USER_HOME="${USER_HOME:-/home/user}" +USER="${USER:-user}" +RUSTDESK_DIR="$USER_HOME/.config/rustdesk" +CONFIG_FILE="$RUSTDESK_DIR/RustDesk.toml" + +log() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG"; } +warn() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] WARN: $1" | tee -a "$LOG" >&2; } +fail() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] FATAL: $1" | tee -a "$LOG" >&2; exit 1; } + +[[ $EUID -ne 0 ]] && fail "Этот скрипт нужно запускать от root: sudo bash setup-host-rustdesk.sh" + +log "========== Начало настройки RustDesk на хосте ==========" +log "USER_HOME=$USER_HOME | USER=$USER" + + +# 1. Проверить dummy Xorg (GNOME с dummy-драйвером должен показывать монитор) +log "--- Шаг 1: Проверка dummy Xorg ---" +# systemd-сервис xorg-dummy уже должен быть создан пользователем или предыдущими сессиями +if systemctl is-active --quiet xorg-dummy 2>/dev/null; then + log "xorg-dummy.service: ACTIVE" +elif systemctl is-active --quiet xorg-dummy@"$USER" 2>/dev/null; then + log "xorg-dummy@$USER.service: ACTIVE" +else + warn "xorg-dummy.service не найден в активных юнитах. Это может быть нормально, если драйвер загружен иначе." +fi + +# Проверяем через xrandr у активного пользователя (display :1 для dummy) +if DISPLAY=:1 xrandr --listmonitors 2>/dev/null | grep -qi "DUMMY\|dummy"; then + log "xrandr: dummy монитор обнаружен (DISPLAY=:1)" +else + warn "xrandr не нашел DUMMY монитор на DISPLAY=:1. Попробуйте DISPLAY=:0" +fi + +log "--- Шаг 2: Статус локального клиента RustDesk --" +if systemctl is-active --quiet rustdesk-client-local 2>/dev/null; then + log "rustdesk-client-local.service: ACTIVE" +else + warn "rustdesk-client-local.service: NOT ACTIVE — будет создан/включён ниже" +fi + + +# 2. Проверить/создать RustDesk.toml и защитить его +log "--- Шаг 3: Проверка/создание RustDesk.toml ---" + +mkdir -p "$RUSTDESK_DIR" + +if [[ -f "$CONFIG_FILE" ]]; then + log "RustDesk.toml найден: $CONFIG_FILE" + # Показать текущий ID + CURRENT_ID=$(rustdesk --get-id 2>/dev/null || echo "N/A") + log "Текущий RustDesk ID: $CURRENT_ID" + + # Убедиться что в конфиге нужный сервер + if grep -q 'custom-rendezvous-server' "$CONFIG_FILE"; then + log "custom-rendezvous-server уже задан в конфиге" + else + log "custom-rendezvous-server НЕ задан — добавляем публичный сервер" + cat >> "$CONFIG_FILE" <<'TOML' + +[options] +custom-rendezvous-server = "rs-ny.rustdesk.com:21116" +TOML + fi +else + CURRENT_ID=$(rustdesk --get-id 2>/dev/null || echo "") + if [[ -z "$CURRENT_ID" ]]; then + warn "RustDesk.toml ОТСУТСТВУЕТ, и rustdesk --get-id не вернул ID." + warn "Возможно, RustDesk ещё ни разу не запускался с GUI (нужен xorg-dummy)." + warn "Если ID ещё не сгенерирован — создайте конфиг вручную:" + warn " mkdir -p $RUSTDESK_DIR && cat > $CONFIG_FILE <<'TOML'" + warn " [options]" + warn " custom-rendezvous-server = \"rs-ny.rustdesk.com:21116\"" + warn " TOML" + warn "Затем перезапустите rustdesk-client-local и повторите скрипт." + else + log "ID получен ($CURRENT_ID), но RustDesk.toml отсутствует — создаём из текущих настроек" + cat > "$CONFIG_FILE" < "$WRITE_SCRIPT" <<'SCRIPT' +#!/usr/bin/env bash +# Этот скрипт временно снимает защиту, перезаписывает конфиг и ставит защиту обратно. +# Запускать от root только если понимаете зачем. +set -euo pipefail + +USER="${1:-user}" +USER_HOME="/home/$USER" +CONFIG_FILE="$USER_HOME/.config/rustdesk/RustDesk.toml" + +[[ $EUID -ne 0 ]] && { echo "Run as root"; exit 1; } + +if [[ ! -f "$CONFIG_FILE" ]]; then + echo "Файл $CONFIG_FILE не найден. Нечего перезаписывать." + exit 1 +fi + +echo "Снимаем immutable..." +chattr -i "$CONFIG_FILE" + +echo "Перезаписываем RustDesk.toml..." +cat > "$CONFIG_FILE" <<'TOML' +[options] +custom-rendezvous-server = "rs-ny.rustdesk.com:21116" +TOML + +chown "$USER:$USER" "$CONFIG_FILE" +chmod 600 "$CONFIG_FILE" + +echo "Ставим immutable обратно..." +chattr +i "$CONFIG_FILE" +lsattr "$CONFIG_FILE" +echo "Готово." +SCRIPT +chmod +x "$WRITE_SCRIPT" +chown root:root "$WRITE_SCRIPT" +log "write-rustdesk-config.sh создан: $WRITE_SCRIPT" + + +# 5. Создать/обновить systemd-сервис rustdesk-client-local +SERVICE_FILE="/etc/systemd/system/rustdesk-client-local.service" +log "--- Шаг 6: Создание systemd unit rustdesk-client-local.service ---" + +if [[ -f "$SERVICE_FILE" ]]; then + cp "$SERVICE_FILE" "$SERVICE_FILE.bak.$(date +%s)" + log "Backup создан: $SERVICE_FILE.bak.*" +fi + +cat > "$SERVICE_FILE" </dev/null || echo "") +if [[ -n "$ID" ]]; then + log "ТЕКУЩИЙ RUSTDESK ID: $ID" +else + warn "Не удалось получить ID (rustdesk --get-id вернул пустоту)" + warn "Убедитесь, что rustdesk установлен и systemd-сервис запущён." +fi + + +# Summary +log "========== Результат ==========" +log "RustDesk ID: ${ID:-пусто}" +log "Конфиг защищён chattr: $(lsattr "$CONFIG_FILE" 2>/dev/null || echo 'не удалось проверить')" +log "systemd unit: $(systemctl is-active rustdesk-client-local 2>/dev/null || echo 'неактивен')" +log "Записи в systemd journal: journalctl -u rustdesk-client-local -f" +log "Лог скрипта: $LOG" +log "Готово."