
У нас есть сервер с ОС Alma Linux 9.3. По умолчанию (как и все текущие RHEL-подобные ОС) он включен fapolicyd
. На этом сервере также запущен сервер приложений (WildFly/JBoss/Java). Развернутое приложение обрабатывает некоторые файлы данных (отправленные пользователями) и отлично работает в стандартной ситуации.
Однако в настоящее время есть период времени, когда приложению необходимо обрабатывать около 1000 файлов в минуту. В такой ситуации накладные fapolicyd
расходы составляют ~15% ресурсов ЦП, что мы оценили как слишком много.
Мне не удалось найти в интернете никого с похожей проблемой.
Я также удивлен, что fapolicyd
здесь нет тега ServerFault.
Вопросы:
- Есть ли способ оптимизировать
fapolicyd
конфигурацию, чтобы она могла быстрее принимать решение о разрешении или запрете доступа к файлу?- Первое, что приходит мне на ум, — это упорядочивание пользовательских правил.
- Возможно, стоит использовать подстановочные знаки вместо буквальных правил.
- Есть ли какие-нибудь подсказки, как оценить, насколько
fapolicyd
это важно для нас?- Можно ли его просто отключить или же оставить его работать, несмотря на огромные накладные расходы, действительно хорошая идея.
- Используют ли другие дистрибутивы что-то подобное
fapolicyd
или это «просто дополнительная безопасность» иSELinux
этого достаточно. (Я знаю, что это не одно и то же.)
Источники:
решение1
Разрешить листинг исполняемых программ — одна из самых эффективных функций безопасности. Без нее скомпрометированная учетная запись пользователя может выполнить любую произвольную полезную нагрузку. Или пользователи устанавливают программы в свой домашний каталог, которые им не следует устанавливать. Хотя это необязательная функция, которую вы решаете включать или нет.
Проверка всех таких вызовов файловой системы имеет удар по производительности. Хотя накладные расходы можно минимизировать, оптимизировав правила и базу данных.
Измерьте, приемлема ли производительность с точки зрения пользователя. Цель, ориентированная на время отклика, например, «99,9% вызовов API приложений будут завершены менее чем за 1 секунду», выявит реальные проблемы, а не только тенденции в использовании ресурсов.
Для начала немного истории fapolicyd, обратите внимание на введение в производительность отREADME-файл:
ПРОИЗВОДИТЕЛЬНОСТЬ
Когда программа открывает файл или вызывает execve, этот поток должен ждать, пока fapolicyd примет решение. Чтобы принять решение, fapolicyd должен найти информацию о процессе и файле, к которому осуществляется доступ. Каждый системный вызов, который fapolicyd должен сделать, замедляет работу системы.
Чтобы ускорить работу, fapolicyd кэширует все, что ищет, так что последующий доступ использует кэш, а не ищет все с нуля. Но кэш не так уж велик. Однако вы контролируете его. Вы можете увеличить как кэш субъекта, так и кэш объекта. Когда программа завершится, она выведет некоторую статистику производительности, например, в /var/log/fapolicyd-access.log или на экран:
Permissive: false q_size: 640 Inter-thread max queue depth 7 Allowed accesses: 70397 Denied accesses: 4 Trust database max pages: 14848 Trust database pages in use: 10792 (72%) Subject cache size: 1549 Subject slots in use: 369 (23%) Subject hits: 70032 Subject misses: 455 Subject evictions: 86 (0%) Object cache size: 8191 Object slots in use: 6936 (84%) Object hits: 63465 Object misses: 17964 Object evictions: 11028 (17%)
В этом отчете вы можете видеть, что внутренняя очередь запросов достигла максимума в 7. Это означает, что у демона было максимум 7 потоков/процессов в ожидании. Это показывает, что он немного задержался, но довольно быстро обрабатывал запросы. Если это число было большим, например, более 200, то может потребоваться увеличение q_size. Обратите внимание, что если вы превысите 1015, то systemd, возможно, придется разрешить более 1024 дескрипторов. В файле fapolicyd.service вам нужно будет добавить LimitNOFILE=16384 или некоторое число, большее, чем ваша очередь.
Еще одна статистика, на которую стоит обратить внимание, — это соотношение попаданий и вытеснений. Когда запросу некуда поместить информацию, он должен что-то вытеснить, чтобы освободить место. Это делается кэшем LRU, который естественным образом определяет, что не используется, и делает свою память доступной для повторного использования.
В приведенной выше статистике коэффициент попадания субъекта составил 95%. Кэш объекта оказался не таким удачливым. Для него мы получаем коэффициент попадания 79%. Это все еще хорошо, но могло бы быть и лучше. Это говорит о том, что для рабочей нагрузки на эту систему кэш мог бы быть немного больше. Если число, используемое для размера кэша, является простым числом, вы получите меньшее перемешивание кэша из-за коллизий, чем если бы у него был общий знаменатель. Вот некоторые простые числа, которые вы могли бы рассмотреть для размера кэша: 1021, 1549, 2039, 4099, 6143, 8191, 10243, 12281, 16381, 20483, 24571, 28669, 32687, 40961, 49157, 57347, 65353 и т. д.
Также следует отметить, что чем больше правил в политике, тем больше правил придется перебрать, чтобы принять решение. Что касается влияния на производительность системы, то оно очень зависит от рабочей нагрузки. Для типичного сценария рабочего стола вы не заметите, что он работает. Система, которая открывает много случайных файлов в течение коротких промежутков времени, будет иметь большее влияние.
Другой параметр конфигурации, который может повлиять на производительность, — это настройка целостности. Если она установлена на sha256, то каждый промах в кэше объектов приведет к вычислению хеша для файла, к которому осуществляется доступ. Одним из компромиссов может быть использование проверки размера вместо sha256. Это не так безопасно, но это вариант, если производительность проблематична.
do_stat_report = 1
в конфигурации, чтобы включить отчет статистики, затем перезапустите fapolicyd, если он не был недавно. Проанализируйте /var/log/fapolicyd-access.log
и отметьте закономерности того, какие PID открывают какие файлы.
Обратите внимание на соотношение «попаданий» и «промахов». Более высокий коэффициент попаданий лучше, доступ к базе данных в памяти намного быстрее, чем доступ к файловой системе и ее обработка. Увеличение obj_cache_size
конфигурации до количества файлов, которые ваша система имеет одновременно. Возможная верхняя граница — это количество используемых inode в файловой системе данных, как из df -i
вывода. Что может быть избыточным, но если у вас есть память, почему бы не кэшировать пару сотен тысяч записей.
Проверьте конфигурацию в fapolicyd.conf. integrity
Значения, отличные от none
или size
, вычисляют контрольную сумму и имеют накладные расходы. Особенно если у вас много промахов при обработке новых файлов, это может быть значительным объемом ЦП. q_size
должно быть больше, чем "максимальная глубина очереди" в отчете о доступе, однако я сомневаюсь, что размер очереди нужно увеличивать.
Просмотрите правила в compiled.rules из rules.d. RHEL и Fedora заполняют доверенные файлы из rpm, не разрешают выполнение неизвестных файлов, не разрешают трюк с ld.so и разрешают большинство открытий. Если вы изменяете правила, подумайте о влиянии на производительность выполнения большего количества действий, пока этот открытый системный вызов ожидает.
И как всегда, вы можете профилировать то, что именно происходит во время устранения неполадок. perf top
Выведет на экран, какие функции задействованы в работе ЦП, и будет еще лучше, если установлена debuginfo. В пакете bcc-tools есть несколько полезных скриптов: opensnoop и execsnoop для составления списка вызовов open и exeve в реальном времени.
В конечном счете, вам решать, какие элементы управления следует установить, чтобы разрешить выполнение только несанкционированных программ. Список разрешений непосредственно в вызове exec, например fapolicyd, конечно, очень мощный. Менее всеобъемлющей альтернативой может быть ограничение доступа к оболочке: не разрешать людям интерактивные оболочки и блокировать разрешения домашних каталогов. Или, если файловая система данных вообще не должна содержать программ, рассмотрите возможность монтирования ее noexec. Хороший аудит безопасности не будет рассматривать контрольный список как неизменяемый, а скорее перечислит альтернативные элементы управления и причины их наличия.