Files
web-vnc/AGENTS.md
T
Codex cf0915878b docs(agents): require keeping AGENTS.md in sync with the code
Add a maintenance note: AGENTS.md is a living document and must be
updated in the same commit whenever code/flags/structure/scripts change,
and reconciled first whenever it diverges from the code.
2026-07-30 17:43:03 +03:00

7.5 KiB
Raw Blame History

AGENTS.md

Руководство для агентов (и людей), работающих с этим репозиторием.

Сопровождение этого файла (ВАЖНО)

  • AGENTS.md должен отражать актуальное состояние кода. Это живой документ, а не одноразовая справка.
  • При любом изменении, влияющем на: архитектуру, состав пакетов/файлов, флаги CLI или env-переменные (WEBVNC_*), протокол/поведение гейтвея, скрипты, кодировки файлов, процесс сборки/запуска или известные ограничения — обязательно обнови соответствующий раздел AGENTS.md в том же коммите.
  • Если заметил расхождение между AGENTS.md и реальным кодом (функция переименована, файл удалён, флаг изменён и т.п.) — сначала приведи AGENTS.md в соответствие с кодом, затем продолжай работу. Не оставляй устаревшие инструкции.
  • Коммит, меняющий поведение/структуру, но не трогающий AGENTS.md при расхождении, считается неполным.

Что это

web-vnc — один Go-бинарник, который открывает доступ к рабочему столу (VNC) через браузер (noVNC) с защитой по паролю. Гейтвей сам раздаёт noVNC-клиент, проверяет пароль, ставит HMAC-сессию и прозрачно релеит WebSocket браузера в TCP VNC-сервера (RFB). Опционально сам находит и запускает VNC-сервер.

Ключевые принципы (НЕ нарушать)

  • Только стандартная библиотека Go. Внешних Go-модулей нет и быть не должно — проект собирается офлайн (в среде сборки нет интернета/Go-proxy). WebSocket (RFC 6455) и хэш пароля (PBKDF2-HMAC-SHA256) реализованы вручную в internal/relay и internal/auth.
  • noVNC-клиент скачивается отдельно (scripts/get-novnc.*) во встроенную статику internal/server/static/. Эти папки (core/,app/,vendor/, utils/,novnc-original.html) в git не коммитятся (см. .gitignore). Наша собственная обёртка — internal/server/static/vnc.html (коммитится).
  • Пароль — один общий для всех (по требованию). Веб-пароль (PBKDF2) хранится как --password-hash; тот же пароль может передаваться VNC-серверу через --vnc-password/WEBVNC_VNC_PASSWORD, чтобы noVNC авторизовался автоматически (одно поле ввода для пользователя).

Сборка и запуск

# среда без интернета: Go уже установлен, прокси недоступен -> stdlib-only
$env:GOCACHE = "$env:TEMP\go-build"   # дефолтный кэш бывает без прав на запись
go build -o web-vnc.exe ./cmd/web-vnc
.\web-vnc.exe --gen-hash "пароль"        # напечатает хэш
.\web-vnc.exe --password-hash <хэш> --spawn

Проверка: go vet ./..., gofmt -l internal cmd (должно быть пусто).

Структура

cmd/web-vnc/main.go        CLI: флаги, спавн VNC, запуск сервера, --gen-hash
internal/config            флаги + env (WEBVNC_*)
internal/auth              PBKDF2-HMAC-SHA256, HMAC session-cookie, rate-limit
internal/relay             websocket.go — RFC6455 на stdlib; relay.go — WS<->TCP
internal/vncspawner        кросс-ОС поиск/запуск VNC-сервера (build-теги по ОС)
internal/server            HTTP-роуты, /api/status, middleware сессии, embed.FS
internal/server/static     встроенные ассеты (vnc.html + noVNC core/app/vendor)
scripts/get-novnc.{ps1,sh} скачать noVNC
scripts/get-vnc.ps1        скачать портативный UltraVNC в vnc/ (с верификацией zip)
scripts/list-ips.ps1       список IPv4 машины (используется run.bat)
scripts/open-firewall.bat  открыть порт 8080 в Windows Firewall (от админа)
run.bat                    запуск в один клик (спрашивает только пароль)

Соглашения и подводные камни

  • Кодировка файлов .bat: сохранять в кодировке cp866 с окончаниями строк CRLF. PowerShell Set-Content -Encoding UTF8 добавляет BOM и пишет LF — не использовать для .bat. Пиши через [System.IO.File]::WriteAllText(path, content -replace "(?<!\r)\n","rn", [Text.Encoding]::GetEncoding(866)).
  • Go-файлы: UTF-8 без BOM, LF. То же самое правило — не использовать Set-Content -Encoding UTF8 (ставит BOM). Используй [System.IO.File]::WriteAllText(path, content, [Text.UTF8Encoding]::new($false)).
  • .gitignore: бинарники игнорируются root-anchored (/web-vnc, /web-vnc.exe), иначе шаблон web-vnc ловит пакет cmd/web-vnc/.
  • vncspawner: функции поиска VNC-сервера определены через build-теги (detect_windows.go/detect_linux.go/detect_darwin.go), каждый файл определяет func candidates() []Candidate. Не ссылаться на платформо-специфичные функции из общих файлов.
  • Тесты в этой среде: интернет отсутствует; проверяй через локальные заглушки (TCP-эхо-сервер на 5900, Get-NetIPAddress часто пуст — list-ips.ps1 имеет фолбэк на ipconfig). Запущенный web-vnc.exe из фонового job может остаться «зомби» (Stop-Process иногда access denied); используй разные порты для тестов и по возможности запускай killable-способом.
  • Hijack WebSocket: internal/relay сам делает апгрейд через http.Hijacker; гейтвей НЕ использует gorilla/websocket.

Что делать дальше (известные TODO)

  • Надёжный авто-скачиватель VNC-сервера (URL UltraVNC на SourceForge нестабилен — get-vnc.ps1 теперь верифицирует zip-магию и даёт фолбэк на ручную установку).
  • На Windows захват экрана может требовать запуск VNC-сервера от администратора.
  • VNC-сервер требует свой пароль; --vnc-password передаёт его noVNC автоматически, но пароль VNC-сервера нужно один раз настроить под тот же.