Защита на уровне ядра
Перехватчики командной оболочки и интеграции на уровне приложений (рассмотрены в разделе
Перехват и посредничество) можно обойти любым процессом,
который открывает защищённый файл напрямую, минуя командную оболочку или интегрированное приложение.
Чтобы закрыть этот пробел, требуется посредничество внутри собственного пути контроля
доступа ОС — до успешного завершения вызова open().
Функция принятия решения
Посредничество на уровне ядра на любой платформе сводится к одной чистой функции: по
текущей политике, отчёту о состоянии защитного ядра (protection-core) и запросу доступа (путь, идентичность
запрашивающего процесса) вернуть «разрешить» (allow) или «запретить» (deny), а также причину и хэш аудита.
%%{init: {"theme": "base", "themeVariables": {"fontFamily": "-apple-system, Segoe UI, Helvetica, Arial, sans-serif", "primaryColor": "#eef2f7", "primaryTextColor": "#0b0b0b", "primaryBorderColor": "#5b6b7c", "lineColor": "#5b6b7c", "secondaryColor": "#eef4ff", "tertiaryColor": "#f4f3f0", "clusterBkg": "#f9f9f7", "clusterBorder": "#c3c2b7", "edgeLabelBackground": "#fcfcfb", "actorBkg": "#eef2f7", "actorBorder": "#5b6b7c", "actorTextColor": "#0b0b0b", "actorLineColor": "#5b6b7c", "signalColor": "#52514e", "signalTextColor": "#0b0b0b", "labelBoxBkgColor": "#eef4ff", "labelBoxBorderColor": "#5b6b7c", "labelTextColor": "#0b0b0b", "loopTextColor": "#0b0b0b", "noteBkgColor": "#fdf3d9", "noteBorderColor": "#c98500", "noteTextColor": "#3d2f00", "activationBorderColor": "#5b6b7c", "activationBkgColor": "#eef4ff", "sequenceNumberColor": "#ffffff"}}}%%
flowchart LR
Req["Процесс запрашивает\nоткрытие файла"] --> Unprot{"Путь\nзащищён?"}
Unprot -- "нет" --> Allow1["Разрешить\n(оценка не требуется)"]
Unprot -- "да" --> Health{"Защитное ядро\nработоспособно?"}
Health -- "деградировано / недоступно" --> Deny1["Запретить\n(запрет при сбое:\nstrict_fallback)"]
Health -- "работоспособно" --> Ctx{"Контекст процесса\nсоответствует\nодобренному селектору?"}
Ctx -- "неизвестно / неклассифицируемо" --> Deny2["Запретить\nпо умолчанию"]
Ctx -- "явно блокирован" --> Deny3["Запретить\n(блокировка важнее одобрения)"]
Ctx -- "явно одобрен" --> Allow2["Разрешить"]
style Deny1 fill:#fbe4e4,stroke:#d03b3b,color:#5c1616
style Deny2 fill:#fbe4e4,stroke:#d03b3b,color:#5c1616
style Deny3 fill:#fbe4e4,stroke:#d03b3b,color:#5c1616
Два свойства этой функции важнее любого платформо-специфичного механизма:
- Неизвестное отклоняется. Процесс, который система не может классифицировать, по умолчанию считается недоверенным.
- Неработоспособное защитное ядро полностью отклоняет доступ к защищённым путям. Незащищённые пути остаются доступными, чтобы рабочая станция не оказалась заблокированной полностью, но конкретная гарантия, ради которой существует этот компонент, деградирует до полностью закрытого состояния с отказом всем запросам.
Linux — fanotify (реальное принудительное применение на уровне ядра, в рабочей среде)
Посредничество на Linux использует fanotify с FAN_CLASS_CONTENT и
FAN_OPEN_PERM / FAN_OPEN_EXEC_PERM — настоящий механизм разрешений ядра:
ядро блокирует вызывающий процесс до ответа монитора, и ответ монитора является
окончательным. Метки размещаются в масштабе всей файловой системы там, где это
поддерживается ядром, иначе используются метки на уровне точки монтирования. Это
дополняется двумя дополнительными уровнями для эшелонированной защиты:
%%{init: {"theme": "base", "themeVariables": {"fontFamily": "-apple-system, Segoe UI, Helvetica, Arial, sans-serif", "primaryColor": "#eef2f7", "primaryTextColor": "#0b0b0b", "primaryBorderColor": "#5b6b7c", "lineColor": "#5b6b7c", "secondaryColor": "#eef4ff", "tertiaryColor": "#f4f3f0", "clusterBkg": "#f9f9f7", "clusterBorder": "#c3c2b7", "edgeLabelBackground": "#fcfcfb", "actorBkg": "#eef2f7", "actorBorder": "#5b6b7c", "actorTextColor": "#0b0b0b", "actorLineColor": "#5b6b7c", "signalColor": "#52514e", "signalTextColor": "#0b0b0b", "labelBoxBkgColor": "#eef4ff", "labelBoxBorderColor": "#5b6b7c", "labelTextColor": "#0b0b0b", "loopTextColor": "#0b0b0b", "noteBkgColor": "#fdf3d9", "noteBorderColor": "#c98500", "noteTextColor": "#3d2f00", "activationBorderColor": "#5b6b7c", "activationBkgColor": "#eef4ff", "sequenceNumberColor": "#ffffff"}}}%%
flowchart TB
L1["Уровень 1 — перехватчик оболочки через profile.d\n(покрывает интерактивные оболочки)"]
L2["Уровень 2 — LD_PRELOAD\n(покрывает динамически линкованные процессы)"]
L3["Уровень 3 — fanotify FAN_OPEN_PERM\n(на уровне ядра, покрывает всё остальное,\nвключая статически скомпонованные исполняемые файлы)"]
L1 -.обходится процессами вне оболочки.-> L3
L2 -.обходится статически скомпонованными исполняемыми файлами.-> L3
style L3 fill:#2a78d6,stroke:#184f95,color:#ffffff,stroke-width:2px
Уровень 3 — фактическая граница безопасности; уровни 1–2 существуют для низконакладной обработки типового случая и более понятных сообщений об ошибках.
macOS — Endpoint Security Framework (реализовано, требует разрешения Apple)
Реализация для macOS использует системный интерфейс Apple Endpoint Security, подписываясь на
события авторизации класса AUTH_OPEN из выделенного процесса protection-core, с той
же моделью классификации, что и на Linux (путь исполняемого файла, идентичность
подписи кода, идентификатор команды, цепочка родительских процессов), и теми же состояниями
работоспособности (healthy, degraded, unavailable, unsupported), которые питают ту
же функцию принятия решения с запретом при сбое.
Перед выбором Endpoint Security были рассмотрены четыре альтернативы: три отклонены по техническим соображениям, одна отложена:
| Альтернатива | Статус | Обоснование |
|---|---|---|
| Только посредничество через перехватчики командной оболочки | Отклонена | Не покрывает процесс, который открывает файл напрямую, минуя любую оболочку |
| FSEvents / журналы аудита / периодические проверки | Отклонена | Наблюдательный и отложенный подход — может сообщать только постфактум, не может заблокировать до завершения чтения |
| Профили песочницы / TCC / права доступа файловой системы | Отклонена | Не может чисто выразить модель политики продукта, основанную на идентичности процесса |
| Аналог модуля ядра / eBPF в стиле Linux | Отложена, технические качества не оценивались | Решение сначала реализовать Endpoint Security было вопросом последовательности (сначала доказать модель на самой сложной платформе), а не выводом о том, что механизм в стиле Linux неприменим к macOS — эта альтернатива просто не была оценена для macOS на данном этапе |
Далее: Перехват и посредничество.