Вопрос или проблема
У меня есть задача, которая должна быть довольно простой:
Перенести набор пользовательских логов в базу данных ночью.
Я использую logrotate (cron.daily) с простой задачей prerotate
/var/log/myapplog/*.log
{
daily
copytruncate
rotate 366
dateext
dateformat .%Y-%m-%d
compress
missingok
compresscmd /usr/bin/xz
compressoptions -ze9
compressext .xz
prerotate
/usr/local/myapp/bin/DBWriter $1
endscript
}
К сожалению, SELinux не считает это так. Если я выполню setenforce 0
, то скрипт работает без проблем. Логи вращаются, отправляются в базу данных и так далее.
Однако setenforce 1
возвращает :
logrotate_script: line 1: /usr/local/myapp/bin/DBWriter: Permission denied
Я пытался изменить контексты на DBWriter, в последний раз я установил его на unconfined_u:unconfined_r:unconfined_t
, что тоже не помогло…
В идеале, мне нужно оставить SELinux включенным. Если это важно, DBWriter также доступен в виде Java .jar файла. Но выполнение java -jar DBWriter.jar
дает такой же результат.
Спасибо заранее!
Редактировать: Ответ Win.T ниже решил проблему для меня.
semanage permissive -a logrotate_t
Частично проблема в том, что я пытался сделать именно то, что SELinux предназначен предотвращать: заставить процесс A выполнить неизвестный файл B и вызвать хаос в системе C.
Проектные соображения и ограничения привели нас к этому пути.
Клиенты не всегда хотят слышать о таких модных модных словах, как безопасность и защита на будущее.
Посмотрите в /var/log/messages
и /var/log/audit/audit.log
(если у вас запущен auditd
). Вы также можете использовать audit2allow
для просмотра сообщений об ошибках SELinux и возможных решений.
Кроме того, попробуйте semanage permissive -a logrotate_t
, чтобы позволить logrotate работать и не быть заблокированным SELinux.
Если вы не уверены, что это SELinux, сначала попробуйте временно отключить принудительное применение SELinux sudo setenforce 0
Ссылка на SELinux и запустить код, который не работал. Если это SELinux, читайте дальше…
Я столкнулся с этой проблемой недавно и был довольно не знаком с SELinux, поэтому это был небольшой учебный процесс для меня. В отличие от стандартных posix разрешений (DAC), использующих chmod
и chown
, SELinux имеет гораздо более детализированную систему разрешений. Он в некоторых случаях будет запрещать определенные операции, такие как подключение к интернету через TCP/443, или разрешать запись в /foo и /bar, но нигде больше в зависимости от вызывающего (приложения).
Для просмотра разрешений (MAC) обязательного контроля доступа файла используйте ls -Z
или id -Z
с выводом в формате user:role:type:level
.
В моем случае на Centos7 у меня был скрипт, вызванный в конфигурационном файле logrotate.d с скриптом prerotate, который загружал файл журнала перед его вращением. У меня было несколько запретов (записанных в /var/log/audit/audit.log
). Я узнал, что можно использовать несколько инструментов для генерации специфического пакета политик для установки. Я создаю .rpm пакеты для нашего кода, поэтому я добавил все шаги ниже в .spec файл, чтобы генерировать и устанавливать пакет политик во время установки.
Что вам понадобится: policycoreutils-python, checkpolicy (возможно, уже установлены)
Насколько я понимаю, если вы планируете распространять эту политику безопасности, идея заключается в том, чтобы отправлять только файл *.te и генерировать политику на месте, чтобы, если определения, от которых зависит эта политика, будут обновлены, они будут унаследованы во время установки.
#поиск сообщений о запрете
watch "tail /var/log/audit/audit.log | grep 'denied'"
# создание файла te (типовое применение) (читаемая человеком политика безопасности)
grep 1561055176.928:11371 /var/log/audit/audit.log|audit2allow -m myapp > myapp.te
# вы также можете grep несколько неудач и передать их все в audit2allow
cat /var/log/audit/audit.log | grep logrotate | audit2allow -m myapp > myapp.te
# вы также можете использовать audit2why, чтобы дать вам небольшое объяснение того, почему это иногда не срабатывает с шагами по устранению проблем
cat /var/log/audit/audit.log | grep logrotate | audit2why
ПРЕДУПРЕЖДЕНИЕ В этот момент я обнаружил, что audit2why сообщает, что мой скрипт будет работать, если я выполню setsebool -P nis_enabled 1
. Хотя это звучит хорошо, вам следует всегда узнать, каковы.security implications выполнения этих команд. Установка этого может увеличить поверхность атаки, так что будьте осторожны.
# создание модуля политики из файла типового применения
checkmodule -M -m -o myapp.mod myapp.te
# создание пакета политики из модуля политики
semodule_package -o myapp.pp -m myapp.mod
# загрузка пакета политики с привилегиями root
semodule -i myapp.pp
Мне пришлось пройти через эти шаги несколько раз, пока я не собрал все мелкие разрешения, необходимые моему коду для работы.
— обновление —
В конце концов, я запустил свой скрипт в встроенном режиме прямо перед заданием cron logrotate, так что мне не пришлось расширять разрешения logrotate_t. Я добавил его в prerotate, потому что не хотел вращать файл при сбоях, что эта синтаксис все еще удовлетворяет. Используя синтаксис ‘&&’, если первая команда не срабатывает, вторая не будет выполнена.
10 * * * * root /usr/bin/sudo -i -u otheruser /opt/send_logs.sh && /usr/sbin/logrotate -f /path/to/myapp_logrotate.conf > /tmp/myapp_rotate.log 2&1
Похоже, что ваша проблема связана с политиками SELinux, ограничивающими выполнение вашего пользовательского скрипта DBWriter во время вращения журналов. Это классический сценарий, когда SELinux обеспечивает безопасность, ограничивая неизвестные выполнения, что и является его целью. Вот решение, которое сохраняет SELinux включенным:
Шаги для решения:
-
Анализируйте запреты SELinux:
Используйтеaudit2allow
, чтобы создать пользовательские политики SELinux:sudo ausearch -c 'logrotate' --raw | audit2allow -M logrotate-custom sudo semodule -i logrotate-custom.pp
Это позволит logrotate запускать ваш пользовательский скрипт без глобального компрометирования SELinux.
-
Установите logrotate в разрешающий режим (если необходимо временно):
semanage permissive -a logrotate_t
Это обеспечит выполнение logrotate вашего скрипта, сохраняя активным SELinux для других процессов.
-
Сохраняйте безопасность, оптимизируя политики:
Если ваши разрешения скрипта или настройки SELinux требуют тонкой настройки, Vultr предоставляет полезное руководство по отключению или настройке SELinux: Отключение SELinux на CentOS 7. Используйте это в качестве справочного материала для создания индивидуального подхода, а не для полного отключения SELinux.
Совет:
Проектные соображения, такие как защита скриптов и изоляция процессов, имеют решающее значение для избежания подобных проблем. Реализация лучших практик для SELinux может избавить вас от подобных головных болей в будущем.
Этот сбалансированный подход гарантирует, что вы соблюдаете протоколы безопасности, выполняя при этом вашу задачу.
Ответ или решение
Разрешение проблем с SELinux, logrotate и prerotate
Введение
При реализации автоматической обработки логов с использованием утилиты logrotate и SELinux могут возникнуть проблемы с разрешениями. В данном случае, выполнение скрипта DBWriter
перед ротацией логов запрещается, когда SELinux находится в режиме принудительного контроля. Это явление связано с принципами безопасности, которые SELinux реализует для защиты системы.
Анализ проблемы
Суть проблемы заключается в том, что SELinux предотвращает выполнение скрипта DBWriter
при его вызове из prerotate
в конфигурационном файле logrotate. При отключении принудительного режима с помощью команды setenforce 0
проблема исчезает, что свидетельствует о том, что именно политика SELinux блокирует выполнение.
Политики SELinux
SELinux использует механизмы управления доступом на основе меток (MAC), которые существенно отличаются от стандартных POSIX разрешений. Каждому файлу и процессу назначается контекст SELinux, который определяет уровень доступа. Для решения данной проблемы необходимо убедиться, что контекст SELinux для скрипта DBWriter
позволяет его выполнение из контекста logrotate.
Шаги по решению проблемы
-
Анализ отказов SELinux:
Для начала следует просмотреть журнал аудита и выявить точные причины отказа управления:sudo ausearch -c 'logrotate' --raw | audit2allow -M logrotate-custom sudo semodule -i logrotate-custom.pp
Данная команда сформирует модуль политики SELinux, который разрешит выполнение вашего скрипта без глобального изменения политики SELinux для других процессов.
-
Временное изменение политики:
Если необходимо временно сохранить возможность выполнения скрипта, можно временно перевести политику logrotate в режим "пермиссив", что позволит выполнить скрипт без изменения его контекста. Используйте следующую команду:sudo semanage permissive -a logrotate_t
-
Оптимизация политик безопасности:
Чтобы предотвратить подобные проблемы в будущем, рекомендуется тщательно настраивать разрешения SELinux. Занимайтесь ручной доработкой политик, добавляя только те разрешения, которые необходимы для выполнения вашего скрипта, сохраняя при этом общий уровень безопасности системы.
Заключение
Использование SELinux является важным аспектом обеспечения безопасности систем Linux. При возникновении проблем с разрешениями, связанных с автоматизированными задачами, такими как ротация логов, ключевым моментом является понимание механизмов, с помощью которых SELinux контролирует доступ к ресурсам. Ликвидировав источники отказов путём настройки политик, можно не только устранить существующую проблему, но и предотвратить подобные ситуации в будущем.
Советы
- Мониторинг журналов: Регулярно проверяйте журналы
/var/log/audit/audit.log
для выявления потенциальных отказов. - Строгое соблюдение политики безопасности: Всегда анализируйте последствия при применении изменений к политикам SELinux.
- Планирование автоматизированных задач: Учите брать во внимание специфические требования безопасности при проектировании автоматизированных процессов.
Следуя данным рекомендациям, вы сможете эффективно управлять системами с активированным SELinux, избегая проблем с разрешениями при помощи интеграции с logrotate и другими утилитами.