--- date: 2026-04-30 type: runbook tags: [rustdesk, runbook, operations, recovery, troubleshooting] --- # RustDesk Server — Operational Runbook Операционная инструкция для повседневной эксплуатации, troubleshooting и recovery. Связанные документы: - [[rustdesk]] — справочник по серверу - [[../../decisions/2026-04-28-rustdesk-lejianwen-pro-migration]] — история миграции с OSS - [[../../decisions/2026-04-29-rustdesk-client-deployment-package]] — пакет установки клиентов - [[../../decisions/2026-04-30-rustdesk-pre-prod-audit]] — pre-production audit + fixes - [[credentials#RustDesk Server (LXC 116)]] — креды --- ## 1. Архитектура и компоненты ``` ┌────────────────────┐ │ Public Internet │ │ (через роутер │ │ dttb.ru NAT) │ └─────────┬──────────┘ │ 443 (HTTPS) 21115-21119 (TCP/UDP) ▼ ┌────────────────────────────────────┐ │ NPM (LXC 103, 10.0.0.195) │ │ • TLS termination + reverse proxy │ │ • Custom stream.conf для wss │ │ • Rate-limit на /api/login │ └─────────┬──────────────────────────┘ │ HTTP/plain TCP ▼ ┌──────────────────────────────────────────┐ │ RustDesk Server (LXC 116, 10.0.0.244) │ │ • hbbs (id-server, 21116/UDP+TCP) │ │ • hbbr (relay, 21117 TCP) │ │ • hbbs WebSocket :21118 │ │ • hbbr WebSocket :21119 │ │ • rustdesk-api 2.7 :21114 (web admin) │ │ • SQLite DB │ │ └─ MUST_LOGIN=Y enforced │ └──────────────────────────────────────────┘ ``` | Компонент | Откуда | Версия | Where | |---|---|---|---| | `hbbs` | lejianwen-pro (extracted from docker `rustdesk-server-s6`) | 1.1.14 | `/usr/bin/hbbs` | | `hbbr` | lejianwen-pro | 1.1.14 | `/usr/bin/hbbr` | | `rustdesk-api` | lejianwen `rustdesk-api` deb (community-script) | 2.7 | `/usr/bin/rustdesk-api` | | `nginx` | NPM (jc21/nginx-proxy-manager) | 2.12.2 / OpenResty | docker container `npm-app-1` | | Cert | Let's Encrypt | renew auto | `/etc/letsencrypt/live/npm-41/` | | Bind | systemd `rustdesk-{hbbs,hbbr,api}.service` | — | LXC 116 | ## 2. Daily operations ### 2.1 Проверить здоровье сервера ```bash # С Mac (или другой машины) curl -ksI https://remot.dttb.ru/_admin/ # → 200 OK curl -ksI https://remot.dttb.ru/webclient/ # → 200 OK # WebSocket endpoints curl -ks --http1.1 -H "Upgrade: websocket" -H "Connection: Upgrade" \ -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \ --max-time 3 https://remot.dttb.ru:21118/ws/id 2>&1 | grep "101" # Сервисы на LXC 116 sshpass -p '1qaz!QAZ' ssh root@10.0.0.250 \ "pct exec 116 -- systemctl is-active rustdesk-hbbs rustdesk-hbbr rustdesk-api" ``` ### 2.2 Кто сейчас в системе (peers онлайн) ```bash # Login в админку ADMIN_PWD=$(cat /root/rustdesk-backup-20260428-1134/admin-password.txt) # на LXC 116 # или из kb: 1qaz!QAZ # Веб-админка open https://remot.dttb.ru/_admin/ # admin / 1qaz!QAZ → Devices/Peers вкладка # Через SQL sshpass -p '1qaz!QAZ' ssh root@10.0.0.250 "pct exec 116 -- sqlite3 \ /var/lib/rustdesk-api/data/rustdeskapi.db \ 'select id, hostname, last_online_ip, datetime(last_online_time,\"unixepoch\") \ from peers order by last_online_time desc limit 20;'" ``` ### 2.3 Включить/выключить пользователя В `/_admin/` → Users → редактирование `status` (1=enabled, 2=disabled). CLI смена пароля: ```bash sshpass -p '1qaz!QAZ' ssh root@10.0.0.250 \ "pct exec 116 -- bash -c 'cd /var/lib/rustdesk-api && /usr/bin/rustdesk-api reset-pwd '" ``` ## 3. Onboarding нового клиента ### 3.1 Workflow на стороне сервера 1. **Создать юзера в `/_admin/`** для клиентской организации (или техника): - admin → Users → "Add" - Username, password, group 2. **Создать группу** (если нужна): - Groups → "Add" - Привязать к ней этого юзера 3. **Сообщить клиенту** username/password + ссылку на установщик ### 3.2 Workflow на стороне клиента 1. Скачать пакет из Nextcloud (см. `[[../../decisions/2026-04-29-rustdesk-client-deployment-package]]`): - **Public link**: см. в kb или генерится через NC API/UI - Файл: `RustDesk-Setup-.zip` (Windows ~23 MB, Linux ~190 MB, macOS ~57 MB) 2. Распаковать, запустить: - Windows: `Install-Windows.bat` (UAC → Да) - Linux: `sudo bash install-linux.sh` - macOS: `bash install-macos.sh` 3. После установки клиент получает **ID + permanent password** (показывается в конце скрипта + сохраняется в файл) 4. Клиент шлёт ID/password админу 5. **Клиент логинится в RustDesk-приложении** (Settings → Account → Sign in `<его-username>` / ``) - Без login: `MUST_LOGIN=Y` отбрасывает входящие connections — peer виден как online но connect к нему отказан 6. **Админ в `/_admin/`** → Devices → находит peer ID → привязывает к нужной группе ### 3.3 Создание public-link на установщик ```bash # Через Nextcloud OCS API APP_PWD=$(cat ~/.config/nextcloud-kb/app-password) EXPIRY=$(date -v+30d +%Y-%m-%d 2>/dev/null || date -d "+30 days" +%Y-%m-%d) SHARE_PWD="rustdesk-$(openssl rand -hex 4)" curl -s -u "admin:$APP_PWD" -X POST \ -H "OCS-APIRequest: true" \ --data-urlencode "path=/RustDesk install/RustDesk-Setup-Windows.zip" \ --data-urlencode "shareType=3" \ --data-urlencode "permissions=1" \ --data-urlencode "password=$SHARE_PWD" \ --data-urlencode "expireDate=$EXPIRY" \ "https://dttb.ru/ocs/v2.php/apps/files_sharing/api/v1/shares?format=json" | python3 -m json.tool ``` Ссылка публичная, **с паролем + 30 дней expiration**. Установщик содержит наш `key=R0lA...`, чтобы не утечь. ## 4. Troubleshooting ### 4.1 Сервер недоступен снаружи **Симптом:** `https://remot.dttb.ru/_admin/` не отвечает ```bash # 1. NPM container жив? sshpass -p '1qaz!QAZ' ssh root@10.0.0.250 \ "pct exec 103 -- docker ps | grep npm" # 2. Backend сервисы на LXC 116 sshpass -p '1qaz!QAZ' ssh root@10.0.0.250 \ "pct exec 116 -- systemctl status rustdesk-hbbs rustdesk-hbbr rustdesk-api --no-pager" # 3. Логи NPM sshpass -p '1qaz!QAZ' ssh root@10.0.0.250 \ "pct exec 103 -- docker exec npm-app-1 tail -30 /data/logs/proxy-host-14_error.log" # 4. Логи rustdesk sshpass -p '1qaz!QAZ' ssh root@10.0.0.250 \ "pct exec 116 -- tail -30 /var/log/rustdesk-server/hbbs.log /var/log/rustdesk-api/rustdesk-api.log" ``` ### 4.2 Peer показан online, но connect не работает Чек-лист: 1. **Залогинен ли peer в API?** ```bash sshpass -p '1qaz!QAZ' ssh root@10.0.0.250 "pct exec 116 -- sqlite3 \ /var/lib/rustdesk-api/data/rustdeskapi.db \ \"select * from user_tokens where device_id='';\"" ``` Если **пусто** → клиент не логинился через RustDesk Settings → Account → Sign in. **MUST_LOGIN=Y** отбивает. 2. **Heartbeat актуальный?** В `/_admin/` → Peers → "Last seen" должен быть < 5 минут. 3. **Релай работает?** На клиенте RustDesk: - Settings → Network → ID server: `remot.dttb.ru:21116` - Settings → Network → Relay server: `remot.dttb.ru:21117` - Если поля пустые — `RustDesk2.toml` не подхватился (см. путь в section 5). ### 4.3 WebClient timeout / "Не удалось подключиться" WebClient (`/webclient/`) Flutter имеет ограничения: - Mac→Mac не работает (controller не может быть peer'ом) - Peer offline → relay timeout → ошибка - Peer не залогинен → MUST_LOGIN отбивает **Используй desktop-клиент** для рутинной работы. WebClient — emergency only. ### 4.4 Rate-limit заблокировал Если 5 неудачных login → `503 Service Unavailable` от NPM на 1 минуту. Подожди или login с другого IP. После 5 неудачных также **`ban-threshold: 5`** в `lejianwen` забанит на ~1 час по user-account (отдельно от NPM IP-ban). ## 5. Конфиги и пути ### LXC 116 | Что | Путь | Перм | |---|---|---| | id_ed25519 (приватный) | `/var/lib/rustdesk-server/id_ed25519` | 600 | | id_ed25519.pub | `/var/lib/rustdesk-server/id_ed25519.pub` | 600 | | db_v2.sqlite3 (hbbs) | `/var/lib/rustdesk-server/db_v2.sqlite3` | 640 | | rustdeskapi.db (api) | `/var/lib/rustdesk-api/data/rustdeskapi.db` | 640 | | api config | `/var/lib/rustdesk-api/conf/config.yaml` | 640 | | systemd hbbs override | `/etc/systemd/system/rustdesk-hbbs.service.d/override.conf` | — | | systemd hbbr override | `/etc/systemd/system/rustdesk-hbbr.service.d/override.conf` | — | | logs | `/var/log/rustdesk-server/`, `/var/log/rustdesk-api/` | — | | Бэкап (вручную) | `/root/rustdesk-backup-20260428-1134/` | drwx— | | Бэкап (auto, daily 03:00) | `/root/rustdesk-backups/` | drwxr-xr-x | | Auto-backup script | `/usr/local/bin/rustdesk-backup.sh` | 700 | | Cron | `/etc/cron.d/rustdesk-backup` | — | | Logrotate | `/etc/logrotate.d/rustdesk` | — | | Rollback script | `/root/rustdesk-rollback.sh` | 700 | ### LXC 103 (NPM) | Что | Путь | |---|---| | Compose файл | `/data/compose/2/docker-compose.yml` (host) — содержит ports 21115-21119 | | Volume mount: NPM data | `/data/compose/2/data` | | Volume mount: LE | `/data/compose/2/letsencrypt` | | Custom http config | `/data/compose/2/data/nginx/custom/http.conf` (limit_req_zone) | | Custom stream config | `/data/compose/2/data/nginx/custom/stream.conf` (TLS terminate 21118/21119) | | Custom server_proxy | `/data/compose/2/data/nginx/custom/server_proxy.conf` (security headers) | | Proxy host 14 | `/data/compose/2/data/nginx/proxy_host/14.conf` (auto-gen NPM) | | Logs | `/data/compose/2/data/logs/proxy-host-14_*.log` | ## 6. Backup & Restore ### 6.1 Auto-backup Cron на LXC 116 запускает `/usr/local/bin/rustdesk-backup.sh` ежедневно в 03:00. - Tarball в `/root/rustdesk-backups/rustdesk-YYYYMMDD.tar.gz` - Содержит: ключи + обе БД + config.yaml + systemd overrides - Retention: 30 дней (find -mtime +30 -delete) ### 6.2 Восстановление БД из backup ```bash # Например, восстановить состояние на 5 дней назад TARBALL=$(ls -1t /root/rustdesk-backups/rustdesk-*.tar.gz | head -5 | tail -1) # Стоп systemctl stop rustdesk-api rustdesk-hbbs rustdesk-hbbr # Распаковка (поверх) tar xzf "$TARBALL" -C / # Старт systemctl start rustdesk-hbbs rustdesk-hbbr rustdesk-api ``` ### 6.3 Полный rollback к OSS `bash /root/rustdesk-rollback.sh` — за 30 секунд откатит к pre-migration (OSS hbbs/hbbr). ## 7. Updates & Maintenance ### 7.1 Обновление RustDesk-сервера Клиенты RustDesk-приложения автоматически обновляются с github releases (если включено auto-update). Сервер `hbbs/hbbr` не требует обновлений каждый месяц — обновлять при выпуске **major** версии (1.2.x → 1.3.x) или при security advisory. ```bash # 1. Скачать новые pro-бинари из docker docker pull lejianwen/rustdesk-server-s6:latest docker create --name rd-extract lejianwen/rustdesk-server-s6:latest docker cp rd-extract:/usr/bin/hbbs /tmp/hbbs.new docker cp rd-extract:/usr/bin/hbbr /tmp/hbbr.new docker rm rd-extract # 2. Передать в LXC 116 pct push 116 /tmp/hbbs.new /usr/bin/hbbs.new --perms 0755 pct push 116 /tmp/hbbr.new /usr/bin/hbbr.new --perms 0755 # 3. Стоп → swap → старт pct exec 116 -- bash -c " systemctl stop rustdesk-hbbs rustdesk-hbbr mv /usr/bin/hbbs /usr/bin/hbbs.old mv /usr/bin/hbbr /usr/bin/hbbr.old mv /usr/bin/hbbs.new /usr/bin/hbbs mv /usr/bin/hbbr.new /usr/bin/hbbr systemctl start rustdesk-hbbs rustdesk-hbbr sha256sum /var/lib/rustdesk-server/id_ed25519.pub # проверка ключ не изменился " ``` ### 7.2 Обновление rustdesk-api (lejianwen) ```bash # Через apt (если репо подключено) или вручную: # 1. Скачать deb с https://github.com/lejianwen/rustdesk-api/releases # 2. dpkg -i rustdesk-api-2.x.y.deb # 3. Проверить config.yaml — могут добавиться новые ключи # 4. systemctl restart rustdesk-api ``` ### 7.3 Лет's Encrypt cert Auto-renew через NPM (он сам делает). Проверка: ```bash docker exec npm-app-1 openssl x509 -in /etc/letsencrypt/live/npm-41/fullchain.pem -noout -dates ``` ## 8. Известные ограничения - **WebClient (Flutter)** не реализует full rustdesk-protocol — для рутины не используй (см. 4.3) - **Connection from Mac→Mac** не работает (peer не может быть controller'ом самого себя) - **Strategy (config push)** в `/_admin/` ещё не настроена — клиенты получают конфиг через `RustDesk2.toml` при установке, не пушится дальше - **Security headers** в NPM не наследуются в `location /` (NPM template ставит `add_header X-Served-By` который перебивает наследование). Workaround — через more_set_headers модуль или patch NPM template. Cosmetic, не критично — TLS 1.2/1.3 + LE cert + rate-limit основной защиты. - **`apt-mark hold` rustdesk-server-hbbs/hbbr** — apt не обновит. Снять hold перед апгрейдом: `apt-mark unhold rustdesk-server-hbbs rustdesk-server-hbbr` ## 9. Connectivity matrix | Откуда | Куда | Порт | Назначение | |---|---|---|---| | Клиент (peer) | hbbs | 21116/UDP | rendezvous, NAT-punching | | Клиент (peer) | hbbs | 21116/TCP | id-server, heartbeat | | Клиент (peer) | hbbs | 21115/TCP | NAT-test | | Клиент (peer) | hbbr | 21117/TCP | relay для P2P | | Браузер (WebClient) | NPM/443 | wss | id-server WebSocket (через `/ws/id` или `:21118` SSL) | | Браузер (WebClient) | NPM/443 | wss | relay WebSocket (через `/ws/relay` или `:21119` SSL) | | Админ браузер | NPM/443 | https | `/_admin/` интерфейс | | Админ CLI | rustdesk-api | https | `/api/admin/login`, `/api/admin/...` | DNS: `remot.dttb.ru` → public IP (через Cloudflare), внутри LAN → 10.0.0.195 (NPM). ## 10. Контакты на критические incidents - Сервер не отвечает > 10 минут → Олег батюшка - Все peers одновременно offline → проверить hbbs.log + LE cert + DNS - Брute-force попытки login (>100/час) → ban IP в NPM Access Lists или fail2ban - Утечка `id_ed25519` → НЕМЕДЛЕННЫЙ key rotation + reinstall всех клиентов с новым `RustDesk2.toml`