Попытка заставить мое приложение 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