Назад | Перейти на главную страницу

Как разрешить apache ротацию журналов в домашнем каталоге пользователя с включенным SELinux?

У нашей машины разработки есть несколько пользователей, и их различные сайты хранятся в /home/username/apache. В этих папках есть подпапки вроде conf содержащий конфигурацию виртуального хоста, logs содержащие журналы, public содержащие фактические веб-файлы и т. д.

Я хочу изменить журналы, чтобы вместо отдельных файлов журналов:

CustomLog "/home/user/apache/domain.tld/logs/web.log" combined

У нас есть журналы, разделенные на ежедневные:

CustomLog "|/usr/sbin/rotatelogs -l /home/user/apache/domain.tld/logs/%Y%m%d_web.log 86400" combined

Однако, когда я вставляю эту конфигурацию, перезапускаю apache, затем перезагружаю страницу, пока audit.log в ausearch, Я вижу такие ошибки:

----
type=SYSCALL msg=audit(06/06/2014 14:16:51.401:406272) : arch=x86_64 syscall=open success=no exit=-13(Permission denied) a0=7fff70a92460 a1=80441 a2=1b6 a3=7fff70a92110 items=0 ppid=64542 pid=64617 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=1193 comm=rotatelogs exe=/usr/sbin/rotatelogs subj=unconfined_u:system_r:httpd_rotatelogs_t:s0 key=(null)
type=AVC msg=audit(06/06/2014 14:16:51.401:406272) : avc:  denied  { search } for  pid=64617 comm=rotatelogs name=home dev=md2 ino=7208961 scontext=unconfined_u:system_r:httpd_rotatelogs_t:s0 tcontext=system_u:object_r:home_root_t:s0 tclass=dir

Я думал, что смогу исправить это, как я исправил другие проблемы SELinux (например, разрешение apache для записи в файлы), изменив тип, но после нескольких попыток я все еще получаю ту же ошибку, что и выше. я пробовал httpd_log_t, httpd_rotatelogs_exec_t и var_log_t но безрезультатно.

Я делал это с chcon команда.

Что мне не хватает?

Актуальная проблема

Чтобы перевести вторую строку предоставленного вами журнала:

В процесс ротации журналов с PID 64617 пробовал искать в домашний каталог, который находится на устройстве md2 и inode 7208961. В доступе отказано.

Контекст безопасности процесс ротации журналов является: unconfined_u:system_r:httpd_rotatelogs_t:s0

Контекст безопасности домашний каталог является: system_u:object_r:home_root_t:s0

Вам необходимо разрешить rotatelogs читать домашний каталог. Разрешить httpd сделать это достаточно просто (setsebool -P httpd_enable_homedirs=1), но, к сожалению, rotatelogs не наследует свой тип от httpd. Что еще хуже, для rotatelogs нет параметра setsebool.

И это еще не все! Вам также необходимо разрешить rotatelogs выполнять поиск вплоть до нужного каталога, а также разрешить ему выполнять все операции, необходимые для его задачи - как с самими файлами, так и с каталогами, которые их содержат.

Короче нужно написать локальную политику.

Пошаговое решение

Создайте где угодно файл с именем homelogs.te, со следующим содержанием:

module homelogs 1.0;

require {
        type httpd_rotatelogs_t;
        type home_root_t;
        type user_home_t;
        type user_home_dir_t;
        class dir { add_name getattr open read remove_name search write };
        class file { create getattr open read rename unlink write };
}

#============= httpd_rotatelogs_t =============
allow httpd_rotatelogs_t home_root_t:dir search;
allow httpd_rotatelogs_t user_home_dir_t:dir search;
allow httpd_rotatelogs_t user_home_t:dir { add_name getattr open read remove_name search write };
allow httpd_rotatelogs_t user_home_t:file { create getattr open read rename unlink write };

Теперь скомпилируйте его:

make -f /usr/share/selinux/devel/Makefile homelogs.pp

И установите его:

semodule -i homelogs.pp

Теперь у rotatelogs должны быть все разрешения, необходимые для выполнения своей задачи в подкаталогах домов пользователей.


Как написать локальную политику

Это для тех, кто хочет получить более подробную информацию о том, как я писал локальную политику. У вас есть два варианта написания политики.

audit2allow

Если вы совершенно новичок в написании локальных политик, один из вариантов - использовать audit2allow инструмент, представленный в policycoreutils-python пакет, чтобы помочь вам написать его.

Чтобы исправить отклонения разрешений SELinux при запуске rotatelogs, вы можете запустить команду

grep rotatelogs /var/log/audit/audit.log | audit2allow -M homelogs

для загрузки журналов аудита, которые включают «ротационные журналы», в audit2allow. Инструмент автоматически проанализирует отказы в разрешении SELinux и создаст файл принудительного применения типов, а также скомпилированный пакет политик (.pp) файл. На этом этапе вы можете просто установить созданный пакет политики, запустив:

semodule -i  homelogs.pp

И вот так вы устранили все проблемы SELinux, связанные с ротацией журналов ... верно?

