CentOS の Apache で Perl CGI がファイル生成できないのは SELinux のせいだった
CentOS Linux 上の Apache に Perl CGI を置いたのだが、上手くファイル生成やファイル書き込みができなかった。CGI 自体は動いていて、ファイルの読み込みまではできるのに、書き込みだけがどうにもできない、という状態だった。
- Apache デフォルトの
cgi-bin/
配下に.cgi
ファイルが置いてある httpd.conf
でExecCGI
などの設定は出来ている.cgi
ファイルのパーミッションは 777、テキストの書き込み先である.log
ファイルは 666 で権限が付与できている- オーナーの設定も
apache
に変えてあって問題ないはず
パーミッション周りの設定は上手くいっていて、Mac 上の Apache では動作するするスクリプトだったので、何が悪いのかしばらく分からなかったのだが、どうやら SELinux という機能が邪魔していることが分かった。
SELinux とは
SELinux とは、ディストリビューションの名前ではなく、ファイルやディレクトリに対する細かなアクセス制御をかけられる機能のことで、CentOS などでは最初から導入されているみたい。
もっと平たくいうと、ls -l
で見える権限の他に、ls -Z
で見える独特の権限を付与する機能がある、という話だ。
SELinux の状況を見る
SELinux が動作していて、アクセス制御を実施しているかどうかを確認するには、$ sestatus
というコマンドを叩く。この中の Current mode:
が enforcing
だったら、制御機能がかかっている状態だ。
他にも、$ getenforce
というコマンドでも状況を確認できる。コマンドが見つからないと云われた場合は $ sudo getenforce
と叩くと良い。コチラも、Enforcing
なら動作中だ。
SELinux の動作を一時的に無効にする
本当に SELinux が邪魔しているのか確認するために、まずはコイツの機能を切ってみる。$ setenforce 0
(必要に応じて $ sudo setenforce 0
) と叩くと、モードを Enforcing から Permisive に変えられる。
Permissive というのは、アクセス制御がかかるべき時に警告ログを出力はするものの、実際にアクセス遮断はしない、というデバッグモード。完全に Stop もできるが、この setenforce
はマシンの再起動によって元に戻ってしまう一時的な設定変更なので、Permissive にできればまずは良いだろう。
で、この状態で httpd
サービスを再起動させてみて ($ sudo systemctl restart httpd
など)、CGI が動作するか確認してみよう。chmod
で設定できるようなパーミッション周りや、httpd.conf
の設定内容に問題がなければ、上手くファイル生成やファイル追記ができるはずだ。
SELinux の権限を正しく与えてみる
前述のとおり、setenforce
コマンドによる SELinux 機能の無効化は、あくまで一時的なモノであり、セキュリティリスクを考えると無効にしっぱなしは怖い。
そこで使用するのが、restorecon
というコマンド。コレを cgi-bin/
配下にあるファイルに対して適用すれば、適切に権限を付与してくれる。
試しに、hoge.cgi
と hoge.log
というファイルを touch
コマンドで新規生成してみた。比較用に、既に設定を終えて正常に動作している test.cgi
と test.log
というファイルも置いてみた。この時点での状況は以下のとおり。
$ ls -lZ
-rw-rw-r--. apache apache unconfined_u:object_r:httpd_sys_script_exec_t:s0 hoge.cgi
-rw-rw-r--. apache apache unconfined_u:object_r:httpd_sys_script_exec_t:s0 hoge.log
-rwxrwxrwx. apache apache system_u:object_r:httpd_sys_script_exec_t:s0 test.cgi
-rw-rw-rw-. apache apache system_u:object_r:httpd_sys_script_exec_t:s0 test.log
正常に設定できている test.cgi
と test.log
は、system_u:object_r:httpd_sys_script_exec_t:s0
といった SELinux の権限が設定されているようだが、hoge.cgi
と hoge.log
の方は、unconfined_u:object_r:httpd_sys_script_exec_t:s0
と書かれている。中身はよく分からないが、unconfined
あたりの文言から察するに、何かイマイチっぽい感じがする (爆
そこで、restorecon
コマンドを使って、SELinux の権限を自動で再設定させてみる。
$ restorecon -RF hoge.cgi hoge.log
$ ls -lZ
-rw-rw-r--. apache apache system_u:object_r:httpd_sys_script_exec_t:s0 hoge.cgi
-rw-rw-r--. apache apache system_u:object_r:httpd_sys_script_exec_t:s0 hoge.log
-rwxrwxrwx. apache apache system_u:object_r:httpd_sys_script_exec_t:s0 test.cgi
-rw-rw-rw-. apache apache system_u:object_r:httpd_sys_script_exec_t:s0 test.log
すると、このようにどうも設定が上手くいったようである。念のため httpd
を再起動すると、上手く CGI が動作するようになった。
参考文献
- 参考 : 【ざっくりと理解する】SELinuxとは?
- 参考 : SELinux を使おう.使ってくれ. - Qiita
- 参考 : Apache に関する SELinux の設定 (CentOS) - Qiita
- 参考 : Apache index.phpやindex.cgiをディレクトリ"/"で呼び出す方法 · DQNEO起業日記
- 全くの別件だが、
httpd.conf
のDirectoryIndex
にindex.cgi
を追加すれば CGI ファイルを/
で呼び出せる
- 全くの別件だが、