LaPorta USB

Установка на одну машину

Что нужно заранее

Ловушка POLICYPATH. Это обязательный параметр установки, и без него первая установка не проходит: установщик отвечает отказом «Не указан путь к файлу политики» – в окне при установке руками и в журнале установки (/l*v) при тихой (/qn). Смена версии и восстановление пакета без параметра проходят: путь берётся тот, что записала прежняя установка.

Если параметр всё же не дошёл – программу поставили прежним пакетом, который тихую установку без него пропускал, или руками мимо установщика, – вместо пути остаётся заглушка \\server\laportausb$\policy.json. По ней служба в сеть не ходит: имени server в сети обычно нет, такие имена Windows доспрашивает широковещательно, и ответить мог бы кто угодно. Служба пишет в журнал policy_unavailable с текстом «путь к политике не задан» и работает по кэшу, а без кэша – в запасном режиме: политика недоступна, значит разрешено всё.

Так получается машина, на которой программа стоит, а не запрещено ничего: ставили ради запрета, вышло прямо противоположное. Поэтому команда установки в этом документе всегда указывает POLICYPATH с локальным путём.

Обновление уже установленной программы путь не сбрасывает: без POLICYPATH установщик берёт тот, что записала прежняя установка, и забытый при смене версии параметр больше не переводит машину в запасной режим. В командах ниже он всё равно указан везде: так команда установки одна и та же и в первый раз, и потом.

Исключение – машина, где прежняя установка записала саму заглушку. Обновление без POLICYPATH на ней отказывает с тем же текстом, что и первая установка: машина без пути к политике ничего не запрещает, и обновление не должно это прятать. Передайте путь в команде обновления – он запишется вместо заглушки.

Заведите файл политики

До установки. Без этого файла служба запустится в запасном режиме и не запретит ничего – установщик его не создаёт и о его отсутствии не предупреждает.

Создайте каталог и положите в него policy.json. Путь может быть любым; здесь и дальше в документе – C:\ProgramData\LaPortaUsb\policy.json. Это не каталог данных самой программы (C:\ProgramData\LaPorta USB), их легко перепутать.

Самая простая политика, запрещающая флешки и внешние диски:

{
  "version": 1,
  "enforcement_mode": "enforce",
  "defaults": { "flash": "block", "external_hdd": "block" }
}

Поле version обязано быть больше нуля и расти при каждой правке – по нему служба узнаёт, что файл сменился. Значение audit вместо enforce даёт режим наблюдения: решения принимаются и пишутся в журнал, но не применяются. Разрешить отдельные носители, поставить метку «только чтение», настроить срок хранения журнала – всё это в policy-reference.md.

Закройте файл от того, кого он ограничивает. Каталог, созданный обычным пользователем в C:\ProgramData, оставляет этому же пользователю полный доступ: он сможет открыть policy.json и разрешить себе всё. Оставьте право на запись только администраторам и системной учётной записи, пользователям – чтение:

icacls "C:\ProgramData\LaPortaUsb" /inheritance:r /grant "*S-1-5-18:(OI)(CI)F" "*S-1-5-32-544:(OI)(CI)F" "*S-1-5-32-545:(OI)(CI)R"

Если каталог или файл создавал обычный пользователь, этого мало. Он остаётся их владельцем, а владелец вправе вернуть себе любые права. Права, выданные им прямо на файл, первая команда тоже не снимает. Поэтому ещё две команды: владельцем становятся администраторы, а у содержимого каталога остаются только права, унаследованные от него:

icacls "C:\ProgramData\LaPortaUsb" /setowner "*S-1-5-32-544" /T /C
icacls "C:\ProgramData\LaPortaUsb\*" /reset /T /C

Учётные записи заданы известными кодами, а не именами: имена встроенных групп переведены, и на английской Windows «Администраторы» команду уронят. Проверить, что вышло: icacls "C:\ProgramData\LaPortaUsb\policy.json" – у группы пользователей должно остаться только чтение, и ни одной строки без пометки (I), то есть права, выданного прямо на файл. Владельца показывает (Get-Acl "C:\ProgramData\LaPortaUsb\policy.json").Owner в PowerShell – там должна стоять группа администраторов.

