A. kb-autosync.sh переписан: pull → regenerate index → commit → push. После каждого push с Mac индекс objects-map.json и _index.md обновляются автоматически на code-server (LXC 132). B. kb-objects-map.py + kb-objects-audit.py добавлены в воскресный weekly cron на LXC 132 — health-check автогенерируется раз в неделю. C. Чистка битых wiki-ссылок (score 84 → 9): - notes/govru-diagnosis → projects/niikn/govru-quickfix-playbook (2) - claude-memory/podkop → 2026-04-17-peredelki-podkop-stability-fix - [[../snippets/clients/]] → snippets/clients/ (текстом, 2) - [[feedback_*]] (user memory) → backtick-cited (2) - [[../znamenskoye/]] → [[../znamenskoye/README]] (4) Скрипт kb-objects-audit.py улучшен: regex теперь требует [[...]] с двойной скобкой (не одной), исключает audit/ и CLAUDE.md (placeholder и autogen). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
205 lines
12 KiB
Markdown
205 lines
12 KiB
Markdown
---
|
||
date: 2026-04-28
|
||
type: project-reference
|
||
tags: [rustdesk, lxc116, lejianwen, dttb]
|
||
---
|
||
|
||
# RustDesk Server — справочник
|
||
|
||
## Что это
|
||
|
||
Self-hosted Remote Desktop сервер для парка ~30-50 машин (НИИКН + клиенты).
|
||
Стек **`lejianwen/rustdesk-server-pro` 1.1.14** (`hbbs`/`hbbr`) + **`lejianwen/rustdesk-api` 2.7** на нативной Debian-установке (без Docker), с `MUST_LOGIN=Y`.
|
||
|
||
История миграции: [[../../decisions/2026-04-28-rustdesk-lejianwen-pro-migration]]
|
||
|
||
## Где живёт
|
||
|
||
- **LXC 116** `rustdeskserver` на Proxmox 10.0.0.250
|
||
- IP: `10.0.0.244` (LAN) / `100.70.191.161` (NetBird)
|
||
- Debian 12, 1 vCPU / 512M / 2G — community-script установка
|
||
|
||
## Домен
|
||
|
||
- Внешний: **`remot.dttb.ru`** (Cloudflare → роутер dttb.ru → NPM 10.0.0.195 → 10.0.0.244)
|
||
- Web-админка: https://remot.dttb.ru/_admin/
|
||
- Swagger: https://remot.dttb.ru/swagger/index.html
|
||
- Login: см. [[credentials#RustDesk Server (LXC 116)]]
|
||
|
||
## Сервисы (systemd)
|
||
|
||
```
|
||
rustdesk-hbbs.service — ID/Rendezvous server (hbbs --must-login Y -k _ -r remot.dttb.ru:21117)
|
||
rustdesk-hbbr.service — Relay server (hbbr -k _)
|
||
rustdesk-api.service — Web admin + REST API (на 21114)
|
||
```
|
||
|
||
Бинари:
|
||
- `/usr/bin/hbbs` — pro 1.1.14 (с патчем `--must-login Y`)
|
||
- `/usr/bin/hbbr` — pro 1.1.14
|
||
- `/usr/bin/rustdesk-api` — 2.7
|
||
- `/usr/bin/{hbbs,hbbr}.oss-1.1.14` — rollback-копии
|
||
|
||
`apt-mark hold rustdesk-server-hbbs rustdesk-server-hbbr` — apt не перезапишет.
|
||
|
||
Override-конфиги:
|
||
- `/etc/systemd/system/rustdesk-hbbs.service.d/override.conf`
|
||
- `/etc/systemd/system/rustdesk-hbbr.service.d/override.conf`
|
||
|
||
## Порты
|
||
|
||
| Порт | Протокол | Назначение |
|
||
|------|----------|------------|
|
||
| 21114 | TCP | rustdesk-api HTTP (только через NPM HTTPS!) |
|
||
| 21115 | TCP | hbbs NAT-test |
|
||
| 21116 | TCP+UDP | hbbs ID/rendezvous (UDP — основной) |
|
||
| 21117 | TCP | hbbr relay |
|
||
| 21118 | TCP | hbbs WebSocket (для All-In-HTTPS клиентов через `/ws/id`) |
|
||
| 21119 | TCP | hbbr WebSocket (через `/ws/relay`) |
|
||
|
||
NPM Proxy Host id=14: `https://remot.dttb.ru → 10.0.0.244:21114` + custom nginx с `/ws/id` и `/ws/relay`.
|
||
NPM Streams: id 38-43 (21115/TCP, 21116/UDP, 21116/TCP, 21117/TCP, 21118/TCP, 21119/TCP) → 10.0.0.244.
|
||
|
||
## Ключи
|
||
|
||
- `/var/lib/rustdesk-server/id_ed25519` — приватный (88 байт)
|
||
- `/var/lib/rustdesk-server/id_ed25519.pub` — `R0lA4r77hAGw6YRL1qG3JioVqQ0Q0fJfzkwlAGqR6jU=`
|
||
|
||
**Не перегенерировать!** Иначе все ~30-50 клиентов перестанут подключаться.
|
||
|
||
## БД
|
||
|
||
- `/var/lib/rustdesk-server/db_v2.sqlite3` — БД hbbs (peers state)
|
||
- `/var/lib/rustdesk-api/data/rustdeskapi.db` — БД api (users, groups, address_books, audit_logs)
|
||
|
||
Пока SQLite. План: MySQL когда дойдём до HA.
|
||
|
||
## Конфиг api
|
||
|
||
`/var/lib/rustdesk-api/conf/config.yaml` — основные параметры:
|
||
- `lang: ru`
|
||
- `app.register: false` (регистрация выключена — юзеров создаёт админ)
|
||
- `app.show-swagger: 1`
|
||
- `app.ban-threshold: 5`
|
||
- `app.captcha-threshold: 3`
|
||
- `rustdesk.id-server: remot.dttb.ru:21116`
|
||
- `rustdesk.relay-server: remot.dttb.ru:21117`
|
||
- `rustdesk.api-server: https://remot.dttb.ru`
|
||
- `rustdesk.key: <id_ed25519.pub>`
|
||
- `jwt.key: <см. credentials>`
|
||
- `ldap.enable: false`
|
||
|
||
## Шаблон RustDesk2.toml для клиентов
|
||
|
||
`/root/RustDesk2.toml` на LXC 116:
|
||
|
||
```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"
|
||
```
|
||
|
||
## CLI-команды (на LXC 116)
|
||
|
||
```bash
|
||
# Сменить пароль admin
|
||
cd /var/lib/rustdesk-api && /usr/bin/rustdesk-api reset-admin-pwd <new-pw>
|
||
|
||
# Сменить пароль обычного юзера
|
||
cd /var/lib/rustdesk-api && /usr/bin/rustdesk-api reset-pwd <username> <new-pw>
|
||
|
||
# Список peers через sqlite
|
||
sqlite3 /var/lib/rustdesk-api/data/rustdeskapi.db \
|
||
"select id, last_online_ip, datetime(last_online_time,'unixepoch') from peers order by last_online_time desc limit 10;"
|
||
|
||
# Список юзеров
|
||
sqlite3 /var/lib/rustdesk-api/data/rustdeskapi.db \
|
||
"select id, username, group_id, status, is_admin from users;"
|
||
|
||
# Логи
|
||
tail -f /var/log/rustdesk-server/hbbs.log
|
||
tail -f /var/log/rustdesk-server/hbbr.log
|
||
tail -f /var/log/rustdesk-api/rustdesk-api.log
|
||
```
|
||
|
||
## Бэкап и rollback
|
||
|
||
- `/root/rustdesk-backup-20260428-1134/` — бэкап от 2026-04-28 миграции (ключи, БД, config.yaml.orig)
|
||
- `/root/rustdesk-rollback.sh` — откат к OSS bin'ам за 30 сек
|
||
|
||
## Operational runbook
|
||
|
||
Полный operational runbook (recovery, troubleshooting, onboarding нового клиента, обновления): [[rustdesk-runbook]].
|
||
|
||
Pre-production audit (2026-04-30) с найденными уязвимостями + fixes: [[../../decisions/2026-04-30-rustdesk-pre-prod-audit]].
|
||
|
||
**Применённые фиксы (2026-04-30):**
|
||
- File permissions: `id_ed25519` 644→600, БД и config.yaml 644→640
|
||
- Logrotate `/etc/logrotate.d/rustdesk` (daily, 14 дней)
|
||
- Auto-backup cron 03:00 → `/root/rustdesk-backups/`
|
||
- NPM rate-limit на `/api/admin/login` (5r/m) и `/api/login` (10r/m)
|
||
|
||
## Известные нюансы
|
||
|
||
- **MUST_LOGIN работает только в pro-бинаре hbbs.** OSS hbbs (как был до 2026-04-28) этот флаг игнорирует. См. [[../../decisions/2026-04-28-rustdesk-lejianwen-pro-migration]].
|
||
- **Admin REST API через curl без web-сессии не пускает.** Юзеров/группы создавать через https://remot.dttb.ru/_admin/.
|
||
- **Admin генерит `/webclient2/`-ссылки на peer'ы, а api отдаёт WebClient на `/webclient/`** — баг lejianwen 2.7. В NPM Proxy Host 14 (advanced_config) добавлен `return 301 /webclient/$1$is_args$args` для `/webclient2/...`.
|
||
- **NPM streams API** — PUT не работает (валидатор `additional properties`). Только DELETE + POST.
|
||
- **NPM streams через UI/API не публикуются наружу docker-контейнера.** Нужно править compose-файл и пересоздавать контейнер. Compose лежит в `/data/compose/2/docker-compose.yml` на host LXC 103 (мы его положили туда, ранее Portainer хранил только в своём volume). При обновлении stack ВАЖНО: `cd /data/compose/2 && docker compose -p npm up -d` — relative `./data` resolve в `/data/compose/2/data` (где реальные данные NPM). НЕ обновляй stack через Portainer UI — он работает со своей копией compose в `/var/lib/docker/volumes/portainer_data/_data/compose/2/`, может перезаписать. Текущий compose содержит ports: 80, 81, 443, 21115-21119 (TCP+UDP где надо).
|
||
- **WebClient в браузере** работает на инфра-уровне (wss://remot.dttb.ru:21118/ws/id и :21119/ws/relay → 101 Switching Protocols). TLS termination для 21118/21119 через `/data/compose/2/data/nginx/custom/stream.conf` (custom stream block в NPM с `listen 21118 ssl` + `ssl_certificate /etc/letsencrypt/live/npm-41/...`). Streams 21115/21117/21116-tcp/udp идут через обычные NPM streams (id 38, 39, 40, 43). Чтобы реально использовать — нужны online peers с api-server login. Подключение Mac→Mac через WebClient невозможно (это и есть `MUST_LOGIN`-style ошибка "не удалось подключиться к серверу ретрансляции").
|
||
- **community-script может пытаться обновить пакеты** — `apt-mark hold` защищает hbbs/hbbr, но если запустить полный re-run скрипта community-scripts, могут быть сюрпризы. Не запускать без необходимости.
|
||
- **`/proc/loadavg` в LXC = нагрузка хоста**, не контейнера (`feedback_lxc_loadavg` (user memory) в 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
|
||
|
||
- Раскатать `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
|