Dengue: Session-Dateien automatisch löschen

Hallo,
ich habe ein Script bei Funpic laufen, welches mit einem Login arbeitet. Das Login-Script ist sessionbasiert und größtenteils von folgendem Script abgeschaut: http://aktuell.de.selfhtml.org/artikel/php/loginsystem/index.htm

Alle diejenigen, die das Login-System nutzen, haben nun dasselbe Problem: nach relativ kurzer, aber nicht definierter Zeit (teilweise 5-10 min) wird man ausgeloggt. Das Problem liegt NICHT an der Übermittlung der Session-ID sondern daran, dass Funpic sehr oft die Session-Dateien mit dem Garbage Collector löscht. Nun ist die Idee, die Session-Dateien per session.save_path() in ein Verzeichnis auf meinem FTP zu hinterlegen. Das Problem dabei ist, dass sie aber auch wieder gelöscht werden müssen. Zuerst dachte ich an einen Cronjob, was aber ungünstig ist, wenn ich das Script veröffentlichen will. Dann dachte ich mir, dass bei jedem Einloggen alle Session-Dateien überprüft werden, ob sie z.B. älter als eine Std sind und dann gelöscht werden.
Ich dachte mir aber dann, dass das nicht die Lösung sein kann, weil z.B. professionell programmierte Scripte wie Foren etc. mit diesem Session-Problem auch umgehen können. Nur leider blicke ich in den Quellcodes nicht durch.

Wisst Ihr, wie das Problem mit dem Löschen der Session-Dateien gelöst werden kann?

Danke

