На данный момент я понимаю, что вам нужно вручную использовать restorecon
чтобы применить желаемый контекст к вновь созданному файлу или каталогу, если вас не устраивает контекст, который он наследует от своего родительского каталога.
Мне интересно, можно ли автоматически применять контекст при создании на основе его пути без необходимости запускать restorecon
.
Я немного погуглил и нашел эта почта Дэна Уолша, где он упоминает restorecond
который использует inotify
изменить контекст при создании. Он также указывает на очевидную проблему с ним (состояние гонки). Является ли это единственным способом автоматического решения проблемы повторного создания контекста в случае, если дочерний элемент не должен наследовать свой контекст из родительского каталога?
Одна проблема в том, что restorecond
похоже, не обрабатывает записи так же, как /etc/selinux/targeted/contexts/files/file_contexts
, то есть без регулярных выражений, и он не работает рекурсивно, поэтому /etc/selinux/restorecond.conf
не может содержать что-то вроде
/var/www(/.*)?/logs(/.*)?
или
/var/www/*
или даже
/var/www/*/logs
Есть ли способ обойти эту проблему?
РЕДАКТИРОВАТЬ:
Согласно ответу @ Michael, это должно работать OOTB, если существует соответствующее правило, но это не так:
# rm -rf /var/www/foo
# semanage fcontext -a -t httpd_log_t '/var/www/foo/logs'
# grep '/var/www.*logs' /etc/selinux/targeted/contexts/files/file_contexts*
/etc/selinux/targeted/contexts/files/file_contexts:/var/www(/.*)?/logs(/.*)? system_u:object_r:httpd_log_t:s0
/etc/selinux/targeted/contexts/files/file_contexts.local:/var/www/foo/logs system_u:object_r:httpd_log_t:s0
# matchpathcon /var/www/foo/logs
/var/www/foo/logs system_u:object_r:httpd_log_t:s0
# mkdir -p /var/www/foo/logs
# touch /var/www/foo/logs/quux
# ls -alZ /var/www/foo/logs*
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 .
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 ..
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 quux
# restorecon -vR /var/www/foo
restorecon reset /var/www/foo/logs context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_log_t:s0
restorecon reset /var/www/foo/logs/quux context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_log_t:s0
Ядро выполняет следующую процедуру, чтобы определить, каким будет тип вновь созданного файла.
В подавляющем большинстве случаев новые файлы наследуют тип родительских каталогов. Иногда это нежелательно - поэтому разработчик политики может создавать правила, основанные на условиях того, кто и где выполняет маркировку, для перехода к другому типу.
Это контролируется политикой с type_transition
заявление, хотя обычно разработчик политики вызывает filetrans_pattern
макрос вместо этого.
В ядре эти решения основаны не на путях, а на типах (хотя небольшое исключение существует в более новых политиках).
Правило обычно выглядит так;
type_transition httpd_t var_log_t:file httpd_var_log_t;
В этом примере правило гласит, что. Если процесс / пользователь, выполняющий создание файла, httpd_t
а каталог, в котором создается объект, - var_log_t
и объект классифицируется как file
, то новый файл должен быть помечен как httpd_var_log_t
.
Это, конечно, имеет ряд ограничений, хорошим примером этого является условие, когда вы создаете файлы .htaccess в apache (в / var / www / html). В этом примере применяется политика по умолчанию для создания типа файла с тем же типом, что и его родительский каталог, но на самом деле правильный тип этого файла httpd_sys_htacess_t
не по умолчанию httpd_sys_content_t
.
Это была известная проблема в течение ряда лет и в конечном итоге была исправлена, позволив разработчикам политик указать имя файла, к которому применяется переход в политике - к сожалению, эта функция недоступна в EL6.
В вашем конкретном случае - как вы упомянули, есть несколько обходных путей, связанных с restorecond. Помимо этого, вы должны в идеале разделить свои данные на разные типы, поместив их в отдельные подкаталоги, где подкаталог имеет соответствующий тип. Если это по-прежнему невозможно, и restorecond невозможен - единственное решение - это пост-исправление запуска restorecon для файла после его создания.
Даже у «более нового» именованного filetrans есть проблемы, потому что он, в конечном счете, не поддерживает глобализацию или регулярное выражение, что сильно ограничивает его функциональность только специально названными файлами (например, .htaccess).
На данный момент не существует более гибкого механизма в ядре, чем restorecon
и его регулярные выражения для правильной маркировки файлов в этой степени.
Проблема правильной маркировки при создании файла была решена в Fedora 16 с помощью функции, называемой переход имени файла (хотя вы можете найти это также как «именованные переходы файлов»), определение которых в основном гласит:
С помощью функций перехода имен файлов разработчики политик могут писать правила, которые принимают во внимание имя файла, а не путь к нему. Это базовое имя пути к файлу. Так как ядро во время создания объекта знает метку содержащего каталога, метку процесса, создающего объект, и имя объекта. Теперь мы можем написать правило политики, которое гласит, что если процесс unlimited_t создает файл с именем resolv.conf в каталоге с меткой etc_t, файл должен иметь имя resolv.conf.
Известно, что способ пометки объекта во время создания может варьироваться в зависимости от процесса, создающего объект (cp
vs. mv
хороший пример). Кроме того, по умолчанию объект маркируется по наследованию: объект получает метку родительского каталога.
Хотя это удобно, но не всегда правильно, и системный администратор должен исправить ситуацию вручную, используя (комбинацию) restorecon
+ restorecond
+ semanage fcontext -a -t
.
Это проблема, которую пытается исправить при смене имени файла, позволяя
[...] авторы политики имеют возможность перезаписать это, написав правило в политике, которое гласит, что если процесс с типом a_t создает объект класса "file" в каталоге с меткой b_t, объект будет создан c_t.
Очевидно, что именованные файловые переходы не существуют для пользовательских расположений. Вы можете найти уже существующие, например:
# sesearch -ASCT -s unconfined_t | grep Found
...
Found XX named file transition filename_trans:
...
Итак, чтобы решить вашу проблему, вам необходимо заранее знать, какой пользователь (пользователь SELinux) создаст, какой файл / каталог и где, а затем написать собственную политику, включая переход файлов. На вики-странице проекта Fedora, на которую я ссылался выше, есть несколько примеров.
Это не проблема, вы просто подходите к ней не с той стороны.
Если вам нужен собственный файловый контекст, просто создайте свой, используя semanage fcontext
. это делает принимать регулярные выражения.
Вот общий пример, используемый для переместить каталог, из которого Apache обслуживает файлы:
semanage fcontext -a -t httpd_sys_content_t "/volume1/web(/.*)?"
Не стесняйтесь адаптировать это под свои нужды.