- Вопрос или проблема
- Это похоже на головную боль с SE Linux.
- Ответ или решение
- Почему CGI-программа на Perl не может записывать файлы на Fedora 40 с использованием Apache
- 1. Обновления и изменения в настройках безопасности
- 2. Проверка состояния SELinux
- 3. Конфигурация SELinux для CGI
- 4. Проверка прав доступа
- 5. Тестирование и отладка
- Заключение
Вопрос или проблема
На прошлой неделе я обновил свой файл-сервер на Linux с Fedora 39 до Fedora 40, и несколько CGI-приложений, написанных на Perl, перестали работать. Я сначала заметил это, когда Foswiki не смог показать ни одной страницы, потому что не мог открыть свой файл журнала.
После неудачной попытки выяснить, что обновление системы привело к несовместимости между (обновленными) библиотеками perl и (старым) приложением Foswiki, я обнаружил, что приложение, которое я сам написал, имело ту же проблему.
Теперь я уменьшил это до очень маленькой программы, ядром которой являются всего лишь несколько строк:
my $file_to_write = "/tmp/writetest.txt";
unless (open(OUTFILE, ">>", $file_to_write)) {
print "Не удалось открыть (для добавления) $file_to_write.<BR>\n";
}
printf "%s %s Запись теста в $file_to_write\n", ljpDate(), ljpTime();
printf OUTFILE "%s %s Запись теста\n", ljpDate(), ljpTime();
close OUTFILE;
print "Запись завершена<BR>\n";
Похоже, что открытие происходит успешно (я не получаю сообщение "Не удалось .."), но ничего не записывается в файл, хотя у него режим 666
(-rw-rw-rw-
) и он принадлежит apache:apache. Если файл существует, он остается нетронутым, а если его нет, он не создается.
Если я запускаю скрипт из командной строки (./writetest.cgi
), все работает как ожидается.
Это работало на прошлой неделе до обновления. Существует ли какая-то новая функция песочницы, которая мешает моим приложениям?
Это похоже на головную боль с SE Linux.
Проверьте, включен ли SE Linux, сделав это:
sestatus
Вывод должен выглядеть примерно так:
Статус SELinux: включен
Маршрут SELinuxfs: /sys/fs/selinux
Корневая директория SELinux: /etc/selinux
Загруженное имя политики: targeted
Текущий режим: enforcing
Режим из файла конфигурации: enforcing
Статус политики MLS: включен
Статус политики deny_unknown: разрешен
Проверка защиты памяти: актуально (безопасно)
Максимальная версия политики ядра: 33
Если это так, вы можете включить доступ CGI для HTTPD так:
sudo setsebool -P httpd_enable_cgi on;
Затем измените файловую систему для SE Linux вот так:
sudo semanage fcontext -a -t httpd_sys_script_exec_t /var/www/cgi-bin/script.cgi
sudo restorecon -vR /var/www/cgi-bin/script.cgi
И все должно заработать.
Заметки: Просто имейте в виду, что вам может понадобиться установить policycoreutils-python
, чтобы запустить эти команды. Я делаю это для установки этого пакета на Red Hat 7:
sudo yum install policycoreutils-python
В противном случае вы можете отключить SE Linux вот так, чтобы выполнить тесты на скрипте:
sudo setenforce permissive
Чтобы навсегда отключить SE Linux, отредактируйте конфигурацию SE Linux (/etc/selinux/config
) и измените значение:
SELINUX=enforcing
На это:
SELINUX=permissive
И перезагрузите машину, чтобы это значение вступило в силу.
Ответ или решение
Почему CGI-программа на Perl не может записывать файлы на Fedora 40 с использованием Apache
Недавнее обновление с Fedora 39 до Fedora 40 могло повлиять на работу ваших CGI-приложений на Perl по нескольким причинам, среди которых ключевой является состояние SELinux. Давайте подробно рассмотрим, почему ваша CGI-программа не может записывать файлы, даже если она работала без сбоев до обновления.
1. Обновления и изменения в настройках безопасности
После обновления операционной системы возможно изменение настроек и политик безопасности, которые могут препятствовать нормальному выполнения ваших CGI-скриптов. SELinux (Security-Enhanced Linux) — это механизм управления доступом, который может блокировать определенные действия и доступ отдельных процессов к файловой системе.
2. Проверка состояния SELinux
Первый шаг — это проверить, активен ли SELinux на вашей системе. Для этого выполните команду:
sestatus
Если результатом будет сообщение о том, что SELinux включен и работает в режиме enforcing, это может означать, что ваши CGI-скрипты ограничены в доступе к файлам из-за текущих политик безопасности.
3. Конфигурация SELinux для CGI
Если вы установили, что SELinux активирован, следующим шагом будет включение поддержки для CGI в Apache. Введите следующую команду:
sudo setsebool -P httpd_enable_cgi on
Также необходимо убедиться, что ваш CGI-скрипт имеет правильный контекст безопасности. Выполните следующие команды:
sudo semanage fcontext -a -t httpd_sys_script_exec_t /var/www/cgi-bin/script.cgi
sudo restorecon -vR /var/www/cgi-bin/script.cgi
Эти команды добавляют новый контекст безопасности и применяют его к вашему скрипту, что должно позволить его нормальное выполнение.
4. Проверка прав доступа
Вы упомянули, что файл /tmp/writetest.txt
уже существует и имеет права доступа 666 (или -rw-rw-rw-), и что он принадлежит пользователю apache
. Однако если Apache работает с другим пользователем (например, www-data
или nobody
), это также может быть причиной проблем с доступом. Проверьте, какой пользователь запускает Apache, и при необходимости измените права доступа к файлу или смените владельца файла на apache
.
5. Тестирование и отладка
Чтобы протестировать, стали ли ваши файловые операции работать снова, вы можете временно установить SELinux в permissive режим, что позволит вам увидеть предупреждения о блокировке, не препятствуя выполнению скриптов:
sudo setenforce permissive
Если после этих изменений ваша программа заработает, это подтвердит, что проблема действительно заключалась в SELinux.
Заключение
Обновление вашей системы открыло новые аспекты управления безопасностью, которые влияют на работу CGI-приложений на Perl. SELinux может ограничивать доступ к файловой системе, что и произошло в вашем случае. Следуя данным рекомендациям и выполняя соответствующие команды, вы сможете восстановить работоспособность своих CGI-скриптов. Постоянный контроль за политиками безопасности будет полезен для предотвращения подобных инцидентов в будущем.