SELinuxでApacheからのファイルへのアクセスを許可する
SELinuxが有効になっていると、ファイルシステム上のパーミッションは問題ないはずなのにApacheや同プロセス内で動くPHPからファイルにアクセスできないことがある。 ログファイルの場所を標準とは異なる場所に指定すると、ログの記録に失敗することもある。
ディストリビューションの標準構成ではあらかじめ/var/www/にhttpd_sys_content_tがついているのでApacheがそのコンテンツをサービスできる。
Apacheから読み出しが必要なファイルやディレクトリにはSELinuxのタイプhttpd_sys_content_tを付与する。
Apacheから書き込みが必要なファイルやディレクトリにはSELinuxのタイプhttpd_sys_rw_content_tを付与する。
エラーのログ
/var/log/messages
ログファイルが吐き出せないというエラーはApacheプロセスから/var/log/messagesに吐き出されていた。
code:grep "home/www" messages*
messages-20201220:Dec 18 15:16:39 www httpd209843: (13)Permission denied: AH00091: httpd: could not open error log file /home/www/logs/error_log. messages-20201220:Dec 18 15:16:57 www httpd209855: (13)Permission denied: AH00091: httpd: could not open error log file /home/www/logs/error_log. /var/log/audit/audit.log
ApacheのロードしたPHPモジュールが外部のサイトにTCPで接続しようとして拒否された様子が吐き出されていた。AVCはアクセスベクタ制御のことである。 code:ausearch -i -l -m avc -if /var/log/audit/audit.log | grep http
type=AVC msg=audit(12/15/20 07:34:03.127:21246) : avc: denied { name_connect } for pid=103987 comm=php-fpm dest=80 scontext=system_u:system_r:httpd_t:s0 tcontext=
system_u:object_r:http_port_t:s0 tclass=tcp_socket permissive=0
type=AVC msg=audit(12/15/20 07:49:19.857:21280) : avc: denied { name_connect } for pid=103982 comm=php-fpm dest=80 scontext=system_u:system_r:httpd_t:s0 tcontext=
system_u:object_r:http_port_t:s0 tclass=tcp_socket permissive=0
auditdが動いていなければ/var/log/messagesに吐き出される。 dmesg
ポリシーをロードしましたとかそういうのが出てるっぽい。
code:dmesg | grep SELinux
2.778990 SELinux: policy capability network_peer_controls=1 2.778991 SELinux: policy capability open_perms=1 2.778991 SELinux: policy capability extended_socket_class=1 2.778991 SELinux: policy capability always_check_network=0 2.778992 SELinux: policy capability cgroup_seclabel=1 2.778992 SELinux: policy capability nnp_nosuid_transition=1 2.799719 systemd1: Successfully loaded SELinux policy in 405.062ms. 3625367.352693 SELinux: Context system_u:system_r:ejabberd_t:s0-s0:c0.c1023 became invalid (unmapped). 3625368.028315 SELinux: Context unconfined_u:system_r:ejabberd_t:s0-s0:c0.c1023 became invalid (unmapped). セキュリティコンテキストの確認
code:ls -alFZ /var/www
drwxr-xr-x. 5 root root system_u:object_r:httpd_sys_content_t:s0 43 Oct 7 15:23 ./
drwxr-xr-x. 21 root root system_u:object_r:var_t:s0 4096 Oct 6 07:59 ../
drwxr-xr-x. 2 root root system_u:object_r:httpd_sys_script_exec_t:s0 6 Sep 16 00:46 cgi-bin/
drwxr-xr-x. 2 root root system_u:object_r:httpd_sys_content_t:s0 42 Oct 6 17:22 html/
drwxrwxr-x. 2 hoge hoge unconfined_u:object_r:httpd_sys_content_t:s0 23 Dec 16 12:34 wp/
chconによるタイプの付与
Apacheプロセスに対して読み出しを許可したいならhttpd_sys_content_tを付与する。
Apacheプロセスに対して書き込みも許可したいならhttpd_sys_rw_content_tを付与する。
親ディレクトリ(この場合は/home/wwwにまで付与する必要はないらしい。
タイプは一つだけ付けられる
httpd_sys_content_tのついているファイルやディレクトリにhttpd_sys_rw_content_tを付与するとタイプは上書きされる。
タイプは子に伝播しない
-Rオプションで再帰的にタイプを適用する
$ chcon -R -h -t httpd_sys_content_t /home/www/wp
table:各ディレクトリのコンテキスト
/var/www system_u object_r httpd_sys_content_t s0
/var/www/wp unconfined_u object_r httpd_sys_content_t s0
/home/www unconfined_u object_r user_home_dir_t s0
/home/www/wp unconfined_u object_r user_home_dir_t s0 chconによる変更の前
/home/www/wp unconfined_u object_r httpd_sys_content_t s0 chconによる変更の後
セキュリティコンテキストの復元
chconによるセキュリティコンテキストの変更は一時的なので、restoreconなどにより戻されてしまう。
restorecon -R -v /home/www/wpとすれば元に戻ってしまうはず。-nオプションでdry runできる。
code:restorecon -n -R -v /home/www | head
Would relabel /home/www/wp from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:user_home_t:s0
以下略
参考