LaPorta USB

Как устроена LaPorta USB

Что делает программа

LaPorta USB ведёт журнал подключения USB-носителей на рабочей станции и применяет к ним правила: полный доступ, только чтение или запрет. Работает штатными средствами Windows – драйвера в ядре нет.

Из чего состоит

Три исполняемых компонента: служба, агент в трее и окно администратора.

Служба LaPortaUsb

Слушает события подключения USB-устройств, принимает решение по политике и применяет его. Работает под системной учётной записью.

Раз в сутки она же спрашивает сайт программы, не вышла ли версия новее, и при более новой пишет в журнал update_available. Сама ставит обновление только если политика назвала часы (install_updates): установка останавливает службу, и выбирать минуту, когда машина останется без запретов, должен администратор. Без этих часов обновление ставит человек – кнопкой в окне управления. Проверка выключается политикой, а на машине целиком – параметром установки. Подробности – в install.md.

Агент в трее

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

В меню значка – перечень подключённых носителей, «О программе» и «Открыть управление». Последний пункт виден всем, но помечен щитом: окно объявлено требующим прав администратора, и обычному пользователю Windows покажет запрос пароля. Так администратор открывает управление на рабочем месте сотрудника, не перезаходя в систему. Пункты «Открыть журнал» и «Выход» видны только администратору: журнал – служебные данные, а закрыть агента сотрудник не должен, иначе запреты останутся в силе, но уведомления о них пропадут.

Окно управления агент запускает как отдельную программу, и одностороннего канала до службы это не отменяет.

Окно администратора

Три вкладки: устройства, журнал, политика. Требует прав администратора.

Два режима: наблюдение и применение

Режим задаётся полем политики enforcement_mode.

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

Два слоя запрета

Реактивный слой

Носитель подключили – служба отключает узел устройства (для запрета) или ставит признак «только чтение» на диск. Работает по факту подключения. Признак «только чтение» действует только на том, который удалось перемонтировать: на занятом томе запись продолжает идти, и служба сообщает об этом – см. troubleshooting.md.

Превентивный слой, он же строгий режим

Включается полем strict_mode и только в режиме применения (enforce) – в режиме наблюдения он отключён, даже если strict_mode установлен. Служба правит ветку ограничений установки устройств: запрещает идентификатор устройства USBSTOR\GenDisk и разрешает поимённо конкретные экземпляры – белый список.

Реактивный слой узнаёт о носителе из уведомления системы, то есть после того, как Windows уже установила устройство, смонтировала том и выдала букву: какое-то время носитель живой. На приёмке режима применения это окно после перезагрузки машины составило от 12,3 до 16,0 секунды, а в одном замере – до 37 секунд от старта службы до применения; всё это время носитель оставался полностью доступен, и запрет обходился перезагрузкой. Превентивный слой закрывает это окно целиком: неизвестный носитель не устанавливается вовсе, буква не появляется, отключать нечего.

Запретов по классу устройств там нет намеренно – в класс дисков входит системный диск машины, и запрет по классу способен оставить её незагружаемой.

Внешние диски с мостом UASP слой не закрывает. Запрещается идентификатор USBSTOR\GenDisk, а диск в коробке USB 3.x с этим протоколом система перечисляет узлом SCSI\Disk… без такого идентификатора: он устанавливается как прежде, и держит его один реактивный слой – по предку на шине USB. Второй запрещающий идентификатор здесь не добавлен по той же причине, что и запрет по классу: узлы SCSI\Disk есть и у системного диска машины. Слой рассчитан на флешки и диски, идущие через USBSTOR.

Занятая ветка слой не включает. Ветку правит не только эта программа: в неё пишут доменная политика и средства защиты, и та же политика Windows – обычный способ запретить USB-накопители через групповую политику, причём под теми же самыми именами значений. Отличить своё от чужого по именам значений поэтому нельзя. Правило простое: если при первом обращении в ветке уже что-то было, она считается чужой и не трогается ни на включение, ни на снятие – служба остаётся на одном реактивном слое и пишет событие strict_mode_conflict, см. journal-reference.md. Своей ветка становится, только когда служба завела её сама; свидетельство этому – копия ветки, снятая перед первой правкой (см. troubleshooting.md).

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

Если по записи своё уже снято, а под теми же именами что-то лежит, ветку занял кто-то другой, чаще всего доменная политика. Служба её не перепишет и не снимет, а напишет strict_mode_conflict.

Сложнее, когда по записи служба ещё держит ограничения, а содержимое с записью не сходится. Так же выглядит установка, обновлённая с версии, которая записи не вела: записи нет вовсе. Отличить свою неудавшуюся правку от чужой тут нечем, поэтому содержимое считается сомнительным: служба его не перепишет и тоже напишет strict_mode_conflict, но при выключении strict_mode или при остановке снимет как своё. Доменная политика вернёт своё при ближайшем обновлении, а машина, оставшаяся с ограничениями и без программы, не вернула бы накопители никогда.

Порядок регистрации носителя. Белый список строится из носителей, по которым журнал уже принял решение allow. Новый носитель нужно сначала подключить при выключенном strict_mode и только потом включить режим – иначе он не установится и в список не попадёт никогда.

В список попадает не только USB-накопители, а всё, что когда-либо получило allow: токены, переносимые устройства, картридеры на шине PCI, телефоны. Это не безобидно само по себе – белый список переживает ужесточение политики: носитель, получивший allow до того, как его класс запретили, остаётся в списке до конца срока хранения журнала и продолжает устанавливаться. Ветка к тому же растёт вместе с историей журнала. Один и тот же носитель может попасть в список сразу под несколькими узлами разных классов, например как накопитель и как переносимое устройство того же корпуса; запрету по накопителю это не мешает, но по содержимому ветки может показаться, что носитель разрешён шире, чем на деле.

Умолчание other: allow в паре со strict_mode пробивает дыру: носитель, который классификатор отнёс к other, остаётся в белом списке даже при flash: block и устанавливается. Это согласуется с политикой – умолчание other: allow так и задумано, – но в превентивном слое цена выше, чем в реактивном: там неопознанное устройство хотя бы попадает в журнал, здесь оно просто ставится.

Срок жизни белого списка. Ограничен retention_days из раздела log политики (см. policy-reference.md): список видевшихся носителей служба строит из журнала за это окно, и носитель, чьи записи в окно не попадают, из списка выпадает и перестаёт устанавливаться – без единой записи о причине. Средство – увеличить retention_days.

Не проверено: это следует из того, как строится список (служба читает журнал за срок retention_days), а не из опыта – само истечение срока не воспроизводили ни на живой машине, ни тестом.

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

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

Когда политика недоступна

Три состояния:

Что программа намеренно не делает