Проблема с этим подходом в том, что audit2allow не может предсказать, какие разрешения необходимы; он может только проанализировать, в каких разрешениях уже было отказано.

Пока что только отказ в обыске в доме (буквально /home) был обнаружен каталог, поэтому audit2allow только исправлю это. Подумайте, сколько раз вам придется повторно запускать инструмент каждый раз, когда вам будет отказано в следующем разрешении. И в зависимости от конфигурации rotatelogs может потребоваться несколько недель для отказа в конкретном разрешении и его регистрации. Например, сколько времени потребуется ротации журналов, чтобы попытаться удалить старый файл журнала и получить отказ в разрешении на отключение?

Майкл Хэмптон указал в комментариях, что эту проблему можно смягчить, изменив SELinux на разрешающий режим:

setenforce 0

В этом режиме SELinux будет предупреждать и регистрировать действия, но не применяет политику. Это позволяет rotatelogs выполнять все свои задачи, в то время как SELinux по-прежнему регистрирует все отказы в разрешениях. Тогда можно было бежать audit2allow в журнале аудита установить автоматически созданную политику, setenforce 1 чтобы вернуться в принудительный режим, и готово.

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

Ручное создание

Имея некоторое представление о файле Type Enforcement, вы можете решить проблемы с разрешениями до того, как они возникнут, написав его вручную. Я создал файл принудительного применения типов (с .te расширение). Не имеет значения, где находится файл принудительного применения типов.

В файле принудительного применения типов есть три раздела.

Раздел модуля

module homelogs 1.0;

В разделе модуля перечислены имя и версия модуля, который вы будете создавать с помощью своей локальной политики. Имя должно быть уникальным, иначе вы замените уже существующий модуль с таким же именем. Вы можете проверить имена установленных модулей с помощью semodule -l.

Требуемый раздел

require {
        type httpd_rotatelogs_t;
        type home_root_t;
        type user_home_t;
        type user_home_dir_t;
        class dir { add_name getattr open read remove_name search write };
        class file { create getattr open read rename unlink write };
}

Как уже упоминалось Вот:

Этот [раздел] информирует загрузчик политики, какие типы, классы и роли требуются в системной политике перед установкой этого модуля. Если какое-либо из этих полей не определено, команда semodule завершится ошибкой.

В вашей ситуации ротационные журналы будут взаимодействовать с несколькими типы. После запуска ls -Z Я обнаружил, что в исполняемом файле rotatelogs и в каталогах нужного пути потребуются следующие типы:

  • httpd_rotatelogs_t
  • home_root_t
  • user_home_t
  • user_home_dir_t

Вам также необходимо взаимодействовать с некоторыми классы. Полный список классов и их разрешений есть Вот. В вашей ситуации мы будем работать только с class file и class dir. Вы также должны указать разрешения каждого класса, с которым вы будете взаимодействовать. Основываясь на полном списке, я решил потребовать эти классы и разрешения (пара, вероятно, не нужна, но я допустил ошибку):

класс dir:

  • add_name - Добавить файл в каталог
  • getattr - Получить атрибуты файла для файла, например режим доступа. (например, stat, некоторые ioctls. ...)
  • open - Открыть каталог
  • read - Прочитать содержимое файла
  • remove_name - Удалить файл из каталога
  • search - Доступ к поиску
  • write - Общий доступ на запись; требуется для добавления или удаления

файл класса:

  • create -
  • getattr - Получить атрибуты файла для файла, например режим доступа. (например, stat, некоторые ioctls. ...)
  • open - Открыть файл
  • read - Прочитать содержимое файла
  • rename - Переименовать файл
  • unlink - Удалить жесткую ссылку (удалить)
  • write - Записать в файл

Раздел правил

allow httpd_rotatelogs_t home_root_t:dir search;
allow httpd_rotatelogs_t user_home_dir_t:dir search;
allow httpd_rotatelogs_t user_home_t:dir { add_name getattr open read remove_name search write };
allow httpd_rotatelogs_t user_home_t:file { create getattr open read rename unlink write };

В правила раздел читается довольно легко. Например:

allow httpd_rotatelogs_t user_home_t:dir { add_name getattr open read remove_name search write };

примерно означает:

Позволять команды с типом httpd_rotatelogs_t для выполнения операции of add_name, geattr, open, read, remove_name, поиск и запись каталоги с типом user_home_t.

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

Компиляция и установка

Это избыточно, но я упомяну еще раз. Вам необходимо скомпилировать файл Type Enforcement в пакет политик. При беге make, файл Type Enforcement должен находиться в вашем текущем рабочем каталоге.

make -f /usr/share/selinux/devel/Makefile homelogs.pp

Наконец, установите пакет политик как модуль:

semodule -i homelogs.pp


Полезные ресурсы по написанию настраиваемых политик:

Не удалось добавить комментарий к отличному ответу выше, поэтому мне придется добавить новый «ответ»:

Если вы не можете скомпилировать только что созданный модуль из-за отсутствия /usr/share/selinux/devel/Makefile файл, обязательно установите selinux-policy-devel пакет:

yum install selinux-policy-devel

Теперь файл будет существовать, и вы можете продолжить работу с остальным.