Краткий вывод: Для изолированного развертывания сигнального сервера hbbs и ретранслятора hbbr в Docker достаточно KVM-инстанса с 1 vCPU, 1 ГБ RAM, 15 ГБ NVMe и выделенным белым IPv4. Сетевая топология требует проброса портов 21115–21119 (TCP/UDP) для прямого P2P-соединения через STUN/NAT traversal, релейного TCP-фолбэка и включения TCP BBR на аплинке от 1 Гбит/с. Безопасность инфраструктуры обеспечивается обязательной принудительной авторизацией клиентов по закрытой связке открытых ключей Ed25519 (-k _), исключающей паразитный транзитный трафик через ваш релей.
Содержание
- Архитектура RustDesk Server: разделение ролей hbbs (Rendezvous) и hbbr (Relay)
- Аппаратные требования и сайзинг KVM VPS: расчет пропускной способности под 60 FPS
- Подготовка операционной системы: тюнинг ядра Linux, TCP BBR и настройка фаервола
- Установка собственного сервера RustDesk в Docker Compose с постоянным хранилищем
- Генерация, защита и ротация открытых ключей шифрования (ed25519)
- Конфигурация клиентов RustDesk: ручной ввод, автоматизация развертывания и брендирование
- Мониторинг, диагностика сетевых задержек и регламент аварийного восстановления (Disaster Recovery)
- Часто задаваемые вопросы (FAQ)
Архитектура RustDesk Server: разделение ролей hbbs (Rendezvous) и hbbr (Relay)
Архитектура собственного сервера RustDesk базируется на строгом разделении сигнального уровня и уровня передачи медиаданных между двумя независимыми бинарными демонами: hbbs (Heartbeat/ID Rendezvous server) и hbbr (Relay server). Подобная декомпозиция исключает влияние пиковых нагрузок видеотрафика на регистрацию клиентов и расчет сетевых маршрутов.
[ Client A (Controlling) ] [ Client B (Target) ]
| |
|-- 1. Heartbeat & ID Registration (UDP) --->|
| | |
+---------------> [ hbbs ] <-----------------+
| (Rendezvous / STUN) |
| | |
|<- 2. Peer Candidates / Hole Punch Signal ->|
| |
+----------+--------------------------------------------+----------+
| |
v v
[ Прямое соединение P2P ] [ Симметричный NAT / Сбой P2P ]
UDP Hole Punching успешен Сброс на резервный транспорт
Direct Socket: Client A <======== P2P Stream ========> Client B |
v
[ hbbr ]
(Relay Server)
|
Client A <=== Encrypted TCP ===+=== Encrypted TCP ===> Client B
Сигнальный демон hbbs: регистрация ID, Rendezvous и NAT traversal
Сервис hbbs выполняет функции координатора сетевого взаимодействия (Rendezvous) и легковесного STUN-сервера. Его жизненный цикл и логика обработки запросов включают три базовые задачи:
- Регистрация ID и отслеживание статуса (Heartbeat): Каждый клиент при старте инициирует периодический обмен пакетами
keepaliveс сервером. Демонhbbsсохраняет соответствие сгенерированного числового идентификатора клиента (RustDesk ID), его локального IP и текущего публичного сокета (IP:Port) в локальной базе данных SQLite или Redis. - Определение типа трансляции адресов (NAT Discovery): Выполняя процедуру, аналогичную RFC 5389 (STUN), демон сопоставляет входящий сокет пакета с адресом, указанным в полезной нагрузке клиентом. Это позволяет классифицировать топологию NAT клиента: Full Cone, Address-Restricted, Port-Restricted или наиболее проблемный Symmetric NAT.
- Координация P2P (NAT Hole Punching): При запросе сессии от управляющего узла к целевой машине
hbbsпередает обоим клиентам внешние и локальные сетевые координаты пира. Обе стороны синхронно начинают отправку встречных UDP-пакетов на полученные публичные порты. При взаимодействии через конусные типы NAT межсетевые экраны фиксируют исходящие сессии и открывают трансляцию для входящего трафика от удаленного пира, обеспечивая прямое одноранговое P2P-соединение с минимальной задержкой.
Ретранслятор hbbr: архитектура Relay-сессий при Symmetric NAT
Прямое P2P-соединение технически невозможно в сценариях, когда хотя бы один из клиентов находится за Symmetric NAT (где для каждого нового внешнего адреса назначения шлюз выделяет уникальный динамический порт трансляции), корпоративным DPI-фаерволом или CGNAT мобильного оператора без поддержки hairpining.
В момент фиксации тайм-аута пробития NAT демон hbbs отдает обоим хостам директиву переключения на резервный транспорт через hbbr (Relay server):
- Сквозная изоляция трафика (End-to-End Encryption): Демон
hbbrфункционирует исключительно как высокопроизводительный TCP-прокси. Сессия передается по защищенному транспортному протоколу, полезная нагрузка шифруется на стороне клиентов алгоритмами ChaCha20-Poly1305 или AES-256-GCM с асимметричным обменом ключами Ed25519. Сам ретранслятор не имеет криптографических ключей, не выполняет инспекцию пакетов и пересылает сырой видеопоток, аудиоданные и команды ввода вслепую. - Требования к пропускной способности: В отличие от сигнального
hbbs, потребляющего единицы килобайт в секунду, ретрансляторhbbrутилизирует полосу со скоростью до 8–25 Мбит/с на одну активную сессию (в зависимости от кодека VP8/VP9/AV1, разрешения экрана и частоты кадров).
Сетевая матрица: назначение TCP/UDP портов
Для корректной работы сервисов на внешнем межсетевом экране хоста (nftables, iptables, ufw) открывается строгий диапазон портов.
| Порт / Протокол | Демон | Вектор трафика | Тип протокола L4/L7 | Назначение и функциональная нагрузка |
|---|---|---|---|---|
| 21115 / TCP | hbbs |
Inbound | TCP / RustDesk API | Служебный шлюз авторизации, передача публичного ключа сервера, проверка лицензий и API-запросы |
| 21116 / UDP | hbbs |
Inbound | UDP / STUN-like | Детектирование внешнего сокета, NAT traversal, отправка зондов синхронизации и координация P2P hole punching |
| 21116 / TCP | hbbs |
Inbound | TCP / Signaling | Регистрация постоянного ID, сигнальный обмен статусами доступности (Heartbeat), передача команд управления |
| 21117 / TCP | hbbr |
Inbound | TCP / Encrypted Data | Транзитная ретрансляция медиапотока (видео, звук, клавиатурный/мышиный ввод, передача файлов) при недоступности P2P |
| 21118 / TCP | hbbs |
Inbound | TCP / WebSocket | Поддержка веб-клиента RustDesk Web Client (Rendezvous и сигнальный обмен через браузерные сокеты) |
| 21119 / TCP | hbbr |
Inbound | TCP / WebSocket | Поддержка веб-клиента RustDesk Web Client (ретрансляция медиапотока через защищенные WebSocket-соединения) |
Аппаратная платформа и сетевой стек гипервизора
Развертывание компонентов RustDesk на VPS требует предсказуемого выделения системных ресурсов и отсутствия скрытого троттлинга на уровне гипервизора.
Требуется полноценная аппаратная виртуализация KVM, так как контейнерные среды OpenVZ и LXC разделяют общее ядро с хостом, блокируют тонкую настройку сетевых очередей черезsysctl, модульtcp_bbrи гранулярное управление буферами сокетов в пространствах имен ядра.
При эксплуатации hbbr на инфраструктуре KVM VPS от tropic.host исключается узкое горлышко оверселлинга процессора: метрика CPU Steal Time поддерживается на уровне %st = 0.0%, что гарантирует выделенные такты CPU для непрерывного мультиплексирования сетевых сокетов без микрофризов потока. Задержка записи логов и транзакций баз данных клиентов нивелируется серверными NVMe-накопителями PCIe 4.0 со скоростью случайного чтения 4K QD1 свыше 50 000 IOPS.
Для поддержания частоты кадров 60 FPS на удаленных рабочих столах критична стабильность задержки передачи пакетов (latency p99 < 15–25 мс). Включение алгоритма контроля перегрузок TCP BBR в сочетании с прямыми аплинками 1–10 Гбит/с в узловых европейских и евразийских точках обмена трафиком (Франкфурт, Амстердам, Стамбул) на платформе tropic.host предотвращает буферблоат (bufferbloat) и просадку битрейта при параллельной передаче десятков тяжелых медиапотоков:
# Оптимизация сетевого стека Linux под высоконагруженный узел hbbs/hbbr
cat << 'EOF' > /etc/sysctl.d/99-rustdesk-performance.conf
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.netdev_max_backlog = 10000
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192
EOF
sysctl --system
Наличие чистого публичного IPv4-адреса без промежуточного провайдерского NAT исключает искажение портовых диапазонов при обработке запросов демоном hbbs, гарантируя максимальный процент успешных прямых P2P-сессий между клиентскими терминалами.
Аппаратные требования и сайзинг KVM VPS: расчет пропускной способности под 60 FPS
При сайзинге серверных мощностей под hbbs и hbbr архитектурно разделяются два типа сетевой нагрузки: сигнальный обмен (handshake, регистрация пиров, heartbeat) и транзитная передача медиапотока. Сигнальный трафик потребляет минимальные ресурсы, однако при невозможности установить прямое P2P-соединение (симметричный NAT, корпоративные фаерволы со строгим DPI) весь видеопоток направляется через релей hbbr. Развертывая собственный сервер RustDesk на VPS, необходимо учитывать, что видеокодеки H.264, VP9 и AV1 сжимают поток на мощностях клиентских устройств (аппаратные блоки NVENC, Intel QuickSync, Apple VideoToolbox, VA-API), тогда как серверный узел целиком берет на себя мультиплексирование сокетов и симметричный сетевой транзит.
Расчет полосы пропускания и профилирование видеокодеков
Для обеспечения частоты развертки 60 кадров в секунду (FPS) в разрешении 1080p потребление полосы на одну активную сессию варьируется от 1.5 до 8.0 Мбит/с. Итоговый битрейт напрямую зависит от сложности сцены и используемого кодека:
- H.264 (AVC): базовый кодек с минимальными аппаратными требованиями к клиентам. В статических офисных задачах требует 1.5–3.0 Мбит/с, но при быстром скроллинге, рендеринге 3D-интерфейсов или воспроизведении видео динамический битрейт возрастает до 6.0–8.0 Мбит/с для предотвращения артефактов блочности.
- VP9: обеспечивает выигрыш в сжатии на 30–35% по сравнению с H.264. Удерживает поток в пределах 2.0–4.5 Мбит/с при 60 FPS, сохраняя высокую четкость векторных шрифтов и мелких деталей UI.
- AV1: наиболее эффективный открытый алгоритм компрессии. Снижает битрейт до 1.5–3.2 Мбит/с при сохранении эталонного качества 1080p@60FPS, минимизируя нагрузку на канал релея при условии наличия аппаратного ускорения AV1 на рабочих станциях.
Математическая модель расчета необходимой серверной полосы пропускания:
$$BW_{total} = \left( \sum_{i=1}^{N_{relay}} (Bitrate_{avg} \times K_{burst}) \right) \times 2$$
где: * $N_{relay}$ — число сессий, принудительно маршрутизируемых через hbbr (на практике составляет 15–30% от общего пула подключений при наличии чистого публичного IP у сервера); * $Bitrate_{avg}$ — средний битрейт используемого видеокодека (базовый расчет: 4.5 Мбит/с для H.264/VP9); * $K_{burst} \approx 1.25$ — коэффициент пиковых всплесков при резкой смене содержимого экрана и передаче ключевых кадров (I-frames); * $\times 2$ — коэффициент дуплексного транзита (сетевой интерфейс сервера одновременно принимает входящий трафик от хоста и отдает исходящий трафик клиенту).
Для пула из 20 активных релей-сессий на кодеке H.264 пиковая утилизация сетевого адаптера составит: $20 \times (4.5 \times 1.25) \times 2 = 225\text{ Мбит/с}$ чистого транзитного трафика без учета накладных расходов TCP/IP-заголовков.
Влияние планировщика процессора и CPU Steal Time на задержку ввода
Несмотря на то что hbbr не декодирует видеопоток, мультиплексирование сотен соединений через системный вызов epoll критично к задержкам переключения контекста ядра Linux. В отличие от контейнерных сред OpenVZ/LXC, где общие таблицы очередей ядра приводят к непредсказуемым задержкам обработки системных прерываний сетевой карты (ksoftirqd), аппаратная виртуализация KVM гарантирует изоляцию адресного пространства и вычислительных потоков.
На виртуальных серверах tropic.host за счет честного сайзинга без оверселлинга процессорных ресурсов метрика CPU Steal Time поддерживается на уровне %st = 0.0%. Это исключает ситуации, когда гипервизор отбирает процессорные такты у vCPU для обслуживания соседних виртуальных машин. Даже 1.5–2% паразитного Steal Time вызывают рассинхронизацию очередей пакетов в кольцевом буфере NIC, приводя к джиттеру (jitter) и микрофризам кадров.
Кадровый интервал при 60 FPS составляет всего 16.6 мс. Если суммарный сетевой джиттер и задержка передачи превышают этот интервал, оператор сталкивается с ощутимым аппаратным отставанием курсора (input lag). Выделенные аплинки 1–10 Гбит/с с включенным алгоритмом контроля перегрузок TCP BBR на площадках tropic.host обеспечивают прямое BGP-соседство с крупнейшими европейскими точками обмена трафиком (DE-CIX во Франкфурте, AMS-IX в Амстердаме). Это удерживает сетевую задержку на уровне p99 < 15–25 мс, гарантируя мгновенный отклик периферии.
Оперативная память под нужды hbbs/hbbr выделяется из расчета 3–5 МБ на одно активное соединение с учетом сетевых буферов сокетов ядра (rmem/wmem). Высокоскоростные серверные NVMe-накопители PCIe 4.0 со скоростью случайного доступа 4K QD1 свыше 50 000 IOPS полностью исключают просадки дисковой подсистемы (iowait = 0.0%) при интенсивной записи audit-логов, транзакций авторизации операторов и синхронизации SQLite/PostgreSQL.
Сравнительная матрица сайзинга ноды под нагрузку
В таблице представлены расчетные параметры инфраструктуры под разный объем параллельных сессий. Спецификации приведены с учетом 25%-ной доли релейного трафика (hbbr) от общего объема соединений:
| Число активных сессий (P2P + Relay) | Расчетная полоса релея (дуплекс) | Рекомендуемые vCPU / RAM | Требования к накопителю (IOPS) | Сетевой интерфейс | Конфигурация инстанса tropic.host |
|---|---|---|---|---|---|
| 5–15 сессий (1–4 Relay) | до 45 Мбит/с | 1–2 vCPU / 2 GB RAM | NVMe PCIe 4.0 (50k+ IOPS) | 1 Гбит/с (BBR, p99 < 20 мс) | Starter KVM (1 vCPU, 2 GB RAM, 30 GB NVMe) |
| 15–40 сессий (4–10 Relay) | 45–115 Мбит/с | 2–4 vCPU / 4 GB RAM | NVMe PCIe 4.0 (50k+ IOPS) | 1 Гбит/с (BBR, p99 < 20 мс) | Standard KVM (2 vCPU, 4 GB RAM, 50 GB NVMe) |
| 40–100 сессий (10–25 Relay) | 115–285 Мбит/с | 4–8 vCPU / 8 GB RAM | Enterprise NVMe (High TBW) | 1–2.5 Гбит/с (BBR, p99 < 15 мс) | Pro KVM (4 vCPU, 8 GB RAM, 100 GB NVMe) |
| 100+ сессий (25–60+ Relay) | от 300 до 700+ Мбит/с | 8–16 vCPU / 16 GB RAM | Enterprise NVMe RAID10 | 10 Гбит/с uplink (BBR, L3/L4 DDoS Guard) | Enterprise High-Freq (8–16 vCPU, 16+ GB RAM) |
Подготовка операционной системы: тюнинг ядра Linux, TCP BBR и настройка фаервола
Стандартный профиль сетевого стека в дистрибутивах Linux (Ubuntu 24.04 LTS, Debian 12) рассчитан на обслуживание типичного веб-трафика с короткими сессиями и статическим контентом. При развертывании инфраструктуры RustDesk на VPS под плотные видеопотоки с переменным битрейтом (VBR) и жесткими лимитами по задержке ввода дефолтные параметры ядра вызывают деградацию сессий: дропы входящих UDP-пакетов при пробиве NAT (hole punching) и скачки задержки при ретрансляции кадров через TCP-релей. Для модификации сетевых буферов и смены алгоритмов диспетчеризации очередей требуется аппаратная виртуализация KVM, так как в контейнерных средах OpenVZ/LXC доступ к управлению модулями ядра заблокирован на уровне хостового гипервизора.
На инстансах tropic.host с чистой KVM-архитектурой и нулевым троттлингом процессора (%st = 0.0%) системные вызовы ядра отрабатывают без задержек планировщика, что позволяет выжать максимум из выделенного сетевого интерфейса.
Активация алгоритма TCP BBR и планировщика fq
Штатный алгоритм контроля перегрузок TCP CUBIC интерпретирует единичную потерю пакета на транзитном узле как сигнал перегрузки канала и моментально уменьшает размер окна передачи (CWND) вдвое. В интерактивном стриминге удаленного рабочего стола это приводит к просадке FPS, заиканию звука и временной пикселизации картинки.
Алгоритм tcp_bbr (Bottleneck Bandwidth and RTT) непрерывно измеряет фактическую пропускную способность узкого места и минимальное время кругового обращения (RTT) пакета независимо от процента потерь. В связке с планировщиком пакетов fq (Fair Queueing) BBR устраняет проблему раздувания очередей на сетевых интерфейсах (bufferbloat), сглаживая пакетный трафик на исходящем аплинке.
Загрузка модуля ядра:
# Проверка и загрузка модуля BBR
sudo modprobe tcp_bbr
echo "tcp_bbr" | sudo tee /etc/modules-load.d/bbr.conf
# Проверка статуса загрузки
lsmod | grep bbr
Увеличение системных буферов сокетов ядра
Стандартный максимальный размер буферов сокетов в Linux (rmem_max и wmem_max — около 212 КБ) не справляется с передачей высокоскоростного несжатого экранного видеопотока в разрешении 2K/4K при 60 FPS. Когда буфер сокета переполняется быстрее, чем сервис считывает фрейм, ядро сбрасывает пакеты, вызывая сбои в декодере клиента.
Для конфигурации RustDesk Relay VPS создается выделенный конфигурационный файл в директории /etc/sysctl.d/, переопределяющий базовые директивы /etc/sysctl.conf:
sudo nano /etc/sysctl.d/99-rustdesk-performance.conf
В файл вносится следующий блок оптимизации сетевого стека:
# /etc/sysctl.d/99-rustdesk-performance.conf
# Активация BBR и дисциплины очереди Fair Queueing
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# Увеличение максимального размера системных буферов сокетов (до 64 МБ)
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
# Автоподстройка TCP-буферов: min (4 КБ), default (87 КБ), max (32 МБ)
net.ipv4.tcp_rmem = 4096 87380 33554432
net.ipv4.tcp_wmem = 4096 65536 33554432
# Выделение буферов под UDP-дейтаграммы (критично для сигнального сервера hbbs)
net.ipv4.udp_rmem_min = 16384
net.ipv4.udp_wmem_min = 16384
# Увеличение глубины входной очереди пакетов на сетевом драйвере
net.core.netdev_max_backlog = 10000
# Лимит очереди ожидающих соединений (backlog сокета)
net.core.somaxconn = 65535
# Оптимизация работы с сокетами в состоянии TIME_WAIT
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.ip_local_port_range = 10240 65535
# Отключение медленного старта после простоя для предотвращения микрофризов при стриминге
net.ipv4.tcp_slow_start_after_idle = 0
Применение конфигурации в пространстве ядра без перезагрузки сервера:
sudo sysctl --system
Проверка фактического применения настроек:
sysctl net.ipv4.tcp_congestion_control net.core.default_qdisc net.core.rmem_max net.core.wmem_max
Команда должна вернуть статус алгоритма bbr, планировщика fq и значение буферов 67108864.
Конфигурация межсетевого экрана (UFW и nftables)
Архитектура RustDesk разделена на сигнальный сервер (hbbs) и релей передачи медиаданных (hbbr). Для работы протоколов требуется прямое открытие выделенных портов на внешнем сетевом интерфейсе. Использование промежуточных трансляторов адресов (DNAT/SNAT) или обратных прокси (reverse proxy) для бинарного трафика исключается, так как это нарушает прямое определение удаленных сокетов клиентами и увеличивает задержку маршрутизации.
Сетевая матрица портов RustDesk:
21115/tcp:hbbs— определение типа NAT у клиента (NAT type test);21116/tcp:hbbs— TCP-сигналинг и управление подключениями;21116/udp:hbbs— критический порт регистрации ID, heartbeat и пробива NAT (hole punching);21117/tcp:hbbr— транзитная передача видео- и аудиопотока сессии (relay);21118/tcpи21119/tcp: опциональные порты веб-сокетов для работы встроенного веб-клиента RustDesk (соответственно дляhbbsиhbbr).
Настройка правил фильтрации через ufw:
# Сброс базовой политики: блокировка всех входящих соединений, разрешение исходящих
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Порт удаленного управления SSH
sudo ufw allow 22/tcp comment 'SSH'
# Порты сигнального сервиса hbbs
sudo ufw allow 21115/tcp comment 'RustDesk NAT test'
sudo ufw allow 21116/tcp comment 'RustDesk Signal TCP'
sudo ufw allow 21116/udp comment 'RustDesk Signal/Heartbeat UDP'
# Порт сервиса ретрансляции hbbr
sudo ufw allow 21117/tcp comment 'RustDesk Relay TCP'
# Порты для веб-клиента (опционально)
sudo ufw allow 21118/tcp comment 'RustDesk Web Console'
sudo ufw allow 21119/tcp comment 'RustDesk Web Relay'
# Применение правил
sudo ufw enable
sudo ufw status numbered
Для высоконагруженных шлюзов с сотнями одновременных релей-сессий рекомендуется использовать низкоуровневый nftables. Это снижает накладные расходы ядра на обработку очередей conntrack при бомбардировке порта 21116/udp тысячами дейтаграмм:
# Добавление нативных правил в цепочку input таблицы inet filter
sudo nft add rule inet filter input tcp dport { 21115, 21116, 21117, 21118, 21119 } counter accept
sudo nft add rule inet filter input udp dport 21116 counter accept
Диагностика сетевых сокетов и валидация публичного адреса
Перед развертыванием контейнеров или бинарных файлов сервиса выполняется проверка чистоты сетевых портов от сторонних демонов:
# Сканирование слушающих сокетов
ss -tulpn | grep -E '21115|21116|21117|21118|21119'
Если утилита ss возвращает пустой вывод, конфликтующие процессы отсутствуют, и порты готовы к связыванию (bind) сервисами hbbs и hbbr.
Завершающий этап — проверка маршрутизации внешнего интерфейса. На ноде должен присутствовать выделенный публичный статический IPv4-адрес без операторского CGNAT:
curl -4 -s https://ipinfo.io/json
Параметры ip, org и city должны соответствовать выбранной локации ноды (например, ключевым европейским узлам обмена трафиком во Франкфурте или Амстердаме на инфраструктуре tropic.host). Прямое подключение к магистральным аплинкам 1–10 Гбит/с с активированным BBR обеспечивает стабильные сетевые задержки $p99 < 15\text{--}20\text{ мс}$ и исключает потери кадров при пиковом битрейте. После завершения тюнинга ядра операционная система полностью подготовлена к установке серверного стека RustDesk.
Установка собственного сервера RustDesk в Docker Compose с постоянным хранилищем
Развертывание сигнального (hbbs) и ретрансляционного (hbbr) сервисов для эксплуатации RustDesk на VPS в изолированном контейнерном окружении устраняет конфликты разделяемых системных библиотек и гарантирует переносимость состояния ноды. Для сохранения криптографических ключей хоста (id_ed25519, id_ed25519.pub), локальных баз SQLite и конфигураций пиров критически важна организация volume persistence — монтирование выделенной директории хост-системы в контейнеры.
Создание структуры каталогов для хранения манифеста и персистентных данных:
sudo mkdir -p /opt/rustdesk-server/data
cd /opt/rustdesk-server
Выбор сетевого стека: Host Network против Docker Bridge
При установке RustDesk Server в Docker ключевым архитектурным решением является конфигурация сетевого интерфейса. Использование стандартного виртуального моста (bridge) сопряжено с серьезным оверхедом: трансляция входящего UDP-потока на порт 21116/udp заставляет ядро задействовать пользовательский процесс docker-proxy и правила iptables цепочки POSTROUTING/MASQUERADE. При параллельной передаче десятков сессий с тяжелым видеотрафиком это кратно увеличивает нагрузку на подсистему conntrack и приводит к микрофризам интерфейса.
Директива network_mode: 'host' подключает контейнеры напрямую к сетевому пространству имен (network namespace) хоста. Демоны hbbs и hbbr связываются с сокетами физического сетевого интерфейса без инкапсуляции трафика в виртуальные пары veth.
Если изоляция на уровне bridged-сети является обязательным требованием корпоративной политики безопасности, порты маппируются строго один к одному с обязательным разделением протоколов TCP и UDP.
Конфигурация манифеста docker-compose.yml
В рабочей директории /opt/rustdesk-server формируется файл docker-compose.yml. В аргументах вызова демона hbbs обязательно передается флаг -r с указанием внешнего публичного адреса ноды и порта ретранслятора (21117), а также флаг -k _, принудительно активирующий шифрование сессий:
services:
hbbs:
image: rustdesk/rustdesk-server:latest
container_name: rustdesk-hbbs
restart: unless-stopped
network_mode: host
command: hbbs -r 198.51.100.1:21117 -k _
volumes:
- ./data:/root
depends_on:
- hbbr
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
hbbr:
image: rustdesk/rustdesk-server:latest
container_name: rustdesk-hbbr
restart: unless-stopped
network_mode: host
command: hbbr -k _
volumes:
- ./data:/root
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
Параметры конфигурации: * command: hbbs -r 198.51.100.1:21117 -k _ — передает клиентам маршрут к relay-серверу. Вместо статического IPv4 допускается использование FQDN (например, relay.yourdomain.com:21117). Аргумент -k _ инструктирует hbbs генерировать пару ключей при старте и требовать совпадения публичного ключа у всех подключающихся клиентов, блокируя неавторизованный транзитный трафик через ваш сервер. * restart: unless-stopped — декларативная restart policy, гарантирующая автозапуск сервисов демоном dockerd после перезагрузки ОС хоста или сбоя процесса. * volumes: ./data:/root — реализация volume persistence: официальный образ rustdesk/rustdesk-server работает в каталоге /root, куда записывает ключи шифрования Ed25519 и файлы базы данных. * Альтернативный сетевой блок (при отказе от host network в пользу моста):
# Вместо network_mode: host
ports:
- "21115:21115/tcp"
- "21116:21116/tcp"
- "21116:21116/udp"
- "21117:21117/tcp"
- "21118:21118/tcp"
- "21119:21119/tcp"
При работе под постоянным медиапотоком аппаратная база сервера определяет стабильность трансляции. Развертывание стека на KVM VPS инфраструктуре tropic.host гарантирует нулевой CPU Steal Time (%st = 0.0%), предотвращая задержки шедулера Linux при кодировании кадров. Серверные накопители NVMe PCIe 4.0 со скоростью случайного чтения 4K QD1 свыше 50 000 IOPS исключают блокировки ввода-вывода при одновременной записи логов и аутентификации пиров в базе данных. Прямые каналы 1–10 Гбит/с в локациях Франкфурта, Амстердама и Стамбула с активированным алгоритмом TCP BBR удерживают сетевую задержку $p99 < 15\text{--}25\text{ мс}$, что критично для интерактивного удаленного управления без джиттера.
Инициализация сервисов и валидация ключевой пары
Запуск демонов в изолированных пространствах cgroups выполняется с помощью Docker Compose:
docker compose up -d
Контроль процесса связывания портов и отсутствия системных ошибок в реальном времени осуществляется через чтение агрегированного лога:
docker compose logs -f
Корректный запуск сопровождается выводом о старте прослушивания сокетов на портах 21115–21117:
rustdesk-hbbr | [2026-10-04 06:12:01.120] INFO [src/relay_server.rs:48] #Starting hbbr
rustdesk-hbbr | [2026-10-04 06:12:01.121] INFO [src/relay_server.rs:50] #Listening on tcp :21117
rustdesk-hbbs | [2026-10-04 06:12:01.128] INFO [src/rendezvous_server.rs:88] #Starting hbbs
rustdesk-hbbs | [2026-10-04 06:12:01.129] INFO [src/rendezvous_server.rs:90] #Listening on tcp/udp :21116
rustdesk-hbbs | [2026-10-04 06:12:01.129] INFO [src/rendezvous_server.rs:92] #Listening on tcp :21115
При первичном старте hbbs автоматически генерирует в постоянном хранилище криптографические ключи Ed25519. Валидация созданных артефактов в каталоге хоста:
ls -la /opt/rustdesk-server/data/
Файл id_ed25519 содержит закрытый ключ сервера, а id_ed25519.pub — открытый ключ, необходимый для настройки клиентов:
cat /opt/rustdesk-server/data/id_ed25519.pub
Строку из полученного вывода (base64-хэш ключа) необходимо скопировать для дальнейшего внесения в конфигурацию клиентов наряду с IP-адресом сервера.
Проверка потребления ресурсов изолированными cgroups-контроллерами контейнеров:
docker stats --no-stream
В штатном режиме демоны потребляют менее 30 МБ оперативной памяти и около 0.1% CPU в режиме ожидания, подтверждая минимальные накладные расходы нативного Rust-кода. Инстанс готов к настройке механизмов безопасности, фильтрации трафика и подключению клиентских приложений.
Генерация, защита и ротация открытых ключей шифрования (ed25519)
Автоматически сгенерированная при первом запуске связка ключей в /opt/rustdesk-server/data/ по умолчанию не блокирует входящие анонимные соединения. Без жесткой фиксации открытого ключа сервер работает в режиме Open Relay: любой сторонний клиент, просканировавший публичный IPv4-адрес и обнаруживший порты 21115–21117, может бесплатно маршрутизировать через чужую инфраструктуру свой видеопоток. Кроме того, сессии без криптографической аутентификации сервера уязвимы к атакам перехвата и подмены трафика (MITM).
Для изоляции инстанса от неавторизованных пользователей и защиты каналов управления внедряется принудительное сквозное шифрование (mandatory encryption) на базе алгоритма Ed25519.
Механика криптографической пары Ed25519
Криптосистема RustDesk построена на асимметричной схеме с использованием эллиптической кривой Curve25519 (Ed25519):
id_ed25519— закрытый ключ (32-байтный приватный seed). Хранится исключительно на сервере в постоянном хранилище хоста. Демоныhbbsиhbbrиспользуют его для аутентификации узла в процессе криптографического рукопожатия (handshake) и согласования сессионных симметричных ключей ChaCha20-Poly1305. Компрометация этого файла позволяет злоумышленнику развернуть фальшивый сервер-двойник.id_ed25519.pub— открытый ключ (публичная часть), закодированный в формат Base64. Передается операторам и жестко зашивается в настройки доверенных клиентских приложений. Если публичный ключ клиента не совпадает с сигнатурой, выдаваемой сервером при установлении TCP-сессии на порту21116, соединение немедленно сбрасывается с кодом ошибки криптографической проверки.
Права доступа к файлам на диске хоста должны строго ограничивать чтение непривилегированными пользователями:
chmod 600 /opt/rustdesk-server/data/id_ed25519
chmod 644 /opt/rustdesk-server/data/id_ed25519.pub
Принудительный запрет незашифрованных сессий через флаг -k _
Чтобы перевести демоны в режим обязательного шифрования, для сервисов hbbs и hbbr задается аргумент командной строки -k _. Символ подчеркивания указывает бинарному файлу считывать приватный ключ непосредственно из текущей рабочей директории (каталога /root внутри контейнера, куда смонтирован том хоста ./data), запрещая любые транзитные соединения без валидного клиентского ключа.
В архитектуре RustDesk настройка relay и rendezvous сервисов на принудительную авторизацию вносится непосредственно в конфигурацию декларативного манифеста docker-compose.yml:
services:
hbbs:
container_name: rustdesk-hbbs
image: rustdesk/rustdesk-server:latest
command: hbbs -k _
volumes:
- ./data:/root
network_mode: host
restart: unless-stopped
depends_on:
- hbbr
hbbr:
container_name: rustdesk-hbbr
image: rustdesk/rustdesk-server:latest
command: hbbr -k _
volumes:
- ./data:/root
network_mode: host
restart: unless-stopped
Применение обновленных параметров запуска:
cd /opt/rustdesk-server
docker compose up -d --force-recreate
После перезапуска hbbr перестает принимать запросы на ретрансляцию от клиентов, у которых не задан публичный ключ, а hbbs отклоняет регистрацию ID-нод в Rendezvous-таблице без цифровой подписи.
Экспорт ключа и генерация конфигурационной строки для операторов
Для подключения клиентов требуется передать три параметра: публичный IPv4-адрес сервера, порт службы Rendezvous (21116) и строковое значение из id_ed25519.pub.
Надежным инфраструктурным фундаментом при эксплуатации RustDesk на VPS выступает платформа tropic.host с аппаратной виртуализацией KVM, где исключен оверселлинг процессорных мощностей (%st = 0.0%), а серверные NVMe-диски PCIe 4.0 обеспечивают быстрый I/O без блокировок. Наличие чистых статических IPv4-адресов без промежуточных операторских NAT-шлюзов и сетевой стек с поддержкой TCP BBR в узловых европейских точках (Франкфурт, Амстердам) минимизируют джиттер и удерживают latency p99 в пределах 15–25 мс при пиковых нагрузках на Relay.
Для автоматического формирования готовой конфигурационной строки оператора используется Bash-однострочник:
PUB_KEY=$(cat /opt/rustdesk-server/data/id_ed25519.pub)
SERVER_IP=$(curl -s -4 https://ifconfig.me)
echo "=== КОНФИГУРАЦИЯ RUSTDESK ДЛЯ КЛИЕНТОВ ==="
echo "ID/Rendezvous Server: ${SERVER_IP}:21116"
echo "Relay Server: ${SERVER_IP}:21117"
echo "API Server: http://${SERVER_IP}:21114"
echo "Key (Public): ${PUB_KEY}"
echo "=========================================="
echo "Строка быстрого импорта (RustDesk Config String):"
echo "host=${SERVER_IP},key=${PUB_KEY}"
Клиент RustDesk поддерживает автоматическую настройку через передачу параметров в имени запускаемого исполняемого файла или через прямое указание строки host=IP,key=PUBKEY в графическом интерфейсе раздела «Сеть» -> «Пользовательский сервер».
Регламент плановой ротации ключей и отзыв доступа
В рамках требований корпоративной безопасности криптографическая пара Ed25519 подлежит регламентной ротации каждые 180 дней, а также внеплановой процедуре в случае компрометации приватного ключа или увольнения привилегированных сетевых инженеров.
Смена ключа приводит к мгновенному разрыву всех активных клиентских сессий и отсекает клиентов со старым id_ed25519.pub.
Порядок безопасной перегенерации ключей:
- Создание резервной копии текущего набора:
mkdir -p /opt/rustdesk-server/backups/keys-$(date +%F)
cp /opt/rustdesk-server/data/id_ed25519* /opt/rustdesk-server/backups/keys-$(date +%F)/
chmod 700 /opt/rustdesk-server/backups/keys-$(date +%F)
- Остановка сервисов и удаление устаревших ключей:
cd /opt/rustdesk-server
docker compose down
rm -f /opt/rustdesk-server/data/id_ed25519 /opt/rustdesk-server/data/id_ed25519.pub
- Генерация новой пары Ed25519 через запуск инстанса:
При инициализации hbbs обнаруживает отсутствие криптографических файлов в точке монтирования и обращается к системному генератору энтропии ядра Linux (/dev/urandom), создавая свежую пару ключей:
docker compose up -d
- Проверка прав и извлечение нового открытого ключа:
chmod 600 /opt/rustdesk-server/data/id_ed25519
NEW_PUB_KEY=$(cat /opt/rustdesk-server/data/id_ed25519.pub)
echo "Новый открытый ключ Ed25519: ${NEW_PUB_KEY}"
- Валидация отсечения неавторизованных запросов в журнале событий:
Попытки подключения клиентов со старыми ключами фиксируются в логе Rendezvous-сервера:
docker compose logs --tail=100 hbbs | grep -i "key"
Присутствие записей с ошибками криптографической верификации подтверждает работоспособность политики mandatory encryption: узел игнорирует нелегитимные запросы, сохраняя сетевую полосу и ресурсы CPU хоста под задачи авторизованных операторов.
Конфигурация клиентов RustDesk: ручной ввод, автоматизация развертывания и брендирование
Сгенерированный открытый ключ id_ed25519.pub в связке с внешним FQDN или публичным IPv4-адресом формирует доверенный криптографический профиль, необходимый для авторизации парка клиентских устройств на собственном сервере. Любой клиент RustDesk, у которого не прописан данный публичный ключ, будет безусловно отсекаться сервисом hbbs еще на этапе первичного сетевого рукопожатия (handshake) по протоколу UDP, что исключает несанкционированную утилизацию вычислительных мощностей и сетевого интерфейса хоста.
Ручная настройка десктопного клиента через GUI
Первичная валидация сетевой связности и криптографического контура выполняется через штатный графический интерфейс клиента. На рабочей станции откройте главное окно программы и перейдите по пути: Настройки (три точки) → Сеть → Разблокировать настройки сети.
Параметры сетевого профиля распределяются по следующим полям:
- Сервер ID (ID Server): FQDN или IPv4-адрес сервера (например,
relay.company.ltd). Порт по умолчанию —21116/TCP/UDP. Демонhbbsиспользует его для регистрации пиров, проверки доступности (heartbeat) и трансляции NAT-маппинга (STUN). - Сервер Relay (Relay Server): Адрес проксирующего узла
hbbr(порт21117/TCP). Если оба демона работают на одном физическом или виртуальном инстансе под общим доменным именем, отдельное указание порта допустимо опустить, однако явное определениеrelay.company.ltd:21117предотвращает лишние итерации опроса портов. - Сервер API (API Server): Эндпоинт централизованной адресной книги и веб-консоли управления (порты
21114/TCPили стандартный443/TCPпри терминации TLS через Nginx/Traefik). При использовании open-source редакции без стороннего веб-бэкенда поле оставляется пустым. - Ключ (Key): Значение публичного ключа из файла
/opt/rustdesk-server/data/id_ed25519.pub. Клиент применяет его для проверки подлинности узла Rendezvous и согласования сессионных ключей шифрования трафика.
При эксплуатации связки клиентов и инстанса RustDesk на VPS критическое значение имеет стабильность аплинка и сетевая задержка. Размещение серверной части на KVM-инфраструктуре tropic.host с прямым подключением к ключевым европейским точкам обмена трафиком (Франкфурт, Амстердам) и включенным алгоритмом контроля перегрузок TCP BBR обеспечивает сетевую задержку p99 < 15–20 мс. Нулевой оверселлинг процессора (%st = 0.0%) гарантирует отсутствие микрофризов при кодировании/декодировании видеопотока, удерживая стабильные 60 FPS в сессиях прямого и ретранслируемого удаленного доступа.
+-------------------------------------------------------------------------+
| RustDesk GUI |
+-------------------------------------------------------------------------+
| [ Сеть: Разблокировано ] |
| |
| ID/Relay Server: [ relay.company.ltd ] |
| Relay Server: [ relay.company.ltd:21117 ] |
| API Server: [ https://relay.company.ltd ] |
| Key: [ 4F8a+K9z1X...[88 символов Ed25519]...mP0= ] |
| |
| Статус: [ Готов ] (Зеленый индикатор в левом нижнем углу окна) |
+-------------------------------------------------------------------------+
Индикатором корректности параметров служит смена статуса в нижнем статус-баре на «Готов» с зеленой маркировкой. Ошибка «Не готов. Пожалуйста, проверьте настройки сети» сигнализирует о блокировке портов 21115-21117 межсетевым экраном, несоответствии открытого ключа или отсутствии PTR-записи у провайдера.
Формирование закодированной строки конфигурации (Host-Key Payload)
Для исключения ошибок операторов при ручном вводе длинных криптографических хешей клиент RustDesk поддерживает импорт сетевого профиля в виде сжатой строки payload. Формат строки представляет собой JSON-объект, содержащий директивы подключения, закодированный по стандарту Base64 (без переводов строк).
Скрипт генерации импортируемой конфигурационной строки на стороне сервера:
#!/usr/bin/env bash
set -euo pipefail
# Конфигурационные параметры хоста
DOMAIN="relay.company.ltd"
PUB_KEY_PATH="/opt/rustdesk-server/data/id_ed25519.pub"
API_URL="https://${DOMAIN}"
if [[ ! -f "${PUB_KEY_PATH}" ]]; then
echo "Критическая ошибка: файл ключа ${PUB_KEY_PATH} не найден." >&2
exit 1
fi
KEY_VALUE=$(tr -d '\r\n' < "${PUB_KEY_PATH}")
# Сборка JSON и кодирование в Base64
PAYLOAD=$(printf '{"host":"%s","key":"%s","api":"%s"}' \
"${DOMAIN}" \
"${KEY_VALUE}" \
"${API_URL}" | base64 -w 0)
echo "================================================================="
echo "Строка конфигурации RustDesk (Вставить в поле 'Конфигурация'):"
echo "${PAYLOAD}"
echo "================================================================="
Применение в клиенте: 1. В интерфейсе Настройки → Сеть нажмите кнопку «Вставить конфигурацию сервера» (или вручную поместите сгенерированный Base64-код в поле ввода конфигурации). 2. Клиент мгновенно десериализует параметры, заполняя адреса ID/Relay Server, порт hbbr и открытый ключ. Нажмите «Применить».
Сравнительный анализ методов доставки конфигурации
Выбор метода доставки настроек на конечные узлы определяется масштабом инфраструктуры, требованиями к прозрачности развертывания для пользователей и наличием доменной службы каталогов.
| Метод развертывания | Поддерживаемые ОС | Механизм передачи параметров | Поддержка Silent-установки | Рекомендованный сценарий |
|---|---|---|---|---|
| Ручной ввод через GUI | Windows, macOS, Linux, Android, iOS | Интерактивный ввод значений в диалоговые поля сетевого интерфейса | Нет (требует прямого участия пользователя) | Тестовые стенды, личные устройства внешних контрагентов, аудит связи |
| Base64 Payload-строка | Все платформы | Буфер обмена / глубокая ссылка (deep link) с десериализацией JSON | Частично (один клик в интерфейсе приложения) | Быстрый онбординг сотрудников на удаленке (BYOD), поддержка через мессенджеры |
| Инъекция параметров в имя файла (.exe) | Windows | Парсинг собственного имени бинарного файла (GetModuleFileNameW) |
Да (параметры подхватываются при первом запуске) | Массовая неконтролируемая рассылка сотрудникам без Active Directory |
| MSI кастомизация + GPO | Windows | Трансформация MST, свойства установщика (msiexec property) |
Полная (фоновая установка учетной записью NT AUTHORITY\SYSTEM) |
Корпоративные домены Active Directory, SCCM, Microsoft Intune |
| Монтирование файлов конфигурации | Linux, macOS | Запись структуры TOML в системные каталоги (/etc/rustdesk/) |
Полная (через Ansible, Puppet, SaltStack, Jamf MDM) | Серверные фермы Linux, рабочие станции разработчиков, корпоративный парк Mac |
| Auto-Discovery (mDNS) | Windows, macOS, Linux | Широковещательный поиск в пределах L2 broadcast-домена (UDP 21119) | Не применимо (динамическое обнаружение хостов) | Изолированные сегменты локальной сети без доступа в глобальный Интернет |
Кастомизация инсталлятора под Windows: инъекция параметров в имя файла
Клиент RustDesk для Windows обладает встроенным модулем разбора собственного имени исполняемого файла при старте процесса инсталляции. Если переименовать дистрибутив по строгому шаблону, установщик автоматически извлечет сетевые параметры и применит их без вызова диалоговых окон.
Синтаксическая схема именования:
rustdesk-host=<HOST_FQDN_OR_IP>,key=<PUBLIC_KEY_STRING>,api=<API_URL>.exe
Нюансы синтаксиса: * Символ запятой , выступает строгим разделителем пар ключ=значение. * Если ключ Ed25519 содержит на конце знак равенства =, клиент корректно обрабатывает экранирование, однако безопаснее передавать строку без завершающих спецсимволов, если они обрезаются на уровне файловых менеджеров. * Пример рабочего имени файла: text rustdesk-host=relay.company.ltd,key=4F8a+K9z1X5mP0aL2vQ8wE3rT6yU9iO2pA4sD7fG1hJ=.exe
При запуске такого файла портативная версия либо процесс установки сразу подключаются к указанному ID/Relay Server. Метод оптимален для сценария QuickSupport, когда неквалифицированному пользователю отправляется готовый бинарник.
Корпоративное GPO развертывание и MSI кастомизация
Для enterprise-контуров под управлением Active Directory применяется распространение софта через групповые политики (GPO). Официальный MSI-пакет RustDesk поддерживает передачу параметров командной строки через утилиту msiexec.
1. Тихая установка через командную строку
Команда для SCCM/MDT/тихой установки:
msiexec.exe /i "rustdesk.msi" ^
HOST="relay.company.ltd" ^
KEY="4F8a+K9z1X5mP0aL2vQ8wE3rT6yU9iO2pA4sD7fG1hJ=" ^
/qn /norestart /log "C:\Windows\Temp\rustdesk_install.log"
2. Доставка конфигурации через доменный реестр и файл RustDesk2.toml
В современных версиях RustDesk служба Windows Service исполняется от имени системной учетной записи NT AUTHORITY\SYSTEM или локального пользователя, храня конфигурацию в профиле: * Системный профиль службы: C:\Windows\ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\RustDesk2.toml * Пользовательский профиль: %APPDATA%\RustDesk\config\RustDesk2.toml
PowerShell-скрипт для централизованного применения настроек (назначается как Startup Script в GPO):
<#
.SYNOPSIS
Автоматическое конфигурирование клиента RustDesk через GPO Startup Script
#>
[CmdletBinding()]
param (
[string]$RelayHost = "relay.company.ltd",
[string]$PublicKey = "4F8a+K9z1X5mP0aL2vQ8wE3rT6yU9iO2pA4sD7fG1hJ=",
[string]$ApiServer = "https://relay.company.ltd"
)
$ErrorActionPreference = "Stop"
# Пути к файлам конфигурации
$Paths = @(
"$env:ProgramData\RustDesk\config\RustDesk2.toml",
"$env:SystemRoot\ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\RustDesk2.toml"
)
# Формирование структуры конфигурации TOML
$TomlContent = @"
rendezvous_server = '$RelayHost'
relay_server = '$RelayHost:21117'
api_server = '$ApiServer'
key = '$PublicKey'
allow_remote_config = false
verification_method = 'use-permanent-password'
"@
foreach ($ConfigPath in $Paths) {
$Directory = Split-Path -Path $ConfigPath -Parent
if (!(Test-Path -Path $Directory)) {
New-Item -ItemType Directory -Path $Directory -Force | Out-Null
}
# Атомарная запись конфигурации
Set-Content -Path $ConfigPath -Value $TomlContent -Encoding UTF8 -Force
Write-Output "Конфигурация успешно записана в $ConfigPath"
}
# Применение политик безопасности через реестр (предотвращение изменения параметров пользователем)
$RegPath = "HKLM:\SOFTWARE\RustDesk\RustDesk"
if (!(Test-Path -Path $RegPath)) {
New-Item -Path $RegPath -Force | Out-Null
}
Set-ItemProperty -Path $RegPath -Name "custom-rendezvous-server" -Value $RelayHost -Force
Set-ItemProperty -Path $RegPath -Name "key" -Value $PublicKey -Force
# Перезапуск службы RustDesk для применения изменений
$Service = Get-Service -Name "rustdesk" -ErrorAction SilentlyContinue
if ($Service -and $Service.Status -eq 'Running') {
Restart-Service -Name "rustdesk" -Force
Write-Output "Служба RustDesk перезапущена."
}
3. Контроль функции Auto-Discovery
Штатная функция Auto-Discovery (порт 21119/UDP) выполняет периодическую рассылку широковещательных пакетов в подсеть для поиска других рабочих станций с запущенным RustDesk. В корпоративных окружениях с разделением на VLAN данное поведение провоцирует нежелательную сетевую активность и нарушает изоляцию рабочих мест. Отключение автообнаружения выполняется добавлением директивы в TOML:
direct_server = false
direct_access_port = 0
Настройка кроссплатформенных клиентов: Linux, macOS, Android и iOS
Linux-клиенты (Debian/Ubuntu/RHEL)
Конфигурация клиента RustDesk в Linux управляется через файл /etc/rustdesk/RustDesk.toml (для системного демона) и ~/.config/rustdesk/RustDesk2.toml (для интерфейса пользователя).
Автоматизация через Bash:
sudo mkdir -p /root/.config/rustdesk
cat << 'EOF' | sudo tee /root/.config/rustdesk/RustDesk2.toml
rendezvous_server = 'relay.company.ltd'
relay_server = 'relay.company.ltd:21117'
key = '4F8a+K9z1X5mP0aL2vQ8wE3rT6yU9iO2pA4sD7fG1hJ='
EOF
# Синхронизация для пользовательской сессии
mkdir -p "$HOME/.config/rustdesk"
cp /root/.config/rustdesk/RustDesk2.toml "$HOME/.config/rustdesk/"
# Перезапуск демона
sudo systemctl restart rustdesk
macOS (Apple Silicon / Intel)
Архитектура безопасности macOS требует не только применения конфигурации, но и выдачи разрешений в подсистеме TCC (Transparency, Consent, and Control): Универсальный доступ (Accessibility), Запись экрана (Screen Recording) и Входной мониторинг (Input Monitoring).
- Запись конфигурации через CLI:
CONFIG_DIR="$HOME/Library/Application Support/RustDesk/config"
mkdir -p "${CONFIG_DIR}"
cat << 'EOF' > "${CONFIG_DIR}/RustDesk2.toml"
rendezvous_server = 'relay.company.ltd'
relay_server = 'relay.company.ltd:21117'
key = '4F8a+K9z1X5mP0aL2vQ8wE3rT6yU9iO2pA4sD7fG1hJ='
EOF
- Для корпоративных Mac выдача прав TCC осуществляется централизованно через MDM-профиль (Mobile Device Management) с указанием идентификатора бандла
com.carriez.rustdesk.
Мобильные клиенты Android и iOS
На мобильных платформах ручной ввод параметров неэффективен. Оптимальный метод подключения смартфона или планшета к корпоративному контуру — генерация QR-кода, содержащего Base64 Host-Key Payload:
# Генерация QR-кода прямо в терминале Linux
qrencode -t ANSIUTF8 "${PAYLOAD}"
▄▄▄▄▄▄▄ ▄▄▄ ▄▄▄▄▄▄▄
█ ▄▄▄ █ ▀ █ █ ▄▄▄ █
█ ███ █ █▀█ █ ███ █
█▄▄▄▄▄█ █ █ █▄▄▄▄▄█
█ ▄▄ ▄█▄▀█▀▄█ ▄▄ ▄█
██ █ ▄▄▀▀ ▀▄▄▀▄ ▀██
█▄▄▄▄▄█ █▀█ █ █ ▀ █
Оператор открывает мобильный клиент RustDesk, переходит в Настройки → Сеть/ID/Relay Server и нажимает на пиктограмму сканирования QR-кода. Камера считывает строку, валидирует контрольную сумму Ed25519 и фиксирует серверные параметры.
При работе мобильных клиентов в сотовых сетях (LTE/5G) критически важен чистый белый IP-адрес инстанса. Развертывание узла на облачной платформе tropic.host исключает промежуточный операторский Carrier-Grade NAT (CGNAT) на стороне сервера и обеспечивает прямой роутинг мобильного трафика. Это минимизирует задержки ввода на тачскрине и предотвращает обрывы управляющих TCP-сокетов при хендовере между базовыми станциями сотовой связи. Наличие аппаратного фильтра DDoS на уровнях L3/L4/L7 защищает открытые клиентские порты 21115-21117 от синхронизационного флуда и сетевых атак, гарантируя непрерывную доступность шлюза.
Мониторинг, диагностика сетевых задержек и регламент аварийного восстановления (Disaster Recovery)
Стабильность удаленного управления рабочим столом (передача 60 FPS при битрейте 15–30 Мбит/с) определяется не номинальной полосой пропускания, а стабильностью задержек и отсутствием микропотерь UDP-дейтаграмм. При промышленной эксплуатации RustDesk на VPS сетевой стек сервера обязан удерживать строгие SLA-метрики: задержка latency p99 не должна превышать 25–30 мс, джиттер (packet delay variation) — удерживаться в пределах 1–2 мс, а потери пакетов на маршруте обязаны составлять 0.0%.
Сетевая телеметрия и диагностика узких мест (mtr, iperf3)
Стандартная утилита ping непригодна для продакшен-аудита: ICMP-эхо-запросы деприоритизируются магистральными маршрутизаторами tier-1 провайдеров и маскируют реальные задержки прикладных сокетов. Диагностика транспортного уровня выполняется с помощью утилит mtr и iperf3.
Для измерения потерь дейтаграмм и отклонений джиттера непосредственно на сигнальном порту hbbs (21116/udp) запускается трассировка пакетами фиксированного размера:
# Аудит сетевого маршрута по UDP на сигнальный порт сервера (100 циклов опроса)
mtr --report --report-cycles 100 --aslookup --show-ips --udp --port 21116 --psize 1400 <IP_ИЛИ_FQDN_СЕРВЕРА>
В выводе mtr ключевыми метриками являются Loss% (потери) и StDev (стандартное отклонение времени доставки). Если на хопах дата-центра параметр StDev превышает 3–5 мс при нулевых общих потерях, на физическом интерфейсе маршрутизатора возникает буферблоут (bufferbloat) — накопление очередей при пульсирующем трафике.
Синтетическое нагрузочное тестирование пропускной способности и эмуляция многопоточного видеострима производятся через связку iperf3:
# 1. На сервере VPS запускается тестовый демон:
iperf3 -s -p 5201 -1
# 2. На стороне клиента запускается генерация UDP-потока 30 Мбит/с в реверсном режиме:
# Параметр -R тестирует направление от VPS к клиенту (основной трафик видеопотока RustDesk)
iperf3 -c <IP_СЕРВЕРА> -u -b 30M -l 1400 -t 30 -p 5201 -R
Если по результатам теста фиксируется Jitter > 3 ms или показатель Lost/Total Datagrams > 0.2%, сетевой стек ядра Linux требует тюнинга очередей. В файле /etc/sysctl.d/99-rustdesk-telemetry.conf фиксируются параметры планировщика FQ и алгоритма контроля перегрузок TCP BBR:
# Переключение на планировщик Fair Queueing и алгоритм TCP BBR
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# Расширение сетевых буферов для компенсации burst-всплесков
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.udp_rmem_min = 16384
net.ipv4.udp_wmem_min = 16384
# Увеличение размера очереди сокетов ядра
net.core.netdev_max_backlog = 10000
Применение параметров выполняется без перезагрузки ноды: sysctl --system.
Мониторинг сокетов hbbs/hbbr и аудит аномалий
Демоны hbbs (сигнальный брокер) и hbbr (relay-мост) работают с большим количеством параллельных дескрипторов файлов. Контроль состояния активных сессий осуществляется через утилиту ss:
# Подсчет текущих активных ретрансляционных сессий на порту hbbr (21117/tcp)
ss -nt state established '( sport = :21117 or dport = :21117 )' | grep -v "Recv-Q" | wc -l
# Проверка очередей приема и отправки сокета hbbs (21116/udp)
ss -u -l -n -p '( sport = :21116 )'
Если в выводе ss для UDP-сокета колонка Recv-Q стабильно больше нуля, процесс hbbs не успевает вычитывать входящие дейтаграммы из буфера ядра. Главные причины: дефицит тактов vCPU из-за оверселлинга хоста (рост метрики %st) либо блокировки потоков ввода-вывода.
| Метрика / Параметр | Норматив (SLA) | Критический порог (Alert) | Инструмент аудита | Инженерное решение |
|---|---|---|---|---|
CPU Steal Time (%st) |
0.0% |
> 0.5% |
vmstat 1 / top |
Миграция с перегруженного хоста на чистый KVM без оверселлинга |
| Сетевая задержка (latency p99) | < 25 ms |
> 50 ms |
mtr --report |
Перевод трафика на провайдера с прямым IXP-пирингом (BGP Anycast) |
| Джиттер пакетов (Jitter) | < 1.5 ms |
> 4.0 ms |
iperf3 -u -R |
Активация fq + bbr в sysctl, уменьшение MTU payload до 1380 байт |
| Потери пакетов (Packet Loss) | 0.0% |
> 0.1% |
mtr --udp |
Трассировка узких мест на стыках транзитных операторов Tier-1 |
| Очередь сокета (Recv-Q) | 0 |
> 1024 |
ss -u -l -n |
Увеличение net.core.rmem_max, привязка процесса к изолированному ядру vCPU |
| Дисковая задержка (Write I/O) | < 0.2 ms |
> 2.0 ms |
iostat -xz 1 |
Перенос SQLite-базы на корпоративный NVMe-диск (PCIe 4.0) |
Автоматизированный скрипт резервного копирования (GPG шифрование + S3 бэкап)
Резервное копирование сервера RustDesk должно обеспечивать сохранность двух критических компонентов: 1. Приватный ключ сервера id_ed25519: утеря ключа инвалидирует верификацию на всех развернутых клиентах, делая невозможным удаленный доступ без ручного ввода новых реквизитов. 2. База данных db.sqlite3 (учетные записи, назначенные права OIDC, логи сессий и адресные книги).
Для обеспечения транзакционной целостности SQLite запрещено копировать работающий файл базы утилитой cp. Необходимо выполнять экспорт через команду .backup интерфейса sqlite3.
Ниже представлен скрипт /usr/local/bin/rustdesk-backup.sh, выполняющий создание консистентного снапшота, GPG шифрование по симметричному или асимметричному ключу и последующий S3 бэкап в объектное хранилище.
#!/usr/bin/env bash
set -euo pipefail
# Конфигурационные параметры
BACKUP_DIR="/var/backups/rustdesk"
DATA_DIR="/opt/rustdesk"
S3_BUCKET="s3://infra-backups-production/rustdesk"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
ARCHIVE_NAME="rustdesk_backup_${TIMESTAMP}.tar.gz"
ENCRYPTED_ARCHIVE="${ARCHIVE_NAME}.gpg"
PASSPHRASE_FILE="/etc/rustdesk/backup_gpg_passphrase"
RETENTION_DAYS=14
mkdir -p "${BACKUP_DIR}"
chmod 700 "${BACKUP_DIR}"
trap 'rm -rf "${BACKUP_DIR}/temp_${TIMESTAMP}"' EXIT INT TERM
mkdir -p "${BACKUP_DIR}/temp_${TIMESTAMP}"
# 1. Транзакционный дамп базы SQLite без остановки контейнера
if [ -f "${DATA_DIR}/data/db.sqlite3" ]; then
sqlite3 "${DATA_DIR}/data/db.sqlite3" ".backup '${BACKUP_DIR}/temp_${TIMESTAMP}/db.sqlite3'"
fi
# 2. Копирование криптографических ключей Ed25519 и конфигураций
cp -p "${DATA_DIR}/data/id_ed25519"* "${BACKUP_DIR}/temp_${TIMESTAMP}/"
cp -p "${DATA_DIR}/docker-compose.yml" "${BACKUP_DIR}/temp_${TIMESTAMP}/"
[ -f "${DATA_DIR}/.env" ] && cp -p "${DATA_DIR}/.env" "${BACKUP_DIR}/temp_${TIMESTAMP}/"
# 3. Упаковка в tar.gz архив
tar -czf "${BACKUP_DIR}/${ARCHIVE_NAME}" -C "${BACKUP_DIR}/temp_${TIMESTAMP}" .
# 4. GPG шифрование архива (AES256)
gpg --batch --yes --pinentry-mode loopback \
--passphrase-file "${PASSPHRASE_FILE}" \
--cipher-algo AES256 \
--symmetric \
--output "${BACKUP_DIR}/${ENCRYPTED_ARCHIVE}" \
"${BACKUP_DIR}/${ARCHIVE_NAME}"
# Удаление открытого незашифрованного архива
rm -f "${BACKUP_DIR}/${ARCHIVE_NAME}"
# 5. Передача в S3-совместимое хранилище через AWS CLI
aws s3 cp "${BACKUP_DIR}/${ENCRYPTED_ARCHIVE}" "${S3_BUCKET}/${ENCRYPTED_ARCHIVE}" \
--storage-class STANDARD_IA
# 6. Очистка локальных бэкапов старше RETENTION_DAYS
find "${BACKUP_DIR}" -name "rustdesk_backup_*.tar.gz.gpg" -type f -mtime +${RETENTION_DAYS} -delete
logger -t rustdesk-backup "Резервное копирование успешно завершено: ${ENCRYPTED_ARCHIVE}"
Установка прав доступа и запуск задачи по расписанию через cron:
chmod 700 /usr/local/bin/rustdesk-backup.sh
chmod 600 /etc/rustdesk/backup_gpg_passphrase
# Запуск каждые сутки в 03:00
echo "0 3 * * * root /usr/local/bin/rustdesk-backup.sh > /dev/null 2>&1" > /etc/cron.d/rustdesk-backup
Пошаговый регламент Disaster Recovery (DR)
В случае масштабной аварии дата-центра или выхода из строя физического узла виртуализации регламент аварийного восстановления (Disaster Recovery) обеспечивает подъем инфраструктуры за 3 минуты с целевыми показателями RTO $\le$ 3 мин и RPO $\le$ 24 ч (при ежедневных бэкапах) без потери авторизаций клиентов.
┌────────────────────────┐ ┌────────────────────────┐ ┌────────────────────────┐
│ 1. Авария хост-ноды │ ──> │ 2. KVM VPS Provision │ ──> │ 3. Скачивание бэкапа │
│ (Полный отказ) │ │ на tropic.host │ │ из S3-бакета │
└────────────────────────┘ └────────────────────────┘ └────────────────────────┘
│
▼
┌────────────────────────┐ ┌────────────────────────┐ ┌────────────────────────┐
│ 6. DNS TTL переключение│ <── │ 5. Запуск Docker-стека │ <── │ 4. Расшифровка GPG: │
│ (Клиенты онлайн) │ │ (hbbs/hbbr активны) │ │ id_ed25519 + sqlite │
└────────────────────────┘ └────────────────────────┘ └────────────────────────┘
Шаг 1: Развертывание инстанса KVM на tropic.host
Для исключения деградации сервиса развертывается новый чистый сервер на платформе tropic.host. Архитектура KVM гарантирует нулевой показатель оверселлинга процессора (%st = 0.0%), а серверные накопители NVMe PCIe 4.0 исключают блокировки ввода-вывода при одновременной записи логов десятков сессий. Премиальные каналы 1–10 Гбит/с с поддержкой TCP BBR и прямым пирингом на Франкфурт, Амстердам и Стамбул обеспечивают задержку p99 < 20 мс для мобильных и десктопных клиентов. При возникновении санкционных ограничений инфраструктура оперативно оплачивается криптовалютой (USDT TRC20/TON/BTC) или банковскими картами.
Шаг 2: Установка зависимостей на чистой ноде
На развернутой ноде (Ubuntu 24.04 LTS / Debian 12) устанавливаются Docker, GPG и клиент объектного хранилища:
apt-get update && apt-get install -y docker.io docker-compose-v2 gnupg awscli sqlite3
mkdir -p /opt/rustdesk/data /etc/rustdesk
Шаг 3: Выгрузка и расшифровка архива из S3
# Размещение мастер-пароля GPG
echo "YOUR_SECURE_PASSPHRASE" > /etc/rustdesk/backup_gpg_passphrase
chmod 600 /etc/rustdesk/backup_gpg_passphrase
# Поиск последнего бэкапа в хранилище S3
LATEST_BACKUP=$(aws s3 ls s3://infra-backups-production/rustdesk/ | sort | tail -n 1 | awk '{print $4}')
# Скачивание зашифрованного архива
aws s3 cp "s3://infra-backups-production/rustdesk/${LATEST_BACKUP}" /tmp/recovery_backup.tar.gz.gpg
# GPG расшифровка и распаковка в рабочую директорию
gpg --batch --yes --pinentry-mode loopback \
--passphrase-file /etc/rustdesk/backup_gpg_passphrase \
--decrypt /tmp/recovery_backup.tar.gz.gpg | tar -xz -C /opt/rustdesk/data/
# Перемещение docker-compose.yml и .env в корень каталога проекта
mv /opt/rustdesk/data/docker-compose.yml /opt/rustdesk/
[ -f /opt/rustdesk/data/.env ] && mv /opt/rustdesk/data/.env /opt/rustdesk/
Шаг 4: Валидация прав доступа и целостности базы данных
Перед запуском контейнеров проверяется целостность SQLite и выставляются корректные права на закрытый ключ:
# Валидация SQLite
sqlite3 /opt/rustdesk/data/db.sqlite3 "PRAGMA integrity_check;"
# Вывод обязан вернуть: ok
# Защита приватного ключа
chmod 600 /opt/rustdesk/data/id_ed25519
chmod 644 /opt/rustdesk/data/id_ed25519.pub
Шаг 5: Запуск контейнеров и переключение сетевого контура
cd /opt/rustdesk
docker compose up -d
# Проверка биндинга портов
ss -tulpn | grep -E '21115|21116|21117'
Шаг 6: Переключение DNS и бесшовная реавторизация клиентов
В панели DNS-провайдера обновляется A-запись домена ретранслятора (например, relay.company.domain) на новый публичный IPv4-адрес сервера tropic.host.
Поскольку публичный TTL в DNS для сигнального домена предварительно установлен на 180 секунд, переключение маршрутов занимает не более 3 минут. Главное преимущество сохранения исходного id_ed25519: клиенты RustDesk не фиксируют изменения открытого ключа сервера, поэтому системные диалоги Host key mismatch не генерируются, а все пользовательские сессии восстанавливаются в полностью прозрачном автоматическом режиме.
Часто задаваемые вопросы (FAQ)
Почему для сервера RustDesk Relay необходим VPS с чистой виртуализацией KVM, а не OpenVZ/LXC?
KVM предоставляет полностью изолированное ядро Linux, что позволяет активировать алгоритм TCP BBR, кастомизировать сетевые буферы (sysctl) и гарантирует 0.0% CPU Steal Time. В OpenVZ/LXC общее ядро ограничивает системные вызовы, а перегрузка ноды соседями вызывает скачки пинга и потерю кадров.
Какая пропускная способность канала требуется серверу RustDesk при 20 одновременных подключениях?
В режиме прямого P2P трафик идет мимо сервера (сервер тратит лишь доли килобайта на сигнальные пакеты). Если сессии идут через Relay (hbbr) в разрешении 1080p@60FPS, каждому потоку требуется 2–4 Мбит/с. Для 20 одновременных сессий необходим стабильный симметричный канал от 80–100 Мбит/с с аплинком 1 Гбит/с на стороне KVM VPS.
Что произойдет, если потерять приватный ключ id_ed25519 на сервере RustDesk?
При утере ключа сервер сгенерирует новую пару ed25519 при перезапуске. В результате все ранее настроенные клиенты потеряют возможность подключаться через данный Relay до тех пор, пока на каждом устройстве не будет обновлен публичный ключ.
Можно ли развернуть RustDesk Server за NAT без выделенного белого IPv4 адреса?
Технически возможно через туннелирование (Cloudflare Tunnels, WireGuard), однако это вносит критическую дополнительную задержку (RTT) и не поддерживает передачу сырых UDP-пакетов для сигнального протокола hbbs. Для стабильного 60 FPS remote desktop обязателен статический публичный IPv4 на VPS.