Итак, я новичок в CGI / Perl, я пытаюсь переместить веб-приложение на основе Perl на новый сервер.
Мой новый сервер - CentOS 7, на котором работает Apache HTTPD 2.4.6.
Я пытаюсь заставить базовый Perl CGI работать с HTTP-запросом.
Веб-запрос возвращает «500 Internal Server Error»
В журнале ошибок указано «разрешение отклонено»:
[Tue May 12 16:56:44.604660 2015] [cgi:error] [pid 12302] [client 10.0.2.2:56693] AH01215: (13)Permission denied: exec of '/var/www/html/cgi-test/first.pl' failed
[Tue May 12 16:56:44.604708 2015] [cgi:error] [pid 12302] [client 10.0.2.2:56693] End of script output before headers: first.pl
Мой сценарий CGI находится в /var/www/html/cgi-test/first.pl
Выглядит это так:
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, World.";
В каталоге cgi-test разрешения выглядят так:
drwxr-xr-x. 2 root root 21 May 12 16:48 .
drwxr-xr-x. 4 root root 32 May 12 16:48 ..
-r-xr-xr-x. 1 root root 76 May 12 16:48 first.pl
Perl находится в нормальном месте и имеет нормальные права
[root@localhost cgi-test]# ls -al /usr/bin/perl
-rwxr-xr-x. 2 root root 11400 Mar 6 05:07 /usr/bin/perl
Мой httpd.conf по умолчанию. Я только что добавил следующий раздел, чтобы разрешить cgi в моем каталоге cgi-test:
<Directory "/var/www/html/cgi-test">
Options +ExecCGI
AddHandler cgi-script .cgi .pl
</Directory>
Чтобы исключить возможность того, что suexec является причиной этой проблемы, я переместил его из / usr / sbin / suexec в другое имя файла.
Httpd запущен от имени пользователя "apache", который находится в группе "apache"
[root@localhost cgi-test]# ps -Af | grep httpd
root 12298 1 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 12299 12298 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 12300 12298 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 12301 12298 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 12302 12298 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 12303 12298 0 16:56 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
root 12342 12260 0 17:20 pts/0 00:00:00 grep --color=auto httpd
[root@localhost cgi-test]# groups apache
apache : apache
Я пробовал запускать скрипт как apache, он работает без проблем.
[root@localhost cgi-test]# su -s /bin/bash apache
bash-4.2$ perl /var/www/html/cgi-test/first.pl
Content-type: text/html
Hello, World.bash-4.2$
Предположительно я принимаю меры предосторожности Apache. Множество противоречивых советов о том, что это может быть. Любая помощь очень ценится.
Я вижу из вашего собственного ответа, что это была проблема с разрешениями SELinux из-за попытки запустить сценарии CGI из apache в нестандартном каталоге.
Правильный способ решить проблему с разрешениями при поддержании SELinux в «принудительном» режиме и, таким образом, повышения безопасности вашего сервера, - это применить правильный контекст к файлам в вашем каталоге пользовательских сценариев CGI. Если это будет постоянный каталог, вам следует изменить политику selinux, чтобы автоматически создавать новые файлы с соответствующими разрешениями.
Вы можете проверить политику selinux для каталога cgi-bin с помощью команды:
$ semanage fcontext --list | grep cgi-bin
(...)
/var/www/[^/]*/cgi-bin(/.*)? all files system_u:object_r:httpd_sys_script_exec_t:s0
/var/www/html/[^/]*/cgi-bin(/.*)? all files system_u:object_r:httpd_sys_script_exec_t:s0
(...)
Это означает, что каждому файлу, созданному в стандартных каталогах cgi-bin для apache, будет автоматически присвоен тип SELinux. httpd_sys_script_exec_t
и быть исполняемым httpd, поэтому это то, что ваши файлы в cgi-test
каталог также должен иметь.
НОТА: Примеры, показанные ниже, основаны на CentOS / RHEL6, он должен работать точно так же для RHEL7 с возможной настройкой.
Временное решение
Вы можете просто изменить контекст SELinux вашего Perl-скрипта с помощью:
$ chcon -t httpd_sys_script_exec_t /var/www/html/cgi-test/first.pl
Проверьте атрибуты SELinux файла с помощью ls -laZ
:
$ ls -laZ /var/www/html/cgi-test/first.pl
-rwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 /var/www/html/cgi-test/first.pl
Однако, если в этой файловой системе выполняется операция переназначения SELinux, атрибуты будут возвращены к значениям по умолчанию, и она снова перестанет работать. Это также нужно будет делать каждый раз, когда добавляется новый сценарий CGI.
Определенное решение
Вы можете изменить политику SELinux, добавив правило для вашего пользовательского каталога CGI и всех содержащихся в нем подкаталогов и файлов.
Это делается через semanage
команда (доступна в policycoreutils-python
Пакет RPM):
$ semanage fcontext -a -t httpd_sys_script_exec_t "/var/www/html/cgi-test(/.*)?"
Это займет некоторое время. После изменения политики все новые файлы, созданные в вашем пользовательском каталоге, будут иметь новый контекст. Для тех, которые уже есть, вы можете применить политику вручную с помощью:
$ restorecon -R -v /var/www/html/cgi-test
Вы можете проверить свое недавно добавленное правило с помощью:
$ semanage fcontext --list | grep cgi-test
Убедитесь, что вы добавили ScriptAlias в конфигурацию apache, как показано ниже
ScriptAlias /cgi-test/ /var/www/html/cgi-test/
Также попробуйте добавить FollowSymLinks в директиву Options.
Ответ заключался в том, что SELinux блокировал доступ к скрипту.
Благодаря альфамиквиктор за предложение этого ответа.
По умолчанию в CentOS 7 SELinux включен и блокирует perl / CGI. Я подтвердил, что он был включен, используя / usr / bin / sestatus
На старом сервере SELinux был полностью отключен.