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

Получение скомпилированного модуля Python mod_wsgi, работающего на сервере Apache с принудительным режимом SElinux

Попытка заставить мое приложение Python / Django работать на сервере RedHat в идеальных условиях. Не удалось использовать mod_wsgi из пакета, поскольку у него есть проблема с зависимостями при проверке модулей в моей виртуальной среде, которая использует python 3.6 (некоторая ошибка проверки зависимостей на> python 2.x, похоже, между numpy и pandas), поэтому я был вынужден скомпилировать мой mod_wsgi с использованием PIP, который отлично работал. Потому что я не использую один из признанных каталогов (у меня есть собственный каталог для чистой установки + из соображений безопасности). Если я настрою SELinux на разрешающий, все будет работать отлично, но я хочу, чтобы мое приложение работало с SELinux в принудительном режиме. Я исследовал контексты файлов SELinux и попытался применить их, но, похоже, это работает только частично:

Когда я устанавливаю контекст файла моего модуля mod_wsgi в моей виртуальной среде:

sudo chcon -t httpd_modules_t (специальное расположение) / (virtual_env) / lib / python (версия) /site-packages/mod_wsgi_server/mod_wsgi-py36/cpython-36m-x86_64-linux-gun.so

Ошибки запуска httpd, которые я получил перед установкой нового контекста файла при принудительном применении selinux, исчезли, и служба запустилась правильно, или так казалось ... когда я открываю свои страницы после запуска httpd, я получаю:

Ошибка 500

когда selinux находится в принудительном режиме. Я проверил журнал audit.log и ничего не вижу.

Есть ли у кого-нибудь идеи по этому поводу. Мой файл mod_wsgi в настоящее время имеет следующие настройки:

-rwxrwxr-x. root root system_u: object_r: httpd_exec_t: s0 mod_wsgi-py (версия) .cpython- (версия) m-x86_64-linux-gnu.so

Это кажется правильным, поскольку любой может прочитать и выполнить модуль, а httpd запустится без жалоб. Если я установил принудительное исполнение Selinux после того, как я запустил веб-сервер apache, все будет в порядке до следующего перезапуска веб-сервера apache, который предполагает, что все изначально загружено в память для операций mod_wsgi.

Я просмотрел здесь полный список контекстов файлов для SELinux:

https://linux.die.net/man/8/httpd_selinux

Есть идеи по этому поводу, ребята? Что мне не хватает? Спасибо!

Чтобы добавить информацию тем, кто видит, чтобы помочь:

Я не получаю дополнительных журналов в моем файле audit.log с моих веб-страниц после запуска httpd или доступа к страницам (и получения ошибки 500). Когда я перехожу к http-запросу (мой settings.py перенаправляет на 443), я получаю эту запись в моем журнале ошибок Apache:

[Fri Apr 26 18:10:58.313753 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864] mod_wsgi (pid=6294): Failed to exec Python script file '/var/www/(custom_django_dir)/(custom_section)/(site)/(app)/wsgi.py'.
[Fri Apr 26 18:10:58.313840 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864] mod_wsgi (pid=6294): Exception occurred processing WSGI script '/var/www/(custom_django_dir)/(custom_section)/(site)/(app)/wsgi.py'.
[Fri Apr 26 18:10:58.314117 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864] Traceback (most recent call last):
[Fri Apr 26 18:10:58.314191 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864]   File "/var/www/(custom_django_dir)/(custom_section)/(site)/(app)/wsgi.py", line 18, in <module>
[Fri Apr 26 18:10:58.314206 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864]     application = get_wsgi_application()
[Fri Apr 26 18:10:58.314231 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864]   File "/var/www/(custom_django_dir)/(custom_section)/virtual_env/lib64/python3.6/site-packages/django/core/wsgi.py", line 12, in get_wsgi_application
[Fri Apr 26 18:10:58.314250 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864]     django.setup(set_prefix=False)
[Fri Apr 26 18:10:58.314275 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864]   File "/var/www/(custom_django_dir)/(custom_section)/virtual_env/lib64/python3.6/site-packages/django/__init__.py", line 24, in setup
[Fri Apr 26 18:10:58.314285 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864]     apps.populate(settings.INSTALLED_APPS)
[Fri Apr 26 18:10:58.314307 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864]   File "/var/www/(custom_django_dir)/(custom_section)/virtual_env/lib64/python3.6/site-packages/django/apps/registry.py", line 81, in populate
[Fri Apr 26 18:10:58.314317 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864]     raise RuntimeError("populate() isn't reentrant")
[Fri Apr 26 18:10:58.314350 2019] [wsgi:error] [pid 6294] [remote 142.150.251.220:51864] RuntimeError: populate() isn't reentrant

