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
This commit is contained in:
Orchestrator
2026-05-16 00:16:14 +01:00
parent 32451eb0f8
commit 43e7b30f41
6 changed files with 425 additions and 0 deletions

146
scripts/host/README-host.md Normal file
View File

@@ -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
```
При возникновении проблем — приложите этот файл.

View File

@@ -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" <<TOML
[options]
custom-rendezvous-server = "rs-ny.rustdesk.com:21116"
TOML
fi
fi
# Правильные права
chown -R "$USER:$USER" "$RUSTDESK_DIR"
chmod 600 "$CONFIG_FILE"
# 3. Защита chattr +i (только root)
log "--- Шаг 4: Применение chattr +i к RustDesk.toml ---"
if [[ -f "$CONFIG_FILE" ]]; then
chattr +i "$CONFIG_FILE"
log "chattr +i применён к $CONFIG_FILE"
lsattr "$CONFIG_FILE" | tee -a "$LOG"
else
warn "Файл $CONFIG_FILE не существует — chattr +i НЕ применён!"
warn "Сначала убедитесь, что RustDesk сгенерировал конфигурацию."
fi
# 4. Создать/обновить write-rustdesk-config.sh (для экстренной перезаписи)
WRITE_SCRIPT="$SCRIPT_DIR/write-rustdesk-config.sh"
log "--- Шаг 5: Создание write-rustdesk-config.sh ---"
cat > "$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" <<EOF
[Unit]
Description=RustDesk Client Local (headless host)
After=network.target xorg-dummy.service
Wants=xorg-dummy.service
[Service]
Type=simple
User=$USER
Environment=DISPLAY=:1
Environment=XAUTHORITY=$USER_HOME/.Xauthority
WorkingDirectory=$USER_HOME
ExecStart=/usr/bin/rustdesk --tray
Restart=always
RestartSec=5
StartLimitInterval=60
StartLimitBurst=3
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now rustdesk-client-local.service || true
log "rustdesk-client-local.service: enabled & restarted"
# 6. Текущий ID
log "--- Шаг 7: Проверка RustDesk ID хоста ---"
ID=$(rustdesk --get-id 2>/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 "Готово."