SELinux ファイルタイプの変更
Linux上で動くはずのものが動かないとき、特にそれがパーミッション絡みのエラーの場合、だいたいそれはSELinuxさんの仕事だということに薄々感づいてはいた。
数年前まではSELinuxさんとはなるべく関わりたくなかったので、setenforce 0 して何も見なかったことにしてきたけれども、そろそろそんなことをしているエンジニアは西海岸(もしくはオホーツク海)に飛ばされてしまうだろう。臭いものに蓋というやり方は、レベルを上げて物理で殴るにすら劣った戦略である。
今回起きた現象は、「Apacheプロセスに r 権限を与えてあるはずのファイルにHTTP経由でアクセスしたときに 403 Forbidden が返される」というものであった。ちなみに、同じhttpdocs配下にある他のファイルは正常にアクセスできていた。
$ getenforce Enforcing
ここで、
$ sudo setenforce 0
がワークアラウンドになるようであれば、それは十中八九SELinuxの仕事である。
ただしこれを恒久対策としてはいけない。
システムログを確認してみる。
特定プロセスが特定ファイルにアクセスすることをSELinuxがブロックした場合、以下のようなログが出力されているはずである。
for ... の後ろにプロセス名とファイル名が出ているはずなので、それで検索すれば見つかるはず。
$ sudo cat /var/log/audit/audit.log ... type=AVC msg=audit(xxxxxxxxxx.xxx:xxxxx): avc: denied { read } for ... ...
今回 403 Forbidden になった a.html と、正常にアクセスできている b.html を -Z オプションつきで ls してみると、以下のようになっていた。
$ ls -Z -rw-rw-r--. user group unconfined_u:object_r:user_home_t:s0 a.html -rw-rw-r--. user group unconfined_u:object_r:httpd_sys_content_t:s0 b.html
user:role:type:level の順
これはおそらく、a.htmlをscpで自分のホームディレクトリにアップロードした後で、/var/www/ 配下にsudo cpしたのでファイルタイプに差異が発生してしまったのだろう。
そして、httpd_sys_content_tタイプのラベルが付与されていないために、Apacheプロセスがa.htmlにアクセスできず、
結果として403になってしまったということだと推測される。
a.htmlのファイルタイプをhttpd_sys_content_tタイプに変更する。
$ sudo chcon -t httpd_sys_content_t a.html
これでアクセスできるようになった。
【参考】
読んでもあまり理解できなかったFedoraのマニュアル
SELinuxコンテキスト
https://docs.fedoraproject.org/ja-JP/Fedora/19/html/Security_Guide/sect-Security-Enhanced_Linux-SELinux_Contexts.html