だから、私はCGI/Perlを初めて使い、PerlベースのWebアプリを新しいサーバーに移動しようとしています。
私の新しいサーバーはCentOS 7で、Apache HTTPD 2.4.6を実行しています。
HTTPリクエストから基本的なPerl CGIを機能させようとしています。
Webリクエストが「500内部サーバーエラー」を返す
エラーログに「アクセスが拒否されました」と表示されます。
[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-testディレクトリでcgiを許可するために、次のセクションを追加しました。
<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のセキュリティ上の注意事項にぶつかっています。これが何であるかについての多くの矛盾するアドバイス。どんな助けも大歓迎です。
あなたの回答から、それは非標準のディレクトリでApache内からCGIスクリプトを実行しようとしたことが原因のSELinux権限の問題であることがわかりました。
SELinuxを「強制」モードに維持しながら権限の問題を解決し、サーバーのセキュリティを向上させる適切な方法は、カスタムCGIスクリプトディレクトリ内のファイルに適切なコンテキストを適用することです。永続ディレクトリにする場合は、selinuxポリシーを変更して、適切な権限を持つ新しいファイルを自動的に作成する必要があります。
次のコマンドを使用して、cgi-binディレクトリのselinuxポリシーを確認できます。
$ 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
(...)
これは、Apacheの標準cgi-binディレクトリ内に作成されたすべてのファイルにSELinuxタイプhttpd_sys_script_exec_t
が自動的に付与され、httpdによって実行可能になるため、cgi-test
ディレクトリ内のファイルは上手。
注:以下に示す例はCentOS/RHEL6に基づいています。RHEL7でも同様に機能し、最終的にTweakを使用できます。
一時的な解決策
PerlスクリプトのSELinuxコンテキストを変更するには、次のようにします。
$ 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スクリプトが追加されるたびに実行する必要があります。
確実な解
カスタムCGIディレクトリとそれに含まれるすべてのサブディレクトリおよびファイルのルールを追加することにより、SELinuxポリシーを変更できます。
これは、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
その答えは、SELinuxがスクリプトへのアクセスをブロックしていたことです。
この回答を提案してくれた alphamikevictor に感謝します。
CentOS 7ではデフォルトでSELinuxが有効になっており、Perl/CGIをブロックします。/usr/bin/sestatusを使用して有効になっていることを確認しました
古いサーバーでは、SELinuxは完全に無効化されていました。