# RDtop — RustDesk Headless Display Setup **Автоматический виртуальный дисплей для RustDesk без подключенного HDMI монитора. Работает на Intel iGPU и CPU-only VPS.** --- ## Содержание 1. [Проблема](#проблема) 2. [Решение](#решение) 3. [Файлы проекта](#файлы-проекта) 4. [Установка](#установка) - [Вариант А: Десктоп с Intel iGPU](#вариант-а-десктоп-с-intel-igpu) - [Вариант Б: CPU-only VPS](#вариант-б-cpu-only-vps) 5. [Как это работает](#как-это-работает) 6. [Проверка](#проверка) 7. [Troubleshooting](#troubleshooting) 8. [Откат](#откат) --- ## Проблема Оборудование: **Intel Alder Lake-N (i915)**, Ubuntu 24.04, X11 (GDM/GNOME). ### Что происходит 1. При подключенном HDMI — Xorg инициализирует `HDMI-1` на отдельный CRTC. 2. Когда кабель отключают — **CRTC уничтожается**. 3. У Xorg не остается активного выхода. Может остаться черный экран или fallback 8×8. 4. RustDesk все еще подключен, но захватывает `Screen 0` — и видит либо черный экран, либо 8×8 пикселей. ### Почему стандартные способы не помогли | Способ | Результат | |--------|-----------| | `Option "VirtualHeads" "1"` (intel driver) | **Работает!** Но требует `Driver "intel"` + `VirtualHeads` в `xorg.conf`. | | modesetting driver | Создает VIRTUAL1 через randr, но после reboot пропадает без `intel` config. | | `NoOutputInitialSize` | Требует пересборки xorg или патчей. | | Dummy plug (аппаратный) | Работает, но нужно покупать. | --- ## Решение ### Хост (Intel iGPU): VIRTUAL1 = primary, HDMI1 = clone ``` +------------------------------------------------------------------------+ | X11 Screen 0: 1920x1080 | | | | +-------------------------+ +------------------------------------+ | | | VIRTUAL1 | | HDMI1 | | | | [PRIMARY] 1920×1080 | | [CLONE --same-as VIRTUAL1] | | | | Всегда активен | | При отключении → off | | | +-------------------------+ +------------------------------------+ | | | | RustDesk: всегда захватывает PRIMARY (VIRTUAL1) | +------------------------------------------------------------------------+ ``` ### VPS (CPU-only): Dummy driver + Xorg + RustDesk ``` +------------------------------------------------------------------------+ | Xorg Dummy Driver (1920×1080) | | +-------------------------+ | | | DUMMY0 = primary | ← RustDesk --server захватывает | | | 1920×1080 @ 60Hz | | | +-------------------------+ | | Нет GPU, нет DRM — работает на любом VPS | +------------------------------------------------------------------------+ ``` --- ## Файлы проекта | Файл репозитория | Назначение | Системный путь | |------------------|------------|----------------| | `bin/hdmi-fallback.sh` | Мониторинг HDMI-A-1 и авто-fallback на VIRTUAL1 | `~/.local/bin/hdmi-fallback.sh` | | `bin/vps-start-xorg.sh` | Стартер Xorg с dummy driver на VPS | `/usr/local/bin/start-xorg-dummy.sh` | | `config/x11/90-fallback.conf` | Xorg fallback: Virtual 1920 1080 для modesetting | `/etc/X11/xorg.conf.d/90-fallback.conf` | | `config/x11-host/20-intel-virtual.conf` | Intel driver + VirtualHeads=1 | `/etc/X11/xorg.conf.d/20-intel-virtual.conf` | | `config/systemd/hdmi-fallback.service` | systemd user unit (host) | `~/.config/systemd/user/hdmi-fallback.service` | | `config/vps/xorg-dummy.service` | systemd system unit (VPS Xorg) | `/etc/systemd/system/xorg-dummy.service` | | `config/vps/rustdesk-dummy.service` | systemd system unit (VPS RustDesk) | `/etc/systemd/system/rustdesk-dummy.service` | | `install.sh` | Установщик для хоста | (запускается один раз) | --- ## Установка ### Вариант А: Десктоп с Intel iGPU ```bash bash -c "$(curl -fsSL https://git.softuniq.eu/NW/RDtop/raw/branch/main/install.sh)" ``` После установки **перезагрузить компьютер** или перезапустить GDM: ```bash sudo systemctl restart gdm ``` **Вручную:** ```bash # 1. Клонируем git clone https://git.softuniq.eu/NW/RDtop.git ~/RDtop && cd ~/RDtop # 2. Intel driver + VirtualHeads sudo cp config/x11-host/20-intel-virtual.conf /etc/X11/xorg.conf.d/ # 3. Xorg fallback (резерв) sudo cp config/x11/90-fallback.conf /etc/X11/xorg.conf.d/ # 4. Скрипт мониторинга chmod +x bin/hdmi-fallback.sh cp bin/hdmi-fallback.sh ~/.local/bin/ # 5. systemd unit mkdir -p ~/.config/systemd/user cp config/systemd/hdmi-fallback.service ~/.config/systemd/user/ systemctl --user daemon-reload systemctl --user enable --now hdmi-fallback.service # 6. Перезагрузка sudo systemctl restart gdm ``` ### Вариант Б: CPU-only VPS ```bash # 1. Установить Xorg + dummy apt-get update apt-get install -y xserver-xorg xserver-xorg-video-dummy rustdesk # 2. Копировать конфиги git clone https://git.softuniq.eu/NW/RDtop.git /tmp/rdtop cd /tmp/rdtop sudo cp config/vps/xorg-dummy.service /etc/systemd/system/ sudo cp config/vps/rustdesk-dummy.service /etc/systemd/system/ sudo cp bin/vps-start-xorg.sh /usr/local/bin/start-xorg-dummy.sh chmod +x /usr/local/bin/start-xorg-dummy.sh # 3. Запустить systemctl daemon-reload systemctl enable --now xorg-dummy.service systemctl enable --now rustdesk-dummy.service # 4. Проверить export DISPLAY=:0 xrandr --listmonitors # Должно показать: DUMMY0 primary 1920x1080 ``` --- ## Как это работает ### Хост (Intel iGPU) 1. **Xorg конфиг** `20-intel-virtual.conf` указывает `Driver "intel"` + `Option "VirtualHeads" "1"`. 2. **Intel driver** создает VIRTUAL1 как software output (проверено на Alder Lake-N). 3. **Скрипт** `hdmi-fallback.sh` при старте: - Всегда активирует VIRTUAL1 как primary - Если HDMI connected — делает HDMI1 clone (`--same-as`) - Если HDMI disconnected — выключает HDMI1, VIRTUAL1 остается primary 4. **RustDesk** захватывает VIRTUAL1 (primary), а не HDMI1. ### VPS (CPU-only) 1. **Dummy driver** (`Driver "dummy"`) не требует GPU, работает на чистом CPU. 2. **Xorg** запускается без DRM, создает DUMMY0 1920×1080. 3. **RustDesk `--server`** захватывает DUMMY0 через X11 screen capture. 4. **Нет GUI оболочки** по умолчанию — если нужен рабочий стол, установить `xfce4` + `tightvncserver`. --- ## Проверка ### Хост ```bash # После перезагрузки xrandr --listmonitors # Должно быть: # 0: +*VIRTUAL1 1920x... VIRTUAL1 [PRIMARY] # 1: +HDMI1 1920x... HDMI1 [CLONE] # Сервис systemctl --user status hdmi-fallback.service ``` ### VPS ```bash export DISPLAY=:0 xrandr --listmonitors # Должно быть: # 0: +*DUMMY0 1920x... DUMMY0 [PRIMARY] # RustDesk ps aux | grep rustdesk # /usr/lib/rustdesk/rustdesk --server должен быть запущен ``` --- ## Troubleshooting ### VIRTUAL1 не появляется после reboot ```bash # Проверить intel driver: grep "Loading.*intel" /var/log/Xorg.0.log # Должно быть: (II) Loading /usr/lib/xorg/modules/drivers/intel_drv.so # Если modesetting загружается вместо intel: # Убедиться что 20-intel-virtual.conf существует: ls /etc/X11/xorg.conf.d/20-intel-virtual.conf # Убедиться что нет других конфликтующих xorg.conf: ls /etc/X11/xorg.conf 2>/dev/null || echo "OK: no xorg.conf" ``` ### RustDesk черный экран ```bash # Проверить primary: xrandr --verbose | grep primary # Должно быть: VIRTUAL1 connected primary (или DUMMY0) # Если primary = HDMI1 — переключить: xrandr --output VIRTUAL1 --mode "1920x1080_60.00" --primary xrandr --output HDMI1 --auto --same-as VIRTUAL1 ``` ### VPS: RustDesk не видит DUMMY0 ```bash # Проверить что Xorg запущен: ls /tmp/.X11-unix/X0 # Должен быть сокет # Если нет — запустить вручную: /usr/local/bin/start-xorg-dummy.sh ``` --- ## Откат ```bash # Хост sudo rm -f /etc/X11/xorg.conf.d/20-intel-virtual.conf sudo rm -f /etc/X11/xorg.conf.d/90-fallback.conf systemctl --user disable --now hdmi-fallback.service rm -f ~/.local/bin/hdmi-fallback.sh # VPS systemctl disable --now xorg-dummy.service systemctl disable --now rustdesk-dummy.service sudo rm -f /etc/systemd/system/xorg-dummy.service sudo rm -f /etc/systemd/system/rustdesk-dummy.service ``` --- ## Технические детали ### Почему intel driver, а не modesetting? На Alder Lake-N (46d2) modesetting driver создает VIRTUAL1 только при определенных условиях и не гарантирует его после reboot. Intel driver с `VirtualHeads=1` создает VIRTUAL1 стабильно. ### Почему клон, а не extended desktop? `--same-as` клонирует framebuffer. При disconnect HDMI clone просто перестает рендериться, но primary (VIRTUAL1) не затрагивается — Xorg не теряет framebuffer. ### Dummy driver на VPS Не требует GPU, не использует DRM. Работает на любом Linux с xorg-server. RustDesk использует software capture через X11 API. --- ## Авторы - Deploy via AI Agent (Kilo Code Orchestrator) - Target hardware: Intel Alder Lake-N (i915), Ubuntu 24.04 - VPS: CPU-only, Ubuntu 24.04, Hetzner/DigitalOcean/Linode ## Ссылки - Репозиторий: `https://git.softuniq.eu/NW/RDtop` - Установщик: `bash -c "$(curl -fsSL https://git.softuniq.eu/NW/RDtop/raw/branch/main/install.sh)"`