読者です 読者をやめる 読者になる 読者になる

y_uti のブログ

統計、機械学習、自然言語処理などに興味を持つエンジニアの技術ブログです

SELinux が有効な環境で phpenv を使う

phpenv はホームディレクトリの配下に PHP をインストールするため、SELinux が強制されている状態では、httpd が libphp5.so をロードできません。SELinux を有効にしたまま phpenv 管理下の PHP を利用するには、次のような設定が必要でした*1。なお、私は anyenv を利用しているので、ディレクトリ構成もそれにしたがっていますが、phpenv を単独で利用している場合でも必要な設定は同じだと思います。

httpdPHP モジュールを読み込む処理の流れは、次のとおりです。それぞれの手順で、SELinux のポリシーに違反しないように設定します。

  1. LoadModule の指定により libphp5.so がロードされる
  2. 設定ファイル (php.ini および conf.d/*.ini) が読み込まれる
  3. 設定ファイルの指定により PHP の拡張モジュールがロードされる

libphp5.so のロードを許可する

php-build に前回の記事で紹介したパッチを適用済みであれば、以下の場所に libphp5.so が作成されます。これは PHP 5.5.17 の場合の例です。

~/.anyenv/envs/phpenv/versions/5.5.17/libexec/libphp5.so

また、phpenv global でバージョンを切り替えた際には、以下の場所に、上記のファイルを指すシンボリックリンクが作成されます。このシンボリックリンクを LoadModule で指定することで、httpd を reload するだけで PHP のバージョンの切り替えに対応できる仕組みになっています。

~/.anyenv/envs/phpenv/lib/libphp5.so

この構成に沿って libphp5.so をロードできるようにするため、まず、httpd がユーザのホームディレクトリにアクセスできるようにします。

$ sudo setsebool -P httpd_enable_homedirs 1

次に、libphp5.so の実体に適切なセキュリティコンテキストを付与します*2

$ chcon -t httpd_modules_t ~/.anyenv/envs/phpenv/versions/5.5.17/libexec/libphp5.so

設定ファイルの読み込みを許可する

PHP の設定ファイルは、以下のディレクトリ階層に配置されます。

$ LANG=C tree ~/.anyenv/envs/phpenv/versions/5.5.17/etc
/home/y-uti/.anyenv/envs/phpenv/versions/5.5.17/etc
|-- conf.d
|   |-- pyrus.ini
|   |-- vld.ini
|   `-- xdebug.ini
`-- php.ini

1 directory, 4 files

これらの ini ファイルを読めるようにするには、私が試した範囲では二通りの方法がありました。一つは、setsebool を用いるものです。

$ sudo setsebool -P httpd_read_user_content 1

もう一つは、ini ファイルのセキュリティコンテキストを変更する方法です。なお、それぞれの ini ファイルに個別にセキュリティコンテキストを設定しても問題なく動作します。

$ chcon -R -t etc_t ~/.anyenv/envs/phpenv/versions/5.5.17/etc

PHP 拡張モジュールのロードを許可する

PHP の拡張モジュールは、以下のディレクトリ階層に配置されます。

$ LANG=C tree ~/.anyenv/envs/phpenv/versions/5.5.17/lib/php/extensions
/home/y-uti/.anyenv/envs/phpenv/versions/5.5.17/lib/php/extensions
`-- no-debug-non-zts-20121212
    |-- opcache.so
    |-- vld.so
    `-- xdebug.so

1 directory, 3 files

これらをロードできるように、セキュリティコンテキストを変更します。こちらも、各ファイルに個別に設定しても問題ありません。

$ chcon -R -t lib_t ~/.anyenv/envs/phpenv/versions/5.5.17/lib/php/extensions

以上の手順で、SELinux を有効にしたままサービスを起動できるようになります。

*1:CentOS 7 で確認しています。SELinuxhttpd は公式リポジトリから yum でインストールしたものです。

*2:私は SELinux に詳しいわけではないので、各ファイルにどういったセキュリティコンテキストを与えるのが適切なのかは、よく知りません。単純に、/etc/httpd/modules/libphp5.so などデフォルトのファイルに付与されているものに合わせています。