phpMyAdminでセッションタイムアウトの時間を伸ばしても反映されない

よく phpMyAdmin でログインセッションの有効期限を伸ばす方法として、config.inc.php に以下の設定を追記する方法が紹介されてます。

$cfg['LoginCookieValidity'] = (60 * 60 * 4); // 4 hours
ini_set("session.gc_maxlifetime", $cfg['LoginCookieValidity']);

この設定を Ubuntu 上の phpMyAdmin に設定してみたのですが、どうも設定した時間より早くログインセッションが切れてしまうみたいで、なんでかなーと調べていたら原因が分かったのでメモしておきます。

原因

Debian 系の OS で php5 をインストールしたときに設定されている、古いセッションファイルを定期削除する cron が原因でした。

Ubuntu だと session_start() したタイミングで GC が実行される確率 (session.gc_probability) の値が 0 として設定されており無効になっています。その代わりとして設定されている cron です。

参考: ubuntuではphp.iniのsession.gc_probabilityを変えてはいけない

定期セッションファイル削除時の動作

/etc/cron.d/php5 にこのような設定がされていました。

09,39 * * * * root [ -x /usr/lib/php5/maxlifetime ] && [ -x /usr/lib/php5/sessionclean ] && [ -d /var/lib/php5 ] && /usr/lib/php5/sessionclean /var/lib/php5 $(/usr/lib/php5/maxlifetime)

毎時間の9分と39分に /var/lib/php5 に保存されている古いセッションファイルを探して削除するような設定です。

ざっくりな削除処理の流れとしては
1. /usr/lib/php5/maxlifetime のスクリプトで、各 /etc/php5/*/php.ini に設定されている session.gc_maxlifetime の時間で最も大きい時間を取得(このときの単位は分)
2. /usr/lib/php5/sessionclean のスクリプトで、 /var/lib/php5 以下にあるセッションファイルの内、1で取得した時間より古くなっているセッションファイルを削除
という感じでした。

なので、いくら ini_set 関数で session.gc_maxlifetime の時間を変更したところで、その時間は考慮されずに定期削除されてしまいます。

$cfg['LoginCookieValidity'] = (60 * 60 * 4); // 4 hours
ini_set("session.gc_maxlifetime", $cfg['LoginCookieValidity']); // ← 考慮されない

phpMyAdmin に限った問題ではないですね。

解決方法

対処法の例を2つ載せますが、どちらの場合でも phpMyAdmin の config.inc.php で LoginCookieValidity の時間の設定しておく必要があります。

解決法その1: session.save_path を変更する

cron が定期削除する対象は /var/lib/php5 ディレクトリ決め打ちなので、セッションファイルの保存先を変更してしまえばこの問題は起こりません。

phpMyAdmin/.htaccess:

php_value session.save_path /tmp/phpmyadmin

上記のような設定の場合、あらかじめ phpmyadmin ディレクトリは作成しておく必要があります。

mkdir /tmp/phpmyadmin
chmod 777 /tmp/phpmyadmin

解決法その2: php.ini の gc_maxlifetime の値を伸ばす

この方法の場合、他に稼働しているシステムに影響するかもしれないので注意が必要です。

/etc/php5/apache2/php.ini:

session.gc_maxlifetime = 14400

設定し終わったら以下のコマンドを実行して反映されているか確認してみるといいと思います。

 
/usr/lib/php5/maxlifetime

紛らわしいですが設定時の単位は秒で、確認時の単位は分で表示されます。