Codex 02fefa1e4e fix(autostart): run from repo root + visible console at logon
autostart-run.bat did 'cd /d %~dp0' -> scripts/, but web-vnc.exe/webvnc.conf/
go.mod live in the repo root, so the binary was never found and web-vnc never
started after reboot. Now it cd's to %~dp0.. (repo root).

The task was ONSTART/RU SYSTEM (session 0) so it could not show a window, making
failures invisible. install-autostart.bat now registers ONLOGON /RL HIGHEST as the
current user -> a visible console opens at logon. autostart-run.bat sets a window
title, prints status, stays open while web-vnc serves, and pauses on fatal errors
(no binary / no webvnc.conf) so the reason is visible. Docs updated.
2026-08-06 01:09:47 +03:00

web-vnc

Один бинарник, который открывает доступ к рабочему столу (VNC) через браузер (noVNC) с защитой по паролю. Программа web-vnc:

  • раздаёт HTML5-клиент noVNC,
  • пускает зрителя по общему паролю,
  • прокидывает WebSocket браузера к локальному VNC-серверу (RFB поверх WS),
  • и (по желанию) сама запускает VNC-сервер.

Написано на чистом Go, только стандартная библиотека — никаких внешних Go-модулей, собирается офлайн.

 Браузер (noVNC)  ──ws──▶  web-vnc (один бинарник)  ──tcp RFB──▶  VNC-сервер (127.0.0.1:5900)
                            ├─ вход по паролю (PBKDF2-HMAC-SHA256)
                            ├─ HMAC session-cookie
                            └─ прозрачный релей WS↔TCP

Самый простой запуск (Windows)