Установка пакета

msiexec /i LaPortaUsb.msi POLICYPATH="C:\ProgramData\LaPortaUsb\policy.json" /qn /l*v install.log

Пакет может быть подписан кодовой подписью или не подписан. Если не подписан – при первом запуске компонентов Windows SmartScreen предупредит о неизвестном издателе; это ожидаемо, установку можно продолжить.

Где хранится путь к политике

Путь из POLICYPATH записывается в реестр (HKLM\SOFTWARE\LaPortaUsb\PolicyPath), откуда его читают и служба, и окно администратора. Реестр выбран не просто для порядка: диспетчер служб кэширует блок окружения, и служба, запущенная установщиком сразу после установки, переменную среды могла бы не увидеть – поэтому путь передаётся не через неё, а через параметр установки.

Чтобы сменить путь к политике на уже установленной машине, задайте POLICYPATH заново при восстановлении пакета (msiexec /i ... POLICYPATH=... REINSTALL=ALL REINSTALLMODE=amus) и перезапустите службу.

Проверка: запрет работает

Вставьте носитель в USB-порт и убедитесь, что буква диска не появилась (при правиле «только чтение» – что носитель доступен без возможности записи). В журнале программы должна появиться запись с принятым решением. Разбор видов записей и полей – в journal-reference.md.

Политику служба перечитывает сама, опросом раз в пять минут, – перезапускать её после правки файла не нужно. В журнале это видно парой: policy_reloaded с новой версией, следом enforced с applied: true. Рядом появится detach через считаные миллисекунды – это не извлечение носителя, а исчезновение отключённого узла.

Обновления

Программа умеет узнавать о новых выпусках сама, но не ставит их сама.

