PHP, Apache, and the session that could not die

I am not really a web guy, coming from an operating systems and Java background. But for some reasons, I’ve been working on a Symfony3 project for the past year. I learned a lot and developed a deep love-hate relationship with both PHP and JavaScript. They have their strengths and weaknesses and I can respect that. But man, the way Apache and PHP are configured is just evil!

Today, I wanted to kill all user sessions, that have not been accessed for at least two hours. Now, there’s two ways to go about this.

Set session variables in php.ini and let PHP do the job

PHP brings it’s own session cleaning mechanism that involves these three settings in the php.ini:

session.gc_maxlifetime = 1440
session.gc_probability = 1
session.gc_divisor = 100

That translates to:

  • A session is dead after 1440 seconds (24 minutes) of inactivity
  • The chance that the garbage collection will be started is 1 in …
  • …100 session starts (user logins)

That’s neat, if that you have lots of user logins. I was working on an internal tool with only 50 registered users. The chance to kill the session of one inactive user if all other 49 users logged in right after the two hours mark where still less than 39%. (1-0.99^49) Not ideal. So, what’s the other option?

Release the Kraken Cronjob

Most Debian/Ubuntu systems come with a cronjob that kills stale sessions for you. It doesn’t care for your fancy session settings. Well, it only cares for one fancy session setting session.gc_maxlifetime is still the deadline for stale sessions.

Now, you could combine the two approaches, but since my symfony was already tripping over itself with complex permission problems, I decided to rely on just the cronjob. I set the session.gc_maxlifetime to 10 and the session.gc_probability to 0, logged into my system, waited for 10 seconds, manually started the cronjob-script and voila… I was still logged in.

No Mr Session, I expect you to die!

Why? Why did the session not expire? Why was it still there? Taunting me from within the session folder. What did I forget? I ran the crobjob-script again. Nothing. So I started to augment the script with some ‘printfs’ and read the output. It said: “24 minutes max session lifetime”. Wait. What? I looked at my active PHP version: 7.1. I looked into the ‘/etc/php/7.1/apache/php.ini’ AND the ‘/etc/php/7.1/cli/php.ini’. Both said: Max lifetime is 10 seconds. What went wrong?

What went wrong?

I still had my old PHP 7.0 ini-files. Although PHP 7.1 was active, the cronjob-script looked at ALL possible ini-files and searched for the HIGHEST max session lifetime. Once I also changed the inactive ini-files to 10 seconds, all stale sessions where gone.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.