トラブルシュート

【解決法】Apache/nginxが403 forbiddenが表示される (パーミッション777でも)

事象

パーミッション設定は 777 になっているのに、Apache や Nginx で 403 forbidden が表示される。

原因

RedHat 系なら SELinux , Debian (Ubuntu 含む) 系なら AppArmor が有効になっていて、かつ、表示されないファイルのコンテキスト(SELinux/AppArmor におけるアクセス権) が適切な値になっていない。

原因詳細

SELinux , AppArmor は、通常の xfs/ext4 等で使われるアクセス権 (パーミッション) ではカバーしきれないセキュリティを提供する機能です。バッファオーバーフロー攻撃等でプロセスが乗っ取られた際に、被害の範囲を限定することができるのが、SELinux/AppArmor の主なメリットです。

例えば SELinux を有効にしている場合、httpd というプロセスは [httpd_sys_content_t] 等の特定のコンテキストが無いとアクセスができません。なので、例えば postfix プロセスが乗っ取られた場合は、この[httpd_sys_content_t] というラベルのつけられたファイルにアクセスすることはできません。

この SELinux のコンテキストは、NSA および Linux のディストリビュータが「こういった設定が望ましい」というポリシーを記載したファイルを同梱しており、それに基づいて自動的に付与されます。

ただし、SELinux を有効化する前に作ったファイルや、どこかで作成したファイルを移動 (cp ではなく mv) してきた場合、はたまた、プロセスユーザが想定していないディレクトリにファイルを作った場合 (例えば Apache で DocumentRoot を /temporary/ 等に指定した場合) などは、このコンテキストが正しく付与されない場合があります。

解決方法

解決方法1. (RedHat系の場合) SELinux を無効化する

まず SELinux が有効化になっているかを確認します。

# getenforce

このコマンドの結果、 "Enforcing" が返ってきた場合は SELinux が有効になっていますので、以下コマンドで一時的に無効化します。

# setenforce 0

再起動後も恒久的に SELinux を無効化し続けたい場合は、/etc/selinux/config を以下のように変更します。

SELINUX=enforcing

と書かれている箇所を

SELINUX=disabled

に修正します。

解決方法1. (Debian/Ubuntu 系の場合) AppArmor を無効化する

まずは AppArmor が有効化されているか確認します。

 systemctl status apparmor

以下で一時的に無効化します。(再起動すると有効化に戻ります。)

 systemctl stop apparmor

以下で再起動後も恒久的に無効化します。

 systemctl disable apparmor

解決方法2. 該当ディレクトリに適切なコンテキストを設定する

例えば /temporary/ を DocumentRoot にした場合、以下コマンドでこのディレクトリおよび配下のディレクトリ・ファイルに httpd_sys_content_t を付与します。

現状どのコンテキストが割り当たっているかを確認するには、lsコマンドに-Zオプションを使います。

ls -dZ /temporary

付与する方法も一時的に付与する方法と、永続的(再起動後も有効)に付与する方法があります。

一時的に付与する場合は、chcon コマンドを使います。

# chcon -R -t httpd_sys_content_t /temporary

-Rは再帰的に/temporary配下のディレクトリ・ファイルにも適用するオプション、-t は付与したいコンテキストのタイプを指定するためのオプションです。

永続的に付与する場合は、semanage コマンドで定義ファイルを書き換えた後、restorecon コマンドで定義ファイルの適用を行います。

# semanage fcontext -a -t httpd_sys_content_t /temporary
# restorecon -RF /temporary

restorecon コマンドを使うと、chcon で適用した内容は破棄されます。

コメント

タイトルとURLをコピーしました