Что делает служба. Раз в сутки – первая проверка через час после запуска – она берёт с сайта программы подписанный манифест выпуска (https://laportausb.ru/releases/latest.json), проверяет подпись ключом, зашитым в саму программу, и сравнивает версию с установленной. Если на сайте версия новее, в журнал попадает событие update_available, одно на версию. Пакет при этом не скачивается и не ставится.

Неудачная проверка – нет сети, не пустил прокси, не сошлась подпись – в журнал носителей не пишется: она попадает в журнал приложений Windows под источником LaPortaUsb, а следующая попытка идёт через час.

Сама служба не ставит обновление намеренно. Установка останавливает службу, и машина на это время остаётся без запретов; выбирать минуту, когда это произойдёт, должен человек.

Как поставить. Окно администратора, меню «Справка» – «Обновления…». Окно спрашивает сайт, показывает версию, дату и размер, а по кнопке «Скачать и установить» качает пакет, сверяет его размер и sha256 с подписанным манифестом и запускает установщик Windows. Не сошлось – файл удаляется и установка не начинается.

Пакет кладётся в %ProgramData%\LaPorta USB\updates – в каталог, куда пишут только система и администраторы, а не во временную папку: в неё может писать любая программа, запущенная от имени того же человека, и подменённый пакет ушёл бы на установку с правами системы. Перед самым запуском установщика сумма считается ещё раз. Скачанный пакет остаётся в этом каталоге: в минуту запуска его читает установщик, и удалить его тогда нельзя. Он уйдёт при следующем обновлении – пакеты прошлых версий удаляются перед скачиванием новой.

Окно администратора при этом закрывается: заменить программу, пока она работает, установщик не может. Служба на время установки останавливается и снимает запреты, после установки поднимается сама. Путь к файлу политики сохраняется – тот же случай, что и при обновлении командой без POLICYPATH.

Как обновляться без администратора за машиной. Полем install_updates в политике: в нём задаются часы, в которые служба поставит обновление сама, – например "install_updates": "02:00-05:00". Служба скачает пакет, сверит его с подписанным манифестом и запустит установщик тихо, без единого вопроса. Права ей для этого не нужны: она и так работает под системной учётной записью.

Без этого поля служба не ставит ничего. Причина простая: установка останавливает службу, и машина на эти минуты остаётся без запретов – выбирать их должен администратор, а не случай. Поэтому окно задают ночным.

Что при этом попадает в журнал: update_installing – между скачиванием и запуском установщика, update_install_failed – если пакет не скачался или установщик не пошёл. Значок в области уведомлений при тихой установке закроется и вернётся при следующем входе пользователя: в ночные часы в системе обычно никого нет, а показывать значок некому и незачем.

Как выключить. Выключателей два, разной силы:

ВыключательГде задаётсяЧто выключает
check_updates: falseфайл политикиАвтоматическую проверку службой. Кнопка в окне продолжает работать
UPDATECHECK=0параметр установкиВсё: и проверку службой, и кнопку в окне

Параметр установки записывается в реестр и политикой не перебивается:

msiexec /i LaPortaUsb.msi POLICYPATH="C:\ProgramData\LaPortaUsb\policy.json" UPDATECHECK=0 /qn

Обновление без параметра сохраняет записанное значение, как и путь к политике. Включить проверку обратно можно установкой с UPDATECHECK=1 – но на уже установленной машине тем же пакетом это работает только при восстановлении:

msiexec /i LaPortaUsb.msi UPDATECHECK=1 REINSTALL=ALL REINSTALLMODE=amus /qn

Причина та же, что и у пути к политике: обычная установка того же пакета идёт режимом обслуживания и уже существующую запись реестра не переписывает – параметр молча не подействует. Новая версия пакета этого ограничения не имеет.

Прокси. Своих настроек прокси у программы нет: и служба, и окно берут их у Windows. Разница в том, чьи настройки берутся.

Служба работает под системной учётной записью и видит машинную настройку WinHTTP – ту, что задаётся групповой политикой или командой:

netsh winhttp show proxy
netsh winhttp set proxy proxy.example.local:3128 "<local>"

Настройки прокси в свойствах браузера службе не видны: они пользовательские. Окно администратора, наоборот, берёт настройки той учётной записи, под которой открыто, включая сценарий автонастройки (PAC).

Прокси, требующему вход, обе программы представляются учётными данными по умолчанию: служба – учётной записью машины (ДОМЕН\ИМЯМАШИНЫ$), окно – учётной записью администратора. Пароля программа не хранит и не спрашивает, поэтому прокси, который пускает только по введённому руками паролю, не подойдёт: проверка будет молча не проходить, а обновление придётся ставить файлом, скачанным вручную.

Наружу нужен один адрес: https://laportausb.ru – манифест, подпись и пакет лежат там же.

Смена версии

Новая версия ставится тем же пакетом (файлом LaPortaUsb.msi новой сборки) с тем же кодом обновления (UpgradeCode) и увеличенной версией – командой установки, как при первой установке:

msiexec /i LaPortaUsb.msi POLICYPATH="C:\ProgramData\LaPortaUsb\policy.json" /qn /l*v install.log

POLICYPATH указывает на тот же локальный путь, что и при первой установке; без него обновление сохранит путь, записанный прежней установкой. Отдельно удалять прежнюю версию не нужно: совпадающий UpgradeCode и увеличенная версия заставляют Windows Installer снять старую и поставить новую в рамках одной команды – это обновление, а не удаление с последующей установкой руками и не подмена файлов в каталоге программы.

Подмена файлов вместо запуска пакета опасна: учёт отключённых узлов живёт в %ProgramData%\LaPorta USB\disabled-nodes.json и хранит вместе с узлом класс носителя. Формат прежних версий новая служба читает, обратно – нет. Подмена файлов на прежнюю версию оставит машину с записями, которых та не понимает: отключённые узлы останутся отключёнными, а служба о них не узнает, и включать их придётся руками через диспетчер устройств. Обновление пакетом этой сложности не создаёт: штатное удаление внутри процесса обновления останавливает службу, та снимает все отключения и очищает учёт, и новая версия начинает с чистого листа.

Удаление

msiexec /x LaPortaUsb.msi /qn

Удаление останавливает службу и дожидается её остановки: при штатной остановке служба снимает отключения с узлов устройств, и удаление файлов раньше оставило бы машину с носителями, которые не работают и после удаления программы. Каталог данных %ProgramData%\LaPorta USB с журналом при удалении не трогается: записи аудита за три месяца – не собственность программы.