Я был в похожей ситуации и обнаружил, что chcon - это только половина правды. Проблема в том, что изменения, сделанные с помощью chcon, не являются постоянными и в конечном итоге будут перезаписаны SELinux.

В моем случае большинство файлов были помечены правильно, потому что мой виртуальный сервер находится в / var / www. Но общие объекты должны быть httpd_exec_t, и это помогает:

$ semanage fcontext -a -t httpd_exec_t '/var/www/wsgi/env/.*\.so(\..*)?'
$ restorecon -r /var/www/wsgi/env

Вы найдете эти изменения в /etc/selinux/targeted/contexts/files/file_contexts.local.

Чтобы придумать этот материал, требуется немало исследований. Большинство людей, включая поставщиков фреймворков WSGI, кажется, предлагают просто деактивировать SELinux.

[EDIT] Соответствующая информация на Документация RedHat SELinux

Хорошо, кажется, я понял это, и это может быть полезно другим (исправьте меня, если это возможно):

Ключевым моментом, который я считаю, является контекст файла функциональности:

Для выполняемых скриптов, похожих на скрипт apache, я рассматривал как вариант CGI (скрипты php, похоже, обрабатываются аналогичным образом по умолчанию), поэтому я установил места установки ядра django следующим образом:

sudo chcon system_u:object_r:httpd_sys_script_exec_t:s0 (your folder name)

Я не делал это рекурсивно, потому что у меня был некоторый статический контент и каталоги загрузки, сгруппированные по приложениям, поэтому после того, как я сделал django_root, я вошел и применил команду рекурсивно для моих apps_directories (приложений, а не каталогов сайтов, поскольку они содержат статические и, возможно, загружаемые каталоги) Если для скорости вы хотите сделать это с помощью рекурсивной опции "-R":

sudo chcon -R system_u:object_r:httpd_sys_script_exec_t:s0 (your folder name)

убедитесь, что вы проверили каждый из каталогов загрузки файлов вашего сайта и все файлы для чтения / записи (например, файлы sqlite3) и применили этот параметр:

sudo chcon system_u:object_r:httpd_sys_rw_content_t:s0 (upload folder name)
sudo chcon system_u:object_r:httpd_sys_rw_content_t:s0 (sqlite3 file name)

И статические каталоги файлов (содержащие css, javascript, изображения, файлы шаблонов django (* .html с кодом шаблона)) должны иметь этот параметр с рекурсивной опцией:

sudo chcon -R -t httpd_sys_content_t (folder name)

Примечание. При этом для этих папок / файлов сохраняется их исходная классификация unlimited_u: object_r, что кажется нормальным.

в каталоге, в котором я установил свою виртуальную среду (а), я применяю этот контекст:

sudo chcon -R system_u:object_r:httpd_sys_script_exec_t:s0 (virtual environment directory name)

Это казалось ключевым моментом в том, чтобы мой mod_wsgi полностью заработал. Ошибки, которые я получил в моем предыдущем error_log, не дают интуитивных подсказок, в основном он не может получить доступ к ключевым файлам библиотеки из-за ограничений selinux, которые мы удаляем, установив контекст sys_script_exec.

Если вы скомпилировали библиотеки * .so (как я сделал с моим mod_wsgi), вам нужно сделать этот шаг последним в каталогах с файлами * .so (в моем случае мой скомпилированный mod_wsgi.so находится в (папка приложения django) / (категория папка) / (virtual_env) /lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so с помощью этой команды:

sudo chcon system_u:object_r:httpd_modules_t:s0 (module filename)

когда вы закончите, ваш * .so файл должен выглядеть так, когда вы подтверждаете с помощью ls -Z в вашем каталоге * .so:

-rwxrwx-x. root apache system_u: object_r: httpd_modules_t: s0 (ваш модуль)

Я установил root | apache на всякий случай.

Я установил все свои файлы django в группу apache, кроме файла manage.py. Это я держу как root | root.

Теперь я держу selinux в принудительном режиме, и мои приложения django работают с моим скомпилированным модулем mod_wsgi в произвольном месте.

Надеюсь, это поможет всем. Пожалуйста, не стесняйтесь комментировать и обучать нас. Я получил значительную помощь, просмотрев конфигурации в selinux, выполнив эту команду:

grep httpd /etc/selinux/targeted/contexts/files/file_contexts | less

Вы можете увидеть предварительно настроенные параметры в отношении httpd.

Эта статья оказалась очень полезной:

Управление ограниченными службами, типы серверов Apache Http