Unique everlasting session with low collision rate and is set across sub-domains The goal is to try and make an everlasting SESSION without too much or unnecessary scripting for updating of sessions. And at the same time to avoid session collision as session collisions could lead to 2 users trying to make use of the same session. That would not look pretty! And it does happen. Also for websites that use different language sub-domains, it would be useful if session did not change so that you can easily go from one sub-domain to another without requiring new sessions.

STEP 0:

function getUserIP(){
    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];

    if(filter_var($client, FILTER_VALIDATE_IP)){
        $ip = $client;
    }else
    if(filter_var($forward, FILTER_VALIDATE_IP)){
        $ip = $forward;
    }else{
        $ip = $remote;
    }
    return $ip;
}
$ip = getUserIP();


STEP 1:

ini_set('session.gc_probability', 0);// 0% probability of purging session log files, in this case on startup we preventing sessions from ever being deleted!
session_set_cookie_params(0, '/', '.website.com');// allow same session to be set across sub-domains!
session_name('session');// now make sure that the same session will not be regenerated across sub-domains and stay the same!
session_save_path($_SERVER['DOCUMENT_ROOT'].'/SESSION');//finally sessions are stored in a folder of choice in say public_html folder..
session_start();// we allow sessions to be read or changed..


STEP 2:

if(isset($_SESSION['ip'])){// if IP session in session log exist, do..
    if($ip!=$_SESSION['ip']){// if the current IP is not in the session log, then user privileges hasn't been confirmed!
        session_regenerate_id();// make sure that current visitor will be forced to use a different session_id! // new session copy is generated!
        session_destroy();// new session copy will be cleansed from previous data to be ready for use!
        header('Location: .');// reload the current page and to begin using a new session algorithm!
    }// SESSION collision has now been avoided and replaced with SESSION+IP collision where chances of that are pretty much ZERO!!!
    // IP is checked first, even if collision does occur, it will not allow to use it because of the missing IP..
    // that means someone must be in a public place that uses same IP for all PC's and within that amount of PCs a collision can occur!
}else{// if session doesn't exist, start new log!
    $_SESSION['ip']=$ip;// visitor session log file has been updated!
    echo 'NEW SESSION!&lt;br&gt;';
}


Is this a good solution? Is it a great solution? Is it the best solution? What do you guys think? :)
Note, that I didn't include the cleaning up process in this scenario, so you should use your imagination! But with this script you shouldn't even be needing a script to clean up sessions. All you'll need is to go to FileZilla, enter SESSION folder, select 1 file, press ctrl+a to select all session log files and then delete them all once a month or even once a year or so!? Also the storage directory for SESSIONS is just an example that you can put them in some nearby location closer to your development folder. But public_html is kinda PUBLIC and therefore you should use it along with .htaccess file and restrict access to the SESSIONS folder to secure it.
Since nobody else has chimed in here, I figured I would elaborate on my comments above.  If your stated goal is to:


have sessions that last indefinitely
have sessions that are more secure than default settings
have sessions that have have less chance of collision than default settings


Then this is the wrong approach.  You are actually not meeting any of these goals, and in fact are making security and chance of collision worse.

First,  these sessions will not be indefinite.  You are setting session cookie lifetime with value of 0 which means that, if the browser is compliant with this setting, the cookie will only last as long as the browser is open.  If that user closes their browser and then opens it back up 10 minutes later, they will get a new session.  There is no setting that will make a session last forever, as sessions are not really designed to last forever.  If you need data to persist between what truly are "sessions" then you need to look for another solution.  I am not suggesting you change this setting at all, as for most use cases when using sessions as intended, a value of 0 for cookie lifetime is a reasonable setting.



So, now that we have established that you are not truly getting "everlasting" sessions, let's get into the security aspects.

Here are a few PHP documentation links I will refer to:


Securing session INI
PHP Session Management Basics




We will start with garbage collection. Since you are not getting long-lasting sessions, that fact that you want to collect session data files (or database records if one were to use a database to store the data) indefinitely, means that you are, in essence, accumulating attack vectors against your application.  Ideally you should use an appropriate session lifetime and an aggressive approach to invalidating and pruning old records to minimize security risk.  One comment from the session.gc_maxlifetime section of the securing INI link above seems very pertinent here:


  If auto login feature is required, implement your own secure auto
  login feature. Never use long life session ID for it.


Long sessions should not be purposed for long-term data persistence or used for  authentication/authorization as it seems you are trying to do.



As I mentioned earlier accumulating these session files is like accumulating attack vectors, as you increase the opportunity for someone to execute a session hijacking or session fixation attack against your application.  This coupled with the fact that you open the application to using session cookies over non-secure (HTTP) connection, means it would be trivial for a packet sniffer or man in the middle to grab a session ID from a legitimate user's request and use it FOREVER.

And while destroying/regenerating session id's across IP change boundaries is a reasonable security measure, it is by no means enough.  That attacker could be sitting in a Starbucks along with the legitimate user using a wifi network which has the same exact IP address.  A sophisticated attacker can also easily spoof their IP address.