MfG
Dengue

  1. hi,

    Wisst Ihr, wie das Problem mit dem Löschen der Session-Dateien gelöst werden kann?

    Meine Sessions haben grundsätzlich einen Zeitstempel und ein maximales, von mir festgelegtes Alter. In den Anwendungen, die mit der Sessiontabelle arbeiten, starte ich mit Ajax einen Request an den "Saubermann" (CGI-Script). Der guckt in die Tabelle und löscht alles, was alt genug ist gelöscht zu werden.

    Mit Ajax wird praktisch der Löschprozess von der Anwendung asynchron abgekoppelt, für die Anwendung spielt es keine Rolle, wie lange der dauert. Lediglich der Webserver sorgt sich dafür, dass eine Response vor dem Timeout rausgeht, was jedoch zu machen ist.

    Viele Grüße,
    Horst Haselhuhn

    1. Erstmal danke für die sehr schnelle Antwort. Nur leider habe ich nicht die Möglichkeit auf dem Server CGI auszuführen.

      MfG
      Dengue

  2. Hello,

    Wisst Ihr, wie das Problem mit dem Löschen der Session-Dateien gelöst werden kann?

    Du hast es schon gesagt, es kann z.B. mit einem Cronjob gelöst werden. PHP auf Debian macht das so. Dort läuft in der mit session.gc_maxlifetime eingestellten Zeit ein Cronjob. Das führt dazu, dass dieser Job regelmäßig läuft.

    Du brauchst Dir also nur einen solchen Job zu bauen und die Sessiondateien in einem anderen Verzeichnis abzulegen. Dazu musst Du dann aber auch den session.save_path entweder in der php.ini oder  in einer .htaccess (PHP als Apachmodul-Modul) oder einer lokalen php.ini (PHP als CGI) oder eben im Script _bevor_ Du session_start() aufrufst, umstellen.

    Dann werden die Sessiondateien in diesem Vereichnis angelegt und auch wieder gesucht.

    Für Deinen Cronjob musst Du darauf achten, dass dieser die letzte access-time der Datei abfragt und dass er das Locking beachtet. Es könnte sonst doch gelegentlich zu einem Fehler kommen. Im Prinzip sollte eine Sessiondatei, die sich gerade im Zugriff befindet, allerdings einen Zeitstempel tragen, der den Löschprozess von seiner Arbeit abhält. Es könnte aber eine TOCTOU-Situation erzeugt werden.

    Darfst Du bei Funpic eigenen Cronjobs anlegen?

    Benutzt Funpic PHP als Modul oser als CGI/Fast-CGI?

    Ein harzliches Glückauf

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. @Tom:

      Bei Funpic selber kann ich keinen eigenen Cronjob anlegen. Deshalb hätte ich mich bei einem kostenlosen Anbieter angemeldet und einen Verweis auf eine PHP-Datei gemacht, die auf dem Funpic-Account liegt. Diese Datei hätte dann überprüft, wann die Session-Dateien erstellt worden und werden dann evtl. gelöscht.

      Im großen und ganzen kann ich die Variablen der php.ini nicht umstellen, außer aber z.B. den session_save_path. Funktioniert einwandfrei. Den GC kann ich nicht beeinflussen. Wie auch schon geschrieben, kann ich kein CGI ausführen.

      Was verstehst du unter einer TOCTOU-Situation? Und inwieweit sind die Session-Dateien gelockt?

      MfG
      Dengue

      1. Hello,

        Im großen und ganzen kann ich die Variablen der php.ini nicht umstellen, außer aber z.B. den session_save_path. Funktioniert einwandfrei. Den GC kann ich nicht beeinflussen. Wie auch schon geschrieben, kann ich kein CGI ausführen.

        Dann poste mal bitte den Inhalt des Konfigurationswertes zu "Server API", gleich im ersten Abschnitt der PHP-Info-Ausgabe.
        Bei mir teht da "Apache 2.0 Handler" drin. Was steht bei Dir?

        Was verstehst du unter einer TOCTOU-Situation? Und inwieweit sind die Session-Dateien gelockt?

        TOCTOU: http://en.wikipedia.org/wiki/Time-of-check-to-time-of-use

        Der Prozess, der die datei löschen soll, muss sich vorher den exclusiven Zugriff darauf sichern, damit nicht ein anderer Prozess die Datei doch noch zum Arbeiten benutzen kann, während sie bereits gelöscht wird und umgekehrt, dass er nicht die Datei löscht, obwohl sie sich inzwischen durch einen anderen Prozess im Zugriff befindet.

        Ein harzliches Glückauf

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Den Abschnitt, in dem "Server API" steht, habe ich unter Funpic nicht!!! Auf meinem lokalen Apache-Server ist er vorhanden.

          Danke für den Link, ich lese mir das mal durch.

          MfG
          Dengue

          1. Hello,

            Den Abschnitt, in dem "Server API" steht, habe ich unter Funpic nicht!!! Auf meinem lokalen Apache-Server ist er vorhanden.

            Dann bemühe die Funktion http://www.php.net/manual/de/function.php-sapi-name.php, die hoffentlich vorhanden sit.

            Ein harzliches Glückauf

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Rückgabewert: apache2handler

              Also ist es der selbe Handler wie du schon geschrieben hast. Nur inwieweit kannst du damit etwas anfangen?

              MfG
              Dengue

              1. Hello,

                Also ist es der selbe Handler wie du schon geschrieben hast. Nur inwieweit kannst du damit etwas anfangen?

                Dann wird PHP bei Dir als Modul des Apachen ausgeführt und nicht als CGI-Script.
                Das ermöglicht ggf. wilde Zugriffe anderer User auf Dein Reich, wenn der Server nicht vernünftig eingerichtet ist.

                Dann kannst Du viele die PHP-Einstellungen vermutlich in einer .htaccess-Datei einstellen, sofern du die benutzen darfst und auch eine Freigabe für das Überschreiben eingerichtet wurde (AllowOverwrite) und der Admin in der Virtual-Host-Definition keine "php_admin_value" gesetzt hat.

                [libk:http://www.php.net/manual/de/configuration.changes.php]

                Dafür gibt es die

                Ein harzliches Glückauf

                Tom vom Berg

                --
                Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
                1. Hello,

                  Dann kannst Du viele die PHP-Einstellungen vermutlich in einer .htaccess-Datei einstellen, sofern du die benutzen darfst und auch eine Freigabe für das Überschreiben eingerichtet wurde (AllowOverwrite) und der Admin in der Virtual-Host-Definition keine "php_admin_value" gesetzt hat.

                  http://www.php.net/manual/de/configuration.changes.php

                  Ein harzliches Glückauf

                  Tom vom Berg

                  --
                  Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
                  1. Wie schon geschrieben, werde ich es jetzt erstmal weiter überprüfen, wann die session-Dateien genau verfallen.
                    Vielen Dank für deine Bemühungen. Hast dir einen Keks verdient ;-)

                    MfG
                    Dengue

                    1. Hello,

                      Vielen Dank für deine Bemühungen. Hast dir einen Keks verdient ;-)

                      Ich hätte gerne einen flüssigen Weizen-Keks, mit Hopfen vergoren und naturtrüb.

                      Ein harzliches Glückauf

                      Tom vom Berg

                      --
                      Nur selber lernen macht schlau
                      http://bergpost.annerschbarrich.de
              2. Wie ich gerade gesehen habe, verfallen die sessions auch, wenn sie in einem anderen Pfad liegen. Das wäre natürlich praktisch. Es scheint, dass wenn das Cookie bei mir verfällt, auch die session-datei auf dem Server verfällt.
                Das werde ich mal weiter testen.

                MfG
                Dengue

                1. Hello,

                  Wie ich gerade gesehen habe, verfallen die sessions auch, wenn sie in einem anderen Pfad liegen. Das wäre natürlich praktisch. Es scheint, dass wenn das Cookie bei mir verfällt, auch die session-datei auf dem Server verfällt.

                  Sie werden dort auch vom Garbage-Collector gesammelt. Den kannst Du aber ggf. nun einstellen, da dadurch ja keine anderen User mehr betroffen sind.

                  http://www.php.net/manual/en/ini.php#ini.list

                  Er bleibt aber trotzdem einheitlich zuständig für alle Deine Sessions in diesem bestimmten Verzeichnis. Wenn Du also auf dieser Schicht (und diese brutale Art und Weise) die MINDEST-Lebensdauer der Sessions für unterschiedliche Scripte unterschiedlich bemessen willst, dann musst Du nur unterschiedliche Verzeichnisse dafür einrichten und den GC jeweils anders steuern.

                  Es hat aber keinen wirklichen Sinn, für unterschiedliche Scripte, die ihre Sessions aber in einem gemeinsamen Verzeichnis ablegen, unterschiedlich einzustellen.

                  Ein harzliches Glückauf

                  Tom vom Berg

                  --
                  Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
                2. echo $begrüßung;

                  Es scheint, dass wenn das Cookie bei mir verfällt, auch die session-datei auf dem Server verfällt.

                  Die Session-Mindest- und die Keks-Lebenszeit lassen sich unterschiedlich konfigurieren. Kekse werden auf dem Client und Session-Dateien auf dem Server verwaltet. Für das Aufräumen ist jeder der beiden selbst zuständig. Wenn der Keks verfällt geht dem Client nur die Session-ID verloren. Wenn er sie trotzdem noch weiß und vielleicht per URL-Parameter übergibt, dann kann er auf eine noch nicht aufgeräumte Session-Datei stoßen und weiterarbeiten.

                  echo "$verabschiedung $name";

  3. echo $begrüßung;

    Der von Tom vorgeschlagene Weg ist eine Möglichkeit, doch möglicherweise ist der ganze Aufwand gar nicht nötig.

    [...] Funpic sehr oft die Session-Dateien mit dem Garbage Collector löscht.

    Schau bitte zuerst nach, wie die Einstellungen der session.*-Direktiven aussehen. Es kann sein, dass ein externer Mechanismus den Default-save_path reinigt, muss aber nicht.

    PHPs Session-Garbage-Collector läuft bei jedem Session-Start (z.B. Aufruf von session_start()) mit einer Wahrscheinlichkeit von gc_probability/gc_divisor los, Defaultwert ist dabei 1/100. Dabei werden die Session-Dateien gelöscht, die mindestens gc_maxlifetime auf dem Buckel haben. Es werden dabei diejenigen Werte berücksichtigt, die zum Zeitpunkt des Session-Starts konfiguriert sind. Da man sich die Werte im Script umkonfigurieren kann, hat man hier freie Hand. Der GC berücksichtigt dabei alle Dateien im save_path. Es gibt keine Information, zu welchem Projekt eine Session-Datei gehört. Wenn also jemand anderes den GC aufgrund aggresiver Konfiguration und hoher Zugriffszahlen auf sessionstartende Dateien oft laufen lässt, sind deine Daten auch mit fort.

    Nun ist die Idee, die Session-Dateien per session.save_path() in ein Verzeichnis auf meinem FTP zu hinterlegen.

    Ich glaube kaum, dss sich der save_path auf eine per FTP erreichbare Ressource umbiegen lässt. Wenn du hingegen ein ganz normales Verzeichnis meinst, das sich möglichst außerhalb deines DocumentRoot befindet, dann ist das eingeeignetes Ziel für den save_path

    Das Problem dabei ist, dass sie aber auch wieder gelöscht werden müssen.

    Darum kümmert sich PHPs eingebauter Session-GC sobald du eine Session startest.

    Wisst Ihr, wie das Problem mit dem Löschen der Session-Dateien gelöst werden kann?

    Es reicht, den save_path auf ein eigenes Verzeichnis zu stellen. Optional kann man noch die Aufrufwahrscheinlichkeit des GC anpassen, wenn man denkt, den Default-Wert nicht gebrauchen zu können.

    echo "$verabschiedung $name";

    1. Hello,

      Schau bitte zuerst nach, wie die Einstellungen der session.*-Direktiven aussehen. Es kann sein, dass ein externer Mechanismus den Default-save_path reinigt, muss aber nicht.

      Hatte ich aber schon erwähnt, dass dies der Fall sein kann.

      Der GC berücksichtigt dabei alle Dateien im save_path. Es gibt keine Information, zu welchem Projekt eine Session-Datei gehört. Wenn also jemand anderes den GC aufgrund aggresiver Konfiguration und hoher Zugriffszahlen auf sessionstartende Dateien oft laufen lässt, sind deine Daten auch mit fort.

      Aber nur dann, wenn sie im session.save_path des anderen Users liegen, also in einem für beide gemeinsamen Verzeichnis. Dies will aber Dengue gerade ändern.

      Ein harzliches Glückauf

      Tom vom Berg

      --
      Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. echo $begrüßung;

        Schau bitte zuerst nach, wie die Einstellungen der session.*-Direktiven aussehen. Es kann sein, dass ein externer Mechanismus den Default-save_path reinigt, muss aber nicht.

        Hatte ich aber schon erwähnt, dass dies der Fall sein kann.

        Ja, du erwähntest, dass das der Fall sein _kann_. Ich fügte hinzu, dass das nicht unbedingt sein _muss_ sondern andere Gründe haben kann.

        Der GC berücksichtigt dabei alle Dateien im save_path. Es gibt keine Information, zu welchem Projekt eine Session-Datei gehört. Wenn also jemand anderes den GC aufgrund aggresiver Konfiguration und hoher Zugriffszahlen auf sessionstartende Dateien oft laufen lässt, sind deine Daten auch mit fort.

        Aber nur dann, wenn sie im session.save_path des anderen Users liegen, also in einem für beide gemeinsamen Verzeichnis. Dies will aber Dengue gerade ändern.

        Ja, richtig. Dass seine Sessionsdaten verschwinden kann durch ebendiese geschilderten Nebenwirkungen der Konfiguration anderer Projekte zusammenhängen. Meine Ausführungen sollten zeigen, aus welchem Grund eine unerwünschte Bereinigung schon mit PHPs Bordmitteln stattfinden kann, auch ohne dass ein externer GC arbeitet. Und sie sollten auch dazu dienen, zu verstehen warum schon das alleinige Verlagern des save_path ausreichend sein kann.

        echo "$verabschiedung $name";