CentOS の Apache で Perl CGI がファイル生成できないのは SELinux のせいだった

CentOS Linux 上の Apache に Perl CGI を置いたのだが、上手くファイル生成やファイル書き込みができなかった。CGI 自体は動いていて、ファイルの読み込みまではできるのに、書き込みだけがどうにもできない、という状態だった。

パーミッション周りの設定は上手くいっていて、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.cgihoge.log というファイルを touch コマンドで新規生成してみた。比較用に、既に設定を終えて正常に動作している test.cgitest.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.cgitest.log は、system_u:object_r:httpd_sys_script_exec_t:s0 といった SELinux の権限が設定されているようだが、hoge.cgihoge.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 が動作するようになった。

参考文献