Also, keep in mind that there are some legitimate use cases where a user might change IP address during a session (a user on a mobile device for example), so while, IP address can be used as one of the triggers for session invalidation, if you use some of the other takeaways about handling session securely, you might decide that it's importance as a criteria for session invalidation might not be worth a potentially bad user experiences if you had a high number of mobile users.



Accumulating these session files also does increase your risk of a session collision.  Now that may be a pretty minute risk on a website with low traffic level anyway, but you are certainly making the probability of it happening worse, not better, with your approach.  And the IP check has nothing to do with mitigating against session id collision as mentioned in your comments.  That IP value is stored inside the session data and in no way helps mitigate a collision on the session id itself.



Let's talk about the session file save path.  I know there was some back and forth on this in the comments, with me suggesting that putting these files in a web directory is a bad security practice.  You are right that one could limit access to this directory in other ways, but why would you want to introduce a security vulnerability that you need an additional security measure to mitigate?  You are making your application security more complex and more fragile to someone not setting things up properly than it has to be.

Additionally, it just makes no practical sense to be putting this data into your application web directory anyway, just from a straight separation of concerns/access standpoint.  One doesn't typically configure database files, application logging, or other similar functionality that might read-write system files to do so into the application space, so why would you do this with session data?

Ideally, you write session data into a directory only available to the root user or user under which your application is running under to access and you don't let administrators working with the production system have root/sudo access in production unless absolutely necessary.



You should be using session.use_strict_mode if not specified as such in your ini file (this is not shown here obviously,so I am not sure what your current approach is).  This will help mitigate against session fixation, but will not help if an attacker uses one of the sessions id's you are collecting as cruft.



If you are using PHP 7.1, consider using session_create_id() to establish better connection between indvidual user and their session id.  This allows allows better usage of prefix index for database lookups if ever using a relational database as session storage medium.



Even for a case of using long sessions (or true browser-controlled session lengths as you are doing), you should regenerate session id at regular intervals to mitigate against session fixation/hijacking.  This means you have to start managing a timestamp in the session data.  There really is no way around this in PHP sessions.  I know one of your stated goals was to not have to get into this, but there really is no alternative if you want your sessions to be secure.  Please read the "Session ID Regeneration" section of the second link given above.

There is a pertinent quote there:


  Developer must NOT rely on session ID expiration by
  session.gc_maxlifetime. Attackers may access victim's session ID
  periodically to prevent expiration and keep exploiting victim's
  session ID including authenticated sessions.
  
  Instead, you must implement time-stamp based session data management by yourself.


So a bad system would rely on garbage collection alone to provide mitigation against session fixation.  A really bad system would not use garbage collection at all.

Again... you have to use timestamps if you want secure sessions.



Additionally, session_regenerate_id() combined with session_destroy() in PHP doesn't magically work by itself.  See the warning note in the session_regenerate_id() documentation:


  You should not destroy old session data immediately, but should use
  destroy time-stamp and control access to old session ID. Otherwise,
  concurrent access to page may result in inconsistent state, or you may
  have lost session, or it may cause client(browser) side race condition
  and may create many session ID needlessly. Immediate session data
  deletion disables session hijack attack detection and prevention also.


Again... you have to use timestamps if you want secure sessions.



Continuing in the area of session data management. Let's talk data deletion.  Please heed this text from the "Session Data Deletion" section of the second link above:


  Obsolete session data is better to be removed as soon as possible.
  However, active sessions MUST NOT be removed immediately. To satisfy
  these requirements, you MUST implement time-stamp based session data
  management by yourself.
  
  Set and manage expiration time-stamp in $_SESSION. Prohibit access to
  obsolete session data. When obsolete session data access is detected,
  it is advised to remove all authenticated status from the user's
  sessions and force them to re-authenticated. Obsolete session data
  access could be an attack. To do this, you must keep track active
  sessions per user.
  
  In short, do not destroy session data by session_regenerate_id() nor
  session_destroy(), but use time-stamp to control access to session
  data. Let session_gc() to remove obsolete data from session data
  storage.


Again... you have to use timestamps if you want secure sessions.




session_name('session');// now make sure that the same session will not be regenerated across sub-domains and stay the same!



This doesn't really do what the comment says it does.  This function simply determines that name of the session cookie to be used.  This doesn't guarantee any cross-domain interactivity of the cookie unless this same name is used for the cookie in all those sub-domains.  I think naming your sessions is totally fine, but this is really not necessary to achieve this effect. For example, if every subdomain was a PHP app with the same INI setting for this, this line would be unneccessary.  Similarly, if you had other subdomains that were not PHP apps, this code here does nothing to help you, as you would need to use whatever means the language in use on that subdomain uses to set this cookie name.



If all of this seems overly complex to manage in a secure manner, that is understandable.  As I said in my comments to the post above, PHP does not make secure session management easy in an out of the box manner. It requires work on the part of the developer.

You might consider using a good session management library if you want to simply drop some functionality into your application and not worry so more about the minutiae of managing the sessions.