Запуск состоит из двух шагов: один раз задаётся пароль, затем run.bat поднимает gateway без запросов.

  1. Один раз задайте пароль:

    set-password.bat
    

    Спросит пароль доступа, сгенерирует хэш и сохранит его вместе с паролем в webvnc.conf (секрет, в git не коммитится), а затем синхронизирует им пароль UltraVNC-сервиса (scripts\ensure-vnc-password.ps1, UAC только при смене). Веб-пароль оказывается настроен, даже если синк UltraVNC упадёт или UAC отменят. Используйте ASCII-пароль длиной до 8 символов (VNC-пароль = первые 8 байт).

  2. Запустите gateway:

    run.bat
    

    run.bat собирает web-vnc.exe (нужен Go, если бинарника нет), встраивает noVNC-клиент (качает при наличии интернета), находит/докачивает VNC-сервер, читает пароль из webvnc.conf (больше не спрашивает), печатает адреса (http://localhost:8080 и http://<каждый IPv4 машины>:8080) и запускает сервер с флагом --spawn. Если 127.0.0.1:5900 уже слушает (сервис UltraVNC) — запускается без --spawn, подключаясь к существующему серверу.

После запуска откройте в браузере один из выведенных адресов, введите тот же пароль — и попадёте на рабочий стол.

Автостарт при загрузке ОС (вместо ручного run.bat)

set-password.bat                 :: один раз: пароль -> webvnc.conf
install-autostart.bat         :: один раз (от админа): плановое задание «web-vnc»

install-autostart.bat регистрирует через schtasks задание (ONLOGON, HIGHEST, от имени текущего пользователя), которое при входе в систему открывает видимую консоль с scripts\autostart-run.bat — launcher, читающий webvnc.conf, ждущий 127.0.0.1:5900 до ~30 c и затем запускающий web-vnc.exe (не качает ничего на старте). Окно остаётся, пока web-vnc работает; при ошибке — пауза, чтобы было видно причину. Запуск от SYSTEM/ONSTART не используется: он в session 0 и окна не показывает. Запустить сразу без перезагрузки: schtasks /Run /TN "web-vnc". Снять автостарт: uninstall-autostart.bat (от админа).

Смена пароля: web-vnc.exe читает пароль из webvnc.conf только при старте и не перечитывает его в runtime. Поэтому set-password.bat (если задание «web-vnc» установлено) перезапускает его через restart-autostart.bat (с elevation) — тот проверяет, запущен ли web-vnc.exe (если да — стоп + старт, если нет — только старт). Рестарт пропускается, если пароль не изменился. Для интерактивного run.bat просто перезапустите его вручную.

Быстрый старт вручную (Windows)

# 1. Подтянуть noVNC-клиент во встроенную статику (один раз)
.\scripts\get-novnc.ps1

# 2. Собрать бинарник
go build -o web-vnc.exe .\cmd\web-vnc

# 3. Сгенерировать хэш пароля
$hash = .\web-vnc.exe --gen-hash "ваш-пароль"

# 4. Запустить (сам найдёт/запустит VNC-сервер и поднимется на :8080)
.\web-vnc.exe --password-hash $hash --spawn

Быстрый старт (Linux / macOS)

./scripts/get-novnc.sh
go build -o web-vnc ./cmd/web-vnc
hash=$(./web-vnc --gen-hash "ваш-пароль")
./web-vnc --password-hash "$hash" --spawn

Как это работает

  1. Пользователь открывает http://хост:8080/ и попадает на /login.
  2. Вводит общий пароль. Он сверяется с солёным PBKDF2-HMAC-SHA256-хэшем (120 000 итераций). При успехе сервер ставит HMAC-подписанную, HttpOnly-куку сессии (по умолчанию 8 ч, без серверного хранилища).
  3. Браузер загружает /vnc.html (только с валидной сессией). Клиент noVNC открывает WebSocket на /vnc.
  4. web-vnc проверяет сессию до апгрейда WebSocket и затем прозрачно релеит байты между WebSocket и локальным VNC-сервером (127.0.0.1:5900 по умолчанию). RFB-протокол проходит нетронутым, как у websockify.

VNC-сервер должен слушать на loopback (127.0.0.1) и может работать без VNC-пароля — защита по паролю теперь на веб-гейтвее. Если же ваш VNC-сервер требует свой пароль, noVNC спросит и его.

Авто-запуск VNC-сервера (--spawn)

С --spawn программа ищет установленный VNC-сервер и запускает его как дочерний процесс (отдельно, без окна на Windows), после чего подключается к нему.

ОС Что ищет
Windows UltraVNC (winvnc.exe), TightVNC (tvnserver.exe)
Linux x11vnc, tigervncserver / Xvnc
macOS встроенный Screen Sharing (kickstart)

Переопределить авто-поиск своей командой:

.\web-vnc.exe --password-hash $hash --spawn-command "C:\Path\To\winvnc.exe -run"

Без --spawn убедитесь, что VNC-сервер уже слушает по адресу из --vnc.

Настройка

Все флаги дублируются переменными окружения (WEBVNC_*).

Флаг Env По умолчанию Описание
--listen WEBVNC_LISTEN :8080 адрес HTTP/WS
--vnc WEBVNC_VNC 127.0.0.1:5900 адрес вышестоящего VNC-сервера
--password-hash WEBVNC_PASSWORD_HASH (обязателен) хэш PBKDF2 из --gen-hash
--session-secret WEBVNC_SESSION_SECRET случайный при старте HMAC-ключ для подписи куки сессии
--session-ttl WEBVNC_SESSION_TTL 8h время жизни куки сессии
--spawn WEBVNC_SPAWN false авто-запуск найденного VNC-сервера
--spawn-command WEBVNC_SPAWN_COMMAND (нет) явная команда запуска VNC-сервера
--web-root WEBVNC_WEB_ROOT (встроенные) раздавать статику с диска вместо embed
--novnc-path /vnc.html путь страницы noVNC-клиента
--relay-path /vnc endpoint WebSocket-релея

Сгенерировать хэш пароля

web-vnc --gen-hash "ваш-пароль"
# напечатает, например:  pbkdf2-sha256$120000$<соль>$<ключ>

Формат самодокументируемый: pbkdf2-sha256$<итерации>$<base64-соль>$<base64-ключ>.

Запуск одной строкой

.\web-vnc.exe --password-hash (. \web-vnc.exe --gen-hash "secret") --spawn

Безопасность

  • Без TLS: рассчитано на приватную сеть. Если выставляете наружу — поставьте перед ним reverse-proxy с TLS (nginx/caddy).
  • Логин с лимитом попыток (5 в минуту на IP, в памяти).
  • Кука сессии подписана --session-secret. Задайте фиксированный --session-secret, чтобы сессии переживали перезапуск (иначе секрет меняется при каждом старте, и старые сессии инвалидируются).
  • VNC-сервер держите на 127.0.0.1, чтобы до него нельзя было достучаться в обход гейтвея.

Устранение неполадок

  • После ввода пароля — ошибка / нет картинки. Значит, веб-гейтвей не смог подключиться к VNC-серверу (по адресу --vnc, по умолчанию 127.0.0.1:5900). На странице теперь показывается понятное сообщение вместо криптографической ошибки noVNC. Решение: должен работать VNC-сервер, который отдаёт рабочий стол:

    • Windows: установите UltraVNC или TightVNC, либо запустите scripts\get-vnc.ps1 (скачает портативный UltraVNC в папку vnc\, и run.bat сам его запустит).
    • Linux: x11vnc или TigerVNC.
    • macOS: встроенный Screen Sharing. Важно: VNC-сервер должен слушать на 127.0.0.1:5900. На Windows для захвата экрана может потребоваться запуск от имени администратора (UAC).
  • С другого компьютера страница не открывается (таймаут/недоступно). По умолчанию Windows Firewall блокирует входящие подключения. Один раз выполните от имени администратора:

    open-firewall.bat
    

    Это откроет входящий TCP-порт 8080. (run.bat выводит адреса и подсказку.)

  • noVNC-клиент не встроен (страница-заглушка). Запустите scripts\get-novnc.ps1 (нужен интернет), пересоберите и перезапустите.

Структура проекта

cmd/web-vnc/main.go        точка входа CLI: флаги, спавн VNC, запуск сервера
internal/config            конфигурация (флаги + env)
internal/auth              хэш пароля PBKDF2, HMAC-куки сессии, rate-limit
internal/relay             WebSocket на stdlib (RFC 6455) + мост WS↔TCP
internal/vncspawner        кросс-ОС поиск и запуск VNC-сервера
internal/server            HTTP-роуты, middleware сессии, встроенная статика
internal/server/static     встроенные веб-ассеты (vnc.html + core/app/vendor noVNC)

Пользовательские точки входа — в корне репозитория:
run.bat                    интерактивный запуск: собирает бинарник/noVNC/VNC, читает пароль из webvnc.conf (не спрашивает)
set-password.bat           разовая настройка пароля -> webvnc.conf (хэш + VNC-пароль); синхронизирует UltraVNC
install-autostart.bat      автостарт при входе (schtasks ONLOGON/HIGHEST, видимая консоль) — от админа
uninstall-autostart.bat    снять автостарт — от админа
restart-autostart.bat      перезапустить задание «web-vnc» (чтобы применить новый пароль) — от админа
open-firewall.bat          открыть порт 8080 в Windows Firewall (один раз, от админа)
webvnc.conf                секрет: HASH= + VNC_PASSWORD= (создаётся set-password.bat, gitignored)

Внутренние помощники — в scripts/ (вызываются другими скриптами):
scripts/autostart-run.bat  launcher автостарта (видимая консоль): cd в корень репо, читает webvnc.conf, ждёт 5900 до ~30 c, запускает web-vnc (без --spawn, если VNC уже слушает); pause на ошибке
scripts/ensure-vnc-password.ps1 синхронизирует VNC-пароль UltraVNC (вызывается из set-password.bat)
scripts/get-novnc.{ps1,sh} скачать noVNC во встроенную статику
scripts/get-vnc.ps1       скачать портативный VNC-сервер (UltraVNC) в папку vnc/
scripts/list-ips.ps1       список IPv4 машины (используется run.bat)

Кросс-компиляция под другую ОС

GOOS=linux   GOARCH=amd64 go build -o web-vnc-linux   ./cmd/web-vnc
GOOS=windows GOARCH=amd64 go build -o web-vnc.exe     ./cmd/web-vnc
GOOS=darwin  GOARCH=arm64 go build -o web-vnc-macos   ./cmd/web-vnc

Лицензия

MIT. Встроенные ассеты noVNC сохраняют свою лицензию (MPL-2.0) — см. internal/server/static/LICENSE после запуска get-novnc.

S
Description
No description provided
Readme
189 KiB
Languages
Go 46.7%
Batchfile 24%
PowerShell 19.4%
HTML 8.2%
Shell 1.7%