diff --git a/decisions/2026-04-29-rustdesk-client-deployment-package.md b/decisions/2026-04-29-rustdesk-client-deployment-package.md new file mode 100644 index 0000000..b3a1b54 --- /dev/null +++ b/decisions/2026-04-29-rustdesk-client-deployment-package.md @@ -0,0 +1,133 @@ +--- +date: 2026-04-29 +type: deployment +tags: [rustdesk, deployment, installers, nextcloud, automation] +--- + +# RustDesk client deployment package — Nextcloud `RustDesk install/` + +## Цель + +Удобное развёртывание ~30-50 клиентских машин (НИИКН + клиенты) с pre-настроенным RustDesk. Клиент должен после установки сразу подключаться к `remot.dttb.ru`, без ручной настройки api/relay/key. + +## Что сделано + +В корне Nextcloud (`Nextcloud-admin@dttb․ru`) создана папка **`RustDesk install/`** с готовыми установщиками + автоматическими скриптами + конфигом. + +### Структура + +``` +RustDesk install/ ~766 MB total +├── README.md инструкция для клиента +├── RustDesk2.toml шаблон конфига (ID/relay/api/key) +├── windows/ +│ ├── rustdesk-1.4.6-x86_64.exe 23 MB - основной installer +│ ├── rustdesk-1.4.6-x86_64.msi 23 MB - MSI для GPO +│ ├── Install-Windows.ps1 PowerShell автоустановка +│ └── Install-Windows.bat wrapper, двойной клик → UAC → автоинстал +├── linux/ +│ ├── rustdesk-1.4.6-x86_64.deb 22 MB +│ ├── rustdesk-1.4.6-aarch64.deb 20 MB +│ ├── rustdesk-1.4.6-x86_64.rpm 30 MB +│ ├── rustdesk-1.4.6-aarch64.rpm 29 MB +│ ├── rustdesk-1.4.6-x86_64.AppImage 81 MB - для дистрибутивов без apt/dnf +│ └── install-linux.sh bash, авто-detect arch + pkg manager +├── macos/ +│ ├── rustdesk-1.4.6-aarch64.dmg 24 MB - Apple Silicon +│ ├── rustdesk-1.4.6-x86_64.dmg 31 MB - Intel +│ └── install-macos.sh bash, mount dmg + copy to /Applications +└── android/ + └── rustdesk-1.4.6-universal.apk 67 MB +``` + +Версия RustDesk **1.4.6** (latest stable, релиз 2026-03-05). Совпадает с тем что у Олега на Mac и Windows-сервере. + +## Что делает скрипт + +1. **Установка** — silent через системный пакетный менеджер +2. **Остановка сервиса** перед перезаписью конфига (`Stop-Service RustDesk` / `systemctl stop rustdesk`) +3. **Копирование `RustDesk2.toml`** в правильное место: + - Windows service mode: `C:\Windows\ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\` + - Windows user mode (fallback): `%APPDATA%\RustDesk\config\` + - Linux service: `/root/.config/rustdesk/` + - Linux user: `~/.config/rustdesk/` + - macOS: `~/Library/Preferences/com.carriez.RustDesk/` +4. **Генерация permanent password** (10 символов, случайный per-machine) через `rustdesk --password ` +5. **Сохранение creds** в файл (chmod 600): + - Windows: `C:\Users\Public\rustdesk-credentials.txt` + `C:\Users\Public\Desktop\RustDesk-ID.txt` + - Linux: `/root/rustdesk-credentials.txt` +6. **Запуск сервиса** — `Start-Service RustDesk` / `systemctl start rustdesk` +7. **Вывод** ID + пароля для пользователя + +macOS — без auto-password (sandboxing) — пользователь устанавливает permanent password сам через UI. + +## Конфиг сервера (RustDesk2.toml) + +```toml +rendezvous_server = "remot.dttb.ru:21116" +nat_type = 1 +serial = 1 + +[options] +custom-rendezvous-server = "remot.dttb.ru" +relay-server = "remot.dttb.ru" +api-server = "https://remot.dttb.ru" +key = "R0lA4r77hAGw6YRL1qG3JioVqQ0Q0fJfzkwlAGqR6jU=" +allow-websocket = "Y" +verification-method = "use-permanent-password" +approve-mode = "password" +``` + +## Способы развёртывания + +### Текущий (offline-friendly) +1. Олег делает в Nextcloud public share-link (пока не сделано — отдельная ручная задача) +2. Шлёт ссылку клиенту/технику +3. Тот скачивает свою папку → запускает скрипт → готово + +### Будущее — one-liner +Положить скрипт на rustdesk-api сервер (или public path в NPM): +- `irm https://remot.dttb.ru/install/win.ps1 | iex` (Win) +- `curl -sL https://remot.dttb.ru/install/linux.sh | sudo bash` (Linux) + +Скрипт автоматически качает installer с github. + +### Будущее — Strategy +В админке `/_admin/` → Configuration Strategy → создать policy с настройками. Push'ит конфиг существующим клиентам автоматически. Требует чтобы клиент изначально знал api-server URL — то есть всё равно первичная установка нужна. + +### Будущее — `rustdesk-licensed-XXXXXXXX.exe` trick +RustDesk при первом запуске парсит своё имя файла, если оно соответствует formату — применяет встроенный config. Требует утилиту шифрования config (rustdesk-utils 2.x от lejianwen-pro). Наш `rustdesk-utils` 1.1.14 этого не умеет — нужно скачать pro-версию отдельно или использовать веб-инструмент https://aps.lejianwen.com. + +### Будущее — WinRM/SSH push для существующих машин +Уже есть NetBird-подключение к большинству Windows-клиентов (Volkkent, Glavtorg, ММФБ, Зеленоград). Можно через `Invoke-Command` или `pywinrm` развернуть скрипт удалённо без участия пользователя. + +## Безопасность + +- **Public link на скачивание лучше с паролем** — в установщике зашит `key=R0lA...`, кто угодно скачавший может зарегистрировать себя как peer на нашем сервере. MUST_LOGIN отбивает подключения, но heartbeat-флуд возможен. +- **Permanent password** случайный per-машина, в файле с chmod 600 +- **`MUST_LOGIN=Y` на сервере** — каждый peer должен залогиниться в API после установки. Скрипт этого пока **не делает** — клиент должен залогиниться вручную в RustDesk UI (Settings → Account) или через web `/_admin/`. Автоматизация login через скрипт = отдельная задача (нужен service-token / OIDC). + +## Известные ограничения + +- **Windows ARM64** — не поддерживается RustDesk 1.4.6 (нет нативного installer'а). Используется x86_64 в эмуляции. +- **Android** — apk без auto-config; пользователь вручную вводит ID/relay/api/key. Автоматизация для Android = другая задача (Intent URL scheme или MDM push). +- **iOS** — RustDesk через App Store, конфиг через QR-код или Universal Link. Не покрыто текущим пакетом. +- **macOS** — без auto-permanent-password (sandboxing CLI ограничен). Пользователь делает через UI. +- **`MUST_LOGIN` post-install** — после установки клиент вынуждены вручную залогиниться. Без login peer виден как online в hbbs, но connections к нему отбрасываются. + +## TODO / следующие шаги + +- [ ] Олег создаёт public share-link в Nextcloud (с паролем), кладёт ссылку в [[../snippets/clients/]] +- [ ] Подготовить **one-liner-скрипты** на сервере (NPM static path `/install/` → S3 или rustdesk-api resources/public) +- [ ] **Configuration Strategy** в админке lejianwen-api — push config existing peers +- [ ] Скачать `rustdesk-utils` 2.x (lejianwen-pro) для генерации `rustdesk-licensed-*.exe` — single-file deployment без скриптов +- [ ] **Auto-login через скрипт** — создать service-юзера в API с фиксированным password, скрипт логинится этим юзером во время install. После установки админ через `/_admin/` переносит peer в нужную группу. +- [ ] **WinRM bulk-deploy** — список существующих NetBird-managed Windows-машин + Ansible/PowerShell job по разворачиванию + +## Связанные файлы + +- [[projects/dttb/rustdesk]] — справочник по серверу +- [[../decisions/2026-04-28-rustdesk-lejianwen-pro-migration]] — миграция с OSS на pro +- В Nextcloud: `RustDesk install/` (этот пакет) +- На LXC 116: `/root/RustDesk2.toml` (шаблон) +- На LXC 116: `/root/rustdesk-backup-20260428-1134/admin-password.txt` (admin pw для api) diff --git a/projects/dttb/rustdesk.md b/projects/dttb/rustdesk.md index 55e92f3..7edd3af 100644 --- a/projects/dttb/rustdesk.md +++ b/projects/dttb/rustdesk.md @@ -147,11 +147,46 @@ tail -f /var/log/rustdesk-api/rustdesk-api.log - **community-script может пытаться обновить пакеты** — `apt-mark hold` защищает hbbs/hbbr, но если запустить полный re-run скрипта community-scripts, могут быть сюрпризы. Не запускать без необходимости. - **`/proc/loadavg` в LXC = нагрузка хоста**, не контейнера ([[../../../knowledge-base/feedback_lxc_loadavg]] в memory). +## Развёртывание клиентов + +В Nextcloud в корне создан пакет **`RustDesk install/`** с готовыми установщиками для всех платформ + автоматические скрипты. Подробности: [[../../decisions/2026-04-29-rustdesk-client-deployment-package]]. + +``` +RustDesk install/ ~766 MB +├── README.md инструкция для клиента +├── RustDesk2.toml шаблон конфига +├── windows/ (.exe + .msi + Install-Windows.ps1/.bat) +├── linux/ (deb x64+arm64, rpm x64+arm64, AppImage, install-linux.sh) +├── macos/ (.dmg aarch64+x86_64, install-macos.sh) +└── android/ (universal.apk) +``` + +**Workflow для нового клиента:** +1. Олег делает public share-link в Nextcloud (с паролем — установщики содержат `key`) +2. Клиент скачивает свою папку, запускает скрипт (двойной клик `Install-Windows.bat` или `sudo bash install-linux.sh`) +3. Скрипт ставит RustDesk + кладёт `RustDesk2.toml` + генерит permanent password + выводит ID+pw +4. Клиент шлёт ID+pw админу, админ привязывает peer к нужной группе через `/_admin/` + +**Версия:** RustDesk 1.4.6 (релиз март 2026). Обновлять при выпуске новой версии — заменить файлы в папке + обновить `1.4.6` в README/скриптах. + +**Permanent password:** auto-generated 10 символов per-machine, сохраняется в: +- Windows: `C:\Users\Public\rustdesk-credentials.txt` +- Linux: `/root/rustdesk-credentials.txt` (chmod 600) +- macOS: ручная установка через UI (sandboxing) + +**Что НЕ делает скрипт:** +- Auto-login в API (требует service-token, отдельная задача) → клиент должен залогиниться сам через RustDesk UI Settings → Account, иначе MUST_LOGIN=Y отбивает входящие connections +- Configure Android (вручную вводит настройки) + ## TODO -- Раскатать `RustDesk2.toml` на парк через GPO/скрипт -- Заполнить группы клиентских организаций -- Бэкап на ArtLeon через cron + rsync (NetBird) +- Раскатать `RustDesk install/` пакет на парк (~30-50 машин) +- Заполнить группы клиентских организаций в `/_admin/` +- One-liner deployment script на сервере (`https://remot.dttb.ru/install/win.ps1` etc.) +- Configuration Strategy в lejianwen-api для push existing клиентам +- `rustdesk-utils` 2.x для `rustdesk-licensed-*.exe` (single-file deploy) +- Auto-login клиента в API через service-token (упростит post-install) +- Бэкап БД API + ключей на ArtLeon через cron + rsync (NetBird) - Через 2-4 недели — миграция в Docker `lejianwen/rustdesk-server-s6` (Вариант A3 из decision-файла) - MCP-обёртка поверх Swagger API для управления из Claude Code - HA-схема на втором экземпляре (НИИКН Proxmox) с общей MySQL