JobController — корпоративный агент для явно запускаемых защищённых рабочих сессий. Текущая MVP-версия собирает агрегированную активность пользователя и инвентаризацию устройств, не записывая введённые символы, координаты указателя, содержимое буфера обмена или заголовки окон.
Windows Raw Input
|
v
SessionAgent -- Named Pipe --> CollectorService -- HTTP --> Server
JobController.ServerConsole — нативная WinUI-консоль сервера. В установленной
версии она управляет службой Windows JobControllerServer, показывает
зарегистрированные устройства и выпускает персональные клиентские ZIP-комплекты,
привязанные к публичному адресу этого сервера. При локальной разработке консоль
запускает сервер как дочерний процесс.
JobController.Desktop — упакованное управляющее приложение на WinUI 3. Оно
запускает Session Agent с выбранными политиками и корректно останавливает его
через отдельный именованный канал текущей сессии, сохраняя событие
SessionEnded.
Клиент Windows работает с правами администратора, при наличии профиля запускает VPN-службу от имени LocalSystem и сворачивается в область уведомлений при нажатии кнопки закрытия в заголовке. Для полного завершения процесса используйте команду Выход в меню трея. Двухкольцевая пульсация вокруг замка включается только после подтверждённого запуска VPN и начала рабочей сессии.
Настольный клиент импортирует профиль OpenVPN .ovpn, показывает настроенный
сервер и его разрешённый IP-адрес, запрашивает учётные данные только при наличии
в профиле auth-user-pass и запускает VPN до агента мониторинга. Импортированные
профили нормализуются до route-metric 1. Пароль никогда не записывается в
профиль и сохраняется через Windows Credential Manager только по выбору
пользователя. Директивы запуска скриптов и плагинов при импорте отклоняются.
Разбор VPN-профилей и логика управляемых профилей находятся в платформенно
независимом проекте JobController.Vpn.Core. WinUI и текущий агент сессии
являются компонентами Windows. Планируемый клиент macOS сможет повторно
использовать ядро вместе со службой VPN для macOS. Поддержка WSL означает
маршрутизацию трафика WSL через VPN хоста Windows и, при необходимости,
фоновый Linux-агент без запуска WinUI внутри WSL.
JobController.VpnService — привилегированная граница Windows. Служба запускает
OpenVPN, ожидает Initialization Sequence Completed, получает фактический
удалённый IP из вывода OpenVPN, устанавливает метрику интерфейсов IPv4 и IPv6 в
значение 1, а после остановки туннеля восстанавливает прежние автоматические
или ручные значения. Доступ к её именованному каналу разрешён только LocalSystem,
администраторам и SID, выбранному при установке.
Для разработки VPN-службу можно отдельно установить после OpenVPN Community из окна PowerShell с правами администратора:
.\scripts\install-vpn-service.ps1Этот сценарий намеренно не запускается при обычной сборке, поскольку он создаёт автоматическую службу LocalSystem и изменяет метрики сетевых интерфейсов.
JobController.SessionAgentработает в интерактивной сессии Windows, показывает видимый индикатор в трее, считает нажатия клавиш, движения мыши, клики и прокрутку колеса, а также каждые 10 секунд определяет имя активного процесса.- При запуске сессии и изменениях агент сообщает геометрию мониторов и состав клавиатур, мышей и HID-устройств. Системные пути устройств хешируются локально до включения в контракт событий.
- Создание снимков экрана по умолчанию отключено. Когда политика его включает, индикатор в трее сообщает об активных снимках. Каждый монитор снимается отдельно, масштабируется не более чем до 1920x1080, кодируется в JPEG и ограничивается размером 700 КБ.
- Каждые 10 секунд агент сообщает об активных TCP-соединениях IPv4 и IPv6: удалённом IP и порте, локальном порте, состоянии TCP, PID и имени процесса. Содержимое пакетов и локальные IP-адреса не перехватываются. Один снимок сети ограничен 1 024 соединениями.
Сетевые метаданные по умолчанию собираются только во время явно запущенной
рабочей сессии. Для диагностики их можно отключить переменной
JOBCONTROLLER_NETWORK_ENABLED=false; текущее состояние всегда отображается в
меню трея.
JobController.CollectorServiceполучает конверт телеметрии по локальному именованному каналу, доступному только текущему пользователю, атомарно сохраняет его в дисковую очередь и пересылает с токеном устройства. При недоступности сервера используется экспоненциальная задержка, а после перезапуска отправка продолжается с самого старого события. Серверная уникальность последовательности делает повторную доставку идемпотентной.JobController.Serverпроверяет входные данные, хранит телеметрию в SQLite и поддерживает ограниченный буфер последних событий в памяти.JobController.Contractsсодержит намеренно минимальный сетевой контракт.
Session Agent читает флаги Raw Input, необходимые для классификации события, но никогда не помещает в контракт телеметрии виртуальную клавишу, скан-код, введённый символ, координаты мыши или исходную нагрузку Raw Input. Это свойство публичного контракта контролируется тестами.
Корпоративный комплект для Windows x64 состоит из подписанного MSIX-клиента, автономной VPN-службы, x64-зависимостей Windows App Runtime и сценариев установки/удаления. Session Agent и Collector встроены в пакет клиента; на рабочем компьютере не требуется .NET SDK.
Сборка комплекта версии 1.0.0.0:
.\scripts\build-windows-installer.ps1 -Version 1.0.0.0Результат создаётся в artifacts/installer как каталог и ZIP-архив. Если PFX
не указан, сборщик создаёт самоподписанный сертификат внутреннего тестирования с
субъектом CN=AppPublisher. Для производственной поставки передайте PFX
сертификат подписи кода с таким же субъектом либо замените Publisher в
Package.appxmanifest на субъект корпоративного сертификата:
$password = Read-Host 'Пароль PFX' -AsSecureString
.\scripts\build-windows-installer.ps1 `
-Version 1.0.0.0 `
-CertificatePath 'C:\secure\jobcontroller-signing.pfx' `
-CertificatePassword $password `
-DistributionUri 'https://downloads.company.local/jobcontroller'На рабочей станции сначала установите OpenVPN Community, распакуйте ZIP и
запустите Install.cmd. Установщик запросит токен регистрации, проверит хэши и
подпись пакета, установит автоматическую службу и зарегистрирует MSIX для
текущего пользователя. Адрес сервера можно задать явно:
$token = Read-Host 'Токен устройства' -AsSecureString
.\Install-JobController.ps1 `
-TelemetryUrl 'https://jobcontroller.company.local/api/v1/events' `
-DeviceToken $token `
-LaunchРегистрация хранится в %ProgramData%\JobController\client.json; ACL разрешает
доступ только LocalSystem, администраторам и пользователю установки. При
повторном запуске установщика идентификатор устройства и токен сохраняются, а
клиент и служба обновляются. Производственные токены не входят в MSIX, ZIP или
Git.
Серверный комплект включает WinUI-консоль, автономный ASP.NET Core-сервер и базовый клиентский ZIP. Если клиентский шаблон ещё не собран, команда сначала создаст его автоматически:
.\scripts\build-server-installer.ps1 -Version 1.0.0.0Установщик регистрирует ASP.NET Core-сервер как службу Windows с отложенным
автозапуском, запускает её от LocalService и настраивает три попытки
автоматического восстановления после сбоя. Постоянная конфигурация и
серверный токен первоначальной настройки сохраняются с ограниченными ACL в
%ProgramData%\JobController\Server\server-settings.json.
После установки откройте JobController Server: консоль автоматически
подключится к уже работающей службе. Для ручного запуска или остановки службы
консоль необходимо открыть от имени администратора.
При первом запуске открывается мастер, в котором задаются адрес прослушивания
Kestrel, публичный URL, каталог данных, срок хранения, правило брандмауэра и
PFX-сертификат для HTTPS. Перед применением консоль проверяет закрытый ключ и
срок действия сертификата, ограничивает ACL конфигурации и перезапускает службу.
Повторная установка сохраняет действующую конфигурацию и серверный токен.
При первом открытии веб-панели этот токен используется один раз для создания
локальной учётной записи владельца. После этого операторы входят по имени и
паролю; доступны роли владельца, администратора и аудитора, отключение учётных
записей, восьмичасовые серверные сессии, блокировка перебора и журнал безопасности.
Нативная консоль показывает общую сводку, зарегистрированные и наблюдаемые
устройства, рабочие сессии, снимки, сетевые подключения и журнал. Карточка
сессии агрегирует активность клавиатуры и мыши, приложения, удалённые адреса,
передачи данных и снимки; снимок можно открыть в увеличенном виде.
В разделе Установщики укажите сотрудника или устройство. Приложение выдаст копию клиента с одноразовым кодом регистрации на 30 минут. Доступ отдельного устройства можно отозвать в разделе Устройства.
При первом запуске установщика рабочая станция обменивает этот код на собственный
43-символьный токен. Код нельзя использовать повторно; токен связан с
идентификатором устройства и может быть отозван на сервере. База, снимки и
шаблон клиента хранятся в %ProgramData%\JobController\Server, а исполняемые
файлы службы — в %ProgramFiles%\JobController\Server.
Требования: Windows и .NET 10 SDK.
dotnet build JobController.sln
dotnet test JobController.sln
dotnet run --project src/JobController.Server --urls http://localhost:5080
dotnet run --project src/JobController.CollectorService
dotnet run --project src/JobController.SessionAgent
dotnet run --project src/JobController.Desktop -p:Platform=x64Чтобы завершить защищённую рабочую сессию, нажмите Ctrl+C в консоли Session
Agent.
При локальной разработке сервер и коллектор используют тестовый токен
development-token-change-me. В развёрнутой среде замените его через
Security__DeviceToken на сервере и Server__DeviceToken в коллекторе. Никогда
не добавляйте производственный токен устройства в Git.
Тестовый токен присутствует только в appsettings.Development.json.
Производственный запуск немедленно завершается ошибкой, если токен сервера не
задан или короче 16 символов.
В установленном клиенте очередь хранится в
%ProgramData%\JobController\Queue внутри защищённого установщиком каталога.
По умолчанию она ограничена 5000 событиями и 512 МБ; при переполнении удаляются
самые старые записи с предупреждением в журнале. Путь и лимиты настраиваются
параметрами Queue__StoragePath, Queue__MaxItems и Queue__MaxBytes.
Во время разработки настольное приложение находит Debug-сборку Session Agent.
При упакованном развёртывании разместите JobController.SessionAgent.exe рядом
с настольным приложением или задайте путь установки через
JOBCONTROLLER_AGENT_PATH.
Включение снимков экрана для локальной тестовой сессии:
$env:JOBCONTROLLER_SCREENSHOTS_ENABLED = 'true'
$env:JOBCONTROLLER_SCREENSHOT_INTERVAL_SECONDS = '60'
dotnet run --project src/JobController.SessionAgentИнтервал ограничен диапазоном 10–3600 секунд. Сервер сохраняет снимки в
src/JobController.Server/data/screenshots, по умолчанию хранит их семь дней и
удаляет байты изображений из ленты событий в памяти. Срок хранения меняется
через Screenshots__RetentionDays, а путь — через Screenshots__StoragePath.
Просмотр принятых образцов:
$headers = @{ 'X-Device-Token' = 'development-token-change-me' }
Invoke-RestMethod http://localhost:5080/api/v1/events/latest -Headers $headersСобытие снимка содержит storageKey, например
20260825/0123456789abcdef0123456789abcdef.jpg. Получить файл можно через
аутентифицированный endpoint:
Invoke-WebRequest `
http://localhost:5080/api/v1/screenshots/20260825/0123456789abcdef0123456789abcdef.jpg `
-Headers $headers `
-OutFile screenshot.jpgСервер публикует административную панель по адресу /admin/. Для локальной
проверки выполните:
.\scripts\run-monitoring-dashboard.ps1Откройте http://localhost:5080/admin/. При первом входе создайте владельца,
используя тестовый серверный токен development-admin-token-change-me, затем
входите по созданному имени и паролю. Панель содержит сессии, снимки экрана,
сетевые соединения, агрегированную активность клавиатуры и мыши, инвентаризацию
устройств и очищенные журналы VPN. Телеметрия хранится в SQLite по пути
src/JobController.Server/data/jobcontroller.db, а снимки — в
src/JobController.Server/data/screenshots.
Для корпоративного развёртывания опубликуйте JobController.Server за обратным
HTTPS-прокси и передавайте производственные секреты через платформу размещения,
а не через файл appsettings:
$env:Security__DeviceToken = '<per-device-or-enrollment-token>'
$env:Admin__AccessToken = '<one-time-bootstrap-token-at-least-24-characters>'
$env:Storage__DatabasePath = 'D:\JobController\data\jobcontroller.db'
dotnet JobController.Server.dll --urls http://127.0.0.1:5080На каждой управляемой рабочей станции перед запуском JobController направьте Collector на корпоративный сервер:
$env:Server__TelemetryUrl = 'https://jobcontroller.company.local/api/v1/events'
$env:Server__DeviceToken = '<device-token>'Настольное приложение автоматически запускает Collector до Session Agent.
Публичный сервер должен принимать подключения только по HTTPS. Ограничьте доступ
к /admin/ и /api/v1/admin/* административной сетью или прокси с проверкой
идентификации. Веб-панель использует серверный токен только при создании первого
владельца; нативная серверная консоль продолжает применять его как служебный
секрет и поэтому файл конфигурации должен оставаться доступным только службе и
локальным администраторам. Для централизованного управления идентификацией можно
дополнительно подключить корпоративный OIDC/AD.
- Корпоративная авторизация операторов через OIDC/AD и обязательная MFA.
- Понятные PnP-метаданные для разрешённых категорий периферийных устройств.
- Политики снимков по событиям и локальное скрытие чувствительных областей.
- Метаданные событий в PostgreSQL и объектное хранилище производственных снимков.
- Корреляция DNS/ETW для доменов назначения.
- Применение политик VPN и правил сетевых направлений.