タイトル長い上にそんな限られた状況の人居ないとは思いますが
まずは結論
synced_folder の owner オプション には、Web サーバ(Apacheとか)を起動するユーザ(例えば apache ユーザ)と同じにすべし。でないとセッションの保存に失敗します。
経緯
- PHP アプリケーションの開発環境を CentOS6 on Vagrant with Virtualbox で構築している
- PHP のバージョンは PHP 5.4.35 (パッケージリポジトリは remi を利用)
- アプリケーションのソースコードはホスト側に置いており、
synced_folder
でゲスト側にマウントしてそいつを Apache に認識させている
という感じに加えて
session.save_path を synced_folder でマウントしたディレクトリ以下を指定
している。何故そんなことをしているのかというは割愛させていただきます。
どうなるか確認してみよう
こんな Vagrantfile を用意してみました。
# -*- mode: ruby -*- VAGRANTFILE_API_VERSION = "2" $script = <<SCRIPT curl -O http://rpms.famillecollet.com/enterprise/remi-release-7.rpm sudo yum install -y epel-release sudo rpm -ivh remi-release-7.rpm sudo sudo yum install -y --enablerepo=remi php sudo cat <<"PHP" > /var/www/html/foo.php <?php session_save_path('/session'); session_start(); if (!isset($_SESSION['count'])) { $_SESSION['count'] = 0; } else { $_SESSION['count']++; } var_dump($_SESSION['count']); PHP sudo systemctl start httpd sudo systemctl enable httpd SCRIPT Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "chef/centos-7.0" config.vm.network :forwarded_port, guest: 80, host: 8080 config.vm.provision "shell", inline: $script config.vm.synced_folder './', '/session', mount_options: ['fmode=777', 'dmode=777'] end
こいつをてきとーな場所に配置して
$ vagrant up
すれば一通り検証環境ができあがります。終わったら http://localhost:8080/foo.php にアクセスしてみてください。
こういう画面になると思います。
Vagrantfile
にも書いた通り、リロードすれば数値がインクリメントされていくはずなんですが、
現時点ではおそらく int(0)
のままだと思います。
ここで、ゲストOSにログインしてエラーログを確認してみます。
$ vagrant ssh [vagrant@localhost ~]$ sudo tail -n 3 /var/log/httpd/error_log [Wed Dec 17 11:32:51.388156 2014] [:error] [pid 2282] [client 10.0.2.2:58918] PHP Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/session) in Unknown on line 0 [Wed Dec 17 11:32:51.540342 2014] [:error] [pid 2282] [client 10.0.2.2:58918] PHP Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/session) in Unknown on line 0 [Wed Dec 17 11:32:51.702463 2014] [:error] [pid 2282] [client 10.0.2.2:58918] PHP Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/session) in Unknown on line 0
session.save_path
が何かおかしい? /session
の中身を見てみます。
[vagrant@localhost ~]$ ls -la /session/ 合計 8 drwxrwxrwx. 1 vagrant vagrant 170 12月 17 11:32 . drwxr-xr-x. 19 root root 4096 12月 17 11:31 .. drwxrwxrwx. 1 vagrant vagrant 102 12月 17 10:44 .vagrant -rwxrwxrwx. 1 vagrant vagrant 860 12月 17 11:30 Vagrantfile -rwxrwxrwx. 1 vagrant vagrant 0 12月 17 11:32 sess_mjrp1g7fk861nq2gpbivh35ju1
セッションファイルらしくものはできている。この時の Cookie の値を見てみると
となっているため、おそらくこのファイルで間違いないと思われます。
/session
およびその中に作られるファイルは、synced_folder
のマウントオプションによりファイルもディレクトリもパーミッション 777 になっています。なのにファイルサイズは0。つまり
session_start()
- セッションファイルを
/session
以下に作る。/session
は 777 なので apache ユーザでも作れる
/session/sess_xxxx
が作成されるが、この瞬間にsynced_folder
の効果によりファイル owner がvagrant
に変化する/session/sess_xxxx
の owner が apache ではなくなったため、書き込みに失敗
ちなみに PHP 5.3 までは上記 Vagrantfile の状態でもしっかりカウントアップされます。PHP 5.4 にすると駄目。
原因
PHP 5.4、正確には 5.4.28 から セッションファイルの owner は root もしくは Webサーバのユーザに限る という制限が付きました。
- https://github.com/php/php-src/blob/PHP-5.4.28/ext/session/mod_files.c#L190-L192
- Fix bug #66171: better handling of symlinks · 40a9316 · php/php-src
- PHP :: Sec Bug #66171 :: ps_files_open: Block symlinks properly, prevent opening other users' sessions
上記リンクを見ていただければわかるとおり、ユーザセッションファイルをしっかりチェックしていこうという流れの中で、 セッションファイルの owner に関しても制限を付けました、というものです。
この影響で、/session
内に空ファイル事態は作れたけど、その後の内容に関しては上のチェックにひっかかって失敗した、ということでした。
解決策
今回使った環境では Web サーバのユーザは apache
なので、Vagrantfile を下記のように変更してみます。
@@ -34,5 +34,6 @@ config.vm.provision "shell", inline: $script config.vm.synced_folder './', '/session', + owner: 'apache', mount_options: ['fmode=777', 'dmode=777'] end
変更後 vagrant reload
して再度 http://localhost:8080/foo.php にアクセスしてみましょう。リロードするだけカウントアップできるようになっていると思います。
/session
の状態を見てみましょう。
[vagrant@localhost ~]$ ls -la /session 合計 12 drwxrwxrwx. 1 apache vagrant 170 12月 17 11:46 . drwxr-xr-x. 19 root root 4096 12月 17 11:46 .. drwxrwxrwx. 1 apache vagrant 102 12月 17 10:44 .vagrant -rwxrwxrwx. 1 apache vagrant 903 12月 17 11:45 Vagrantfile -rwxrwxrwx. 1 apache vagrant 10 12月 17 11:46 sess_mjrp1g7fk861nq2gpbivh35ju1
書き込めてます!
まとめ
session.save_path
は弄らずに平和に普段通り過ごそう