Hogyan takarítsuk automatikusan a webfiókok tmp könyvtáraiban maradt PHP munkamenet fájlokat az ISPConfig-os szerverkörnyezetben

botond küldte be 2021. 03. 04., cs – 11:26 időpontban

Tartalom

 

Bevezető

A PHP munkamenetek (session-ok) olyan globális változók, amik a webes látogatások során tárolt adatokat több oldalon keresztül is továbbítják, azaz nem vésznek el egyik oldalról átlépve a másikra. Ennek segítségével megvalósítható például, hogy ha valaki belép a felhasználónevével és jelszavával egy weboldalon, akkor ez az állapot mindaddig megmarad a böngészése során, amíg ki nem lép, vagy be nem zárja a böngészőt (a sütikkel – cookies – ellentétben a munkamenetek alapesetben véget érnek a böngésző bezárásakor). A PHP ezt úgy valósítja meg, hogy a látogatásokhoz (munkamenetekhez) egyedi azonosítókat rendel, és a szerver oldali fájlstruktúrában ezekhez az azonosítókhoz kapcsolódó fájlokat hoz létre amikben tárolja a munkamenet számára szükséges adatokat. A rendszer ezeket a fájlokat egy meghatározott – általában tmp – könyvtárában helyezi el, amit normál esetben egy megadott idő elteltével töröl – a garbage collector által.

A helyzet azonban néha nem ilyen kézenfekvő. Ugyanis, ha megváltozik a szerveren lévő PHP környezet, akkor előfordulhat, hogy a takarító rendszer (garbage collector) nem tudja letörölni ezeket az elévült, szükségtelenné vált munkamenet fájlokat. Ilyen esetekben külön kell gondoskodnunk arról, hogy ezek a fájlok rendszeresen törlésre kerüljenek, különben idővel felgyűlhet belőlük nagyon sok, ami tárhelyet is foglal, és ronthatja a rendszer teljesítményét is. Ilyen helyzet általában akkor állhat elő, amikor egy PHP környezet számára egyedi munkamenet könyvtár kerül beállításra, így az alapértelmezett takarító script nem találja ezt a könyvtárat. Pontosan ez a helyzet az ISPConfig-os szerverkonfigurációval is, ahol a kliens fájlstruktúra miatt minden webfiók más munkamenet könyvtárat használ.

Ez a jelenség természetesen más szerverösszeállítás esetén is előfordulhat, ahol egyedi PHP beállításokat használunk, de itt most csak az ISPConfig-os szervereken kivitelezendő megoldásokat tekintjük át. Ebben a leírásban tehát megnézzük, hogyan orvosolhatjuk ezt a helyzetet, hogy a munkamenet fájlok minden esetben törlésre kerüljenek a megfelelő idő eltelte után.

 

 

A probléma felderítése

Nem minden weboldal használ munkameneteket, így lehet, hogy nem érint bennünket ez a probléma, de az is lehet, hogy nincs is tudomásunk erről az egészről, miközben már sok ezer, vagy sok tízezer darab munkamenet fájlunk is összegyűlhetett az ISPConfigos szerverünk valamelyik tmp könyvtárában. Ezért első körben járjunk utána, hogy a saját tárhelyeinken fennáll-e ez a probléma.

A webfiókok tmp könyvtárainak átvizsgálása

Az ISPConfig az alábbi kliens könyvtárstruktúrában tárolja a webfiókok tmp könyvtárait:

/var/www/clientX/webY/tmp/

Ahol az X jelöli a kliens azonosítóját, és az Y pedig a webfiók azonosítót. Ha nem hoztunk létre egyetlen ügyfelet sem a kezelőpanelben, akkor a "client0" lesz az egyetlen kliens könyvtár.

A PHP munkamenet fájlok pedig az ezekben a könyvtárakban lévő "sess_" kezdetű fájlok, amik egy alfanumerikus kóddal végződnek, például:

sess_s04fbu9mn8i8pljh30fr5l0he0

Kézi ellenőrzés

A fentieknek megfelelően nézzünk körül a webfiókjaink tmp könyvtáraiban. Például mondjuk az 1. kliens alatti 1. webfiókban (feltételezve hogy van ilyen):

ls -al /var/www/client1/web1/tmp

És láthatjuk, hogy mi a helyzet. Ha itt nem találunk ilyen fájlokat, akkor nincs teendőnk, lépjünk a következő webfiók tmp könyvtárába, és nézzünk körül ott is.

Ha nem tudjuk, hogy milyen kliens könyvtáraink vannak, akkor a tree parancs segítségével egy fa struktúrában megjeleníthetjük az összes webfiók könyvtárát:

tree -d -L 2 /var/www/clients/

Nálam az éppen kéznél lévő virtuális szerveren a kimenet:

Kliens könyvtárstruktúra felderítése az ISPConfigos szerverkörnyezeben a tree paranccsal

Ezen a szerveren éppen csak egy kliens nélküli webfiók van, de jól látszik, hogy hogyan listázza ki a struktúrát. Ennek megfelelően végigjárhatjuk az összes tárhelyet, és megnézhetjük a tmp könyvtárakat.

Ha valamelyik tmp könyvtárban olyat tapasztalunk, hogy nagy mennyiségben vannak jelen ezek a fájlok, akkor időrendben is megnézhetjük őket:

ls -alt /var/www/client1/web1/tmp

Itt a -t kapcsoló segítségével a legaljára kerülnek a legrégebbi fájlok, így láthatjuk, hogy mióta gyűlnek a munkamenet fájlunk. Ha meg akarjuk őket számolni, akkor egészítsük ki egy wc paranccsal:

ls -alt /var/www/client1/web1/tmp | wc -l
Ezeknek a fájloknak az élettartamát normál esetben a php.ini fájl "session.gc_maxlifetime" beállítása szabályozza, amely másodpercekben van megadva. Ez a változó alapértelmezetten 1440-re van állítva "gyárilag". 1440 másodperc az 24 perc, tehát maximum 24 perc elteltével kell törlődniük ezeknek a fájloknak, amennyiben nincs elállítva más értékre ez a paraméter. Ha ennél az értéknél régebbi fájl(oka)t látunk, akkor nem működik a takarító rendszer (garbage collector). Ebben az esetben – a weboldal forgalmától függően – nagy mennyiségű munkamenet fájl szaporodhat fel, ami hosszú távon nem csak sok helyet foglal, de lassítja a PHP munkamenetek kezelését is – ezáltal rontva a PHP összteljesítményét.

 

 

Automatizált ellenőrzés

Ha sok kliens és/vagy webfiók van a szerverünkön, akkor egyesével elég macerás ellenőrizgetni őket. Erre a célra érdemes inkább összedobni egy kis shell scriptet, ami végigjárja helyettünk ezeket a tmp könyvtárakat, és megszámolja a bennük lévő "sess_" kezdetű fájlokat:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#! /bin/bash
# ISPConfig fiókok tmp könyvtárainak vizsgálata
CLIENT_DIRS="/var/www/clients"                                                          # Kiindulási könyvtár: a kliens fájlstruktúra főkönyvtára
 
# Fő ciklus: kliens könyvtárak
find $CLIENT_DIRS -maxdepth 1 -type d -name "client[0-9]*" |                            # A find megkeresi a clientX könyvtárakat, majd csővezetéken át
    while read client_dir; do                                                           # ciklust készít a kapott eredményhalmazból
        echo "Kliens: $(basename $client_dir)"                                          # kiiratás
        WEB_DIRS=$client_dir                                                            # A web könyvtárakat beállítjuk az aktuális kliens könyvtárra.
                                                                                        # csak az áttekinthetőség miatt raktam ide
        # Belső ciklus: web könyvtárak
        find $WEB_DIRS -maxdepth 1 -type d -name "web[0-9]*" |                          # A find megkeresi a webY könyvtárakat, majd csővezetéken át
            while read web_dir; do                                                      # ciklust készít a kapott eredményhalmazból
                echo "Web: $(basename $web_dir)"                                        # kiiratás
                tmp_dir=$(realpath $web_dir/tmp)                                        # A tmp könyvtárat a teljes útvonallal állítjuk össze, 
                                                                                        # ezt a realpath paranccsal nyerjük ki a relatív útvonalból, amit a find-től kaptunk.
                echo "tmp könyvtár: $tmp_dir"                                         # kiiratás
                session_files=$(find $tmp_dir -type f -name 'sess_*' | wc -l)           # munkamenet fájlok megkeresése, majd a kapott lista elemek megszámolása
                echo "PHP munkamenet fájlok száma: "$session_files                        # darabszám kiiratás
                echo                                                                    # üres sor a webkönyvtárak között
            done
        echo                                                                            # plusz üres sor a kliensek között, hogy áttekinthetőbb legyen a kimenet, ha több kliens van.
    done

Mentsük le egy fájlba, adjunk neki futtatási jogot. Például:

chmod +x scan_tmp

Majd futtassuk. Nálam a kimenete ennek a programnak a szerveren például:

PHP munkamenet fájlok automatizált ellenőrzése a tmp könyvtárakban

Ez a program tehát nem csinál mást, mint hogy a find parancs segítségével és két ciklussal végigjárja a kliens könyvtárstruktúrát, és kiírja a talált PHP munkamenet fájlok darabszámait.

Nálam például 3 olyan weboldal van, ami PHP munkamenetet (session) használ, és jelenleg ezeknél is normális keretek között vannak jelen a munkamenet fájlok – amiknek a mennyisége természetesen a napszaktól, forgalomtól függően változik. Régen ezeknél is gyűltek rendesen a munkamenet fájlok, amíg nem készítettem el a saját takarító programomat hozzá.

Ha lefuttatjuk ezt a programot, és 0-ás értékeket találunk, vagy csak alacsony számokat látunk, mint itt is, akkor nincs további teendőnk. Vannak weboldalak, amik saját maguk gondoskodnak a munkamenet fájlok takarításáról, ezért ilyen esetekben nincs szükség külső beavatkozásra. Azonban ha valamelyik webfiókunkban irreálisan nagy mennyiségű PHP munkamenet fájlt találunk, akkor folytassuk először a probléma okának feltárásával.

 

A probléma okának feltárása

Ahhoz, hogy orvosolni tudjuk a problémát, először meg kell ismernünk annak okát is.

Cron rendszer vizsgalata

A cron rendszer az UNIX-szerű operációs rendszerekben biztosítja az időzített feladatok végrehajtását, ezért itt kell körülnéznünk, mivel a munkamenet fájlok takarítása is időzített feladat. Ehhez lépjünk be a /etc/cron.d könyvtárba, majd listázzuk ki:

cd /etc/cron.d
ls -al

Itt láthatunk több fájlt is, amik például az ISPConfig-os szerverkörnyezet kellékei, és köztük láthatunk egy php nevű fájlt is, ebbe nézzünk bele:

cat php

A php cron fájljának megtekintése

Itt láthatunk egy cron bejegyzést, aminek az elején kommentben le van írva az alábbi:

#  This purges session files in session.save_path older than X,
#  where X is defined in seconds as the largest value of
#  session.gc_maxlifetime from all your SAPI php.ini files
#  or 24 minutes if not defined.  The script triggers only
#  when session.save_handler=files.
#
#  WARNING: The scripts tries hard to honour all relevant
#  session PHP options, but if you do something unusual
#  you have to disable this script and take care of your
#  sessions yourself.

# Look for and purge old sessions every 30 minutes
08,38 *     * * *     root   [ -x /usr/lib/php/sessionclean ] && if [ ! -d /run/systemd/system ]; then /usr/lib/php/sessionclean; fi

Ennek a lényege, hogy ez a cron feladat törli azokat a munkamenet fájlokat, amik a php.ini fájlban a "session.save_path" beállításában meghatározott könyvtárban vannak, valamint a "session.gc_maxlifetime" beállításban meghatározott másodpercnél régebbiek, ami alapértelmezetten 24 perc időküszöb értékre van beállítva.

Valamint figyelmeztet, hogy ez a futtatásra kerülő script a php.ini ide vonatkozó beállításait követi, így ha valami egyedi módosítást eszközölünk a rendszerben, akkor le kell tiltani ezt a scriptet, és magunknak kell megoldanunk a munkamenetek takarítását.

A cron feladat sora pedig előzetes vizsgálatok után (létezik-e és futtatható-e a fájl, nem fut-e a systemd szolgáltatás) root-ként lefuttatja minden órában 09 és 39 perckor a /usr/lib/php/sessionclean fájlt, ami a PHP alapértelmezett munkameneteket pucoló programja.

 

 

Valamint a cron-on kívül még a systemd-ben is van egy phpsessionclean nevű szolgáltatás, ami szintén ugyanezekben az időpontokban lefuttatja ugyanezt a programot. Ezt ellenőrizhetjük is az alábbi paranccsal:

cat /var/log/syslog | grep "php session" | tail -30

Nálam például látszik, hogy lefut ez a szolgáltatás pontosan az előre definiált időpontokban:

A phpsessionclean Systemd szolgáltatás ellenőrzése

Tehát a fenti program két helyről is be van biztosítva hogy lefusson. Ha például nem megy a szolgáltatás, akkor a cron futtatja le a programot. Akkor mi lehet a gond?

Kizárásos alapon a programban lehet a probléma, ezért ezt kell a továbbiakban vizsgálnunk.

Az alapértelmezett php sessionclean program vizsgálata

/usr/lib/php/sessionclean program egy shell script, nézzünk bele:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/bin/sh -e
#
# sessionclean - a script to cleanup stale PHP sessions
#
# Copyright 2013-2015 Ondřej Surý <ondrej@sury.org>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
SAPIS="apache2:apache2 apache2filter:apache2 cgi:php@VERSION@ fpm:php-fpm@VERSION@ cli:php@VERSION@"
 
# Iterate through all web SAPIs
(
proc_names=""
for version in $(/usr/sbin/phpquery -V); do
    for sapi in ${SAPIS}; do
    conf_dir=${sapi%%:*}
    proc_name=${sapi##*:}
    if [ -e /etc/php/${version}/${conf_dir}/php.ini ]; then
        # Get all session variables once so we don't need to start PHP to get each config option
        session_config=$(PHP_INI_SCAN_DIR=/etc/php/${version}/${conf_dir}/conf.d/ php${version} -c /etc/php/${version}/${conf_dir}/php.ini -d "error_reporting='~E_ALL'" -r 'foreach(ini_get_all("session") as $k => $v) echo "$k=".$v["local_value"]."\n";')
        save_handler=$(echo "$session_config" | sed -ne 's/^session\.save_handler=\(.*\)$/\1/p')
        save_path=$(echo "$session_config" | sed -ne 's/^session\.save_path=\(.*;\)\?\(.*\)$/\2/p')
        gc_maxlifetime=$(($(echo "$session_config" | sed -ne 's/^session\.gc_maxlifetime=\(.*\)$/\1/p')/60))
        
        if [ "$save_handler" = "files" -a -d "$save_path" ]; then
        proc_names="$proc_names $(echo "$proc_name" | sed -e "s,@VERSION@,$version,")";
        printf "%s:%s\n" "$save_path" "$gc_maxlifetime"
        fi
    fi
    done
done
# first find all open session files and touch them (hope it's not massive amount of files)
for pid in $(pidof $proc_names); do
    find "/proc/$pid/fd" -ignore_readdir_race -lname "$save_path/sess_*" -exec touch -c {} \; 2>/dev/null
done ) | \
    sort -rn -t: -k2,2 | \
    sort -u -t: -k 1,1 | \
    while IFS=: read -r save_path gc_maxlifetime; do
    # find all files older then maxlifetime and delete them
    find -O3 "$save_path/" -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin "+$gc_maxlifetime" -delete
    done
 
exit 0

A program leegyszerűsítve annyit csinál, hogy lekérdezi a rendszerünkben rendelkezésre álló PHP verziókat, majd a fő ciklusban végigmegy ezeken a PHP verziókon, és egy belső ciklusban pedig a szerver API-kon (SAPI) megy végig, bejárva tehát az összes PHP verzió összes szerver API változatát (apache, CGI, FPM, CLI), és mindegyiknél kiolvassa a megfelelő php.ini fájlból a szükséges SESSION beállításokat, mint például a "save_path" és a "gc_maxlifetime" értékeit. Majd ezeknek megfelelően a save_path útvonalról törli a gc_maxlifetime másodperceknél régebbi "sess_" kezdetű fájlokat. Tehát pontosan azt teszi, amiről már fentebb is volt szó a cron feladat kommentjében.

Ez a takarító program például egy LAMP szerver esetén működik is megfelelően, ahol a php.ini alapértelmezett /var/lib/php/sessions útvonalát használja a rendszer a munkamenetek tárolására, azonban az ISPConfig kezelőpaneljában ha egy weboldalt a PHP-FPM szerver API-ra állítunk, akkor a weboldalt egy külön FPM pool-ba helyezi, amivel még mindig nem lenne gond, csak hogy a fentebb említett save_path értékét a weboldal pool-jának a konfigurációs fájljában állítja be – a webfiók tmp könyvtárára –, nem pedig a php.ini fájlban. A fenti takarító script pedig nem terjed ki a PHP-FPM pool-ok konfigurációs fájljainak vizsgálatára, hanem csak a "gyári" php.ini fájlokból olvassa ki a session.save_path és a gc_maxlifetime értékeket, amik alapján hajtja végre a törléseket. Így tehát ez a program nem törli a PHP-FPM SAPI által futtatott weboldalak PHP munkamenet fájljait az ISPConfig-os szerverkonfigurációban egyedileg beállított útvonalakról, ezért erről nekünk kell külön gondoskodnunk.

 

A megoldások

A fenti problémára kétféle variációt is bemutatok, ezek saját receptek, amik nálam már beváltak. Az alábbi példák csak ISPConfig-os szerverkörnyezetben működnek!

PHP munkamenet fájlok törlése weboldalanként

Az alábbi script egy adott weboldal cron-jában futtatva törli a webfiók tmp könyvtában felgyűlt PHP munkamenet fájlokat:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
# PHP munkamenet pucoló script
# A PHP csak a gyári beállítású munkamenet könyvtárból törli a munkameneteket.
# Így ha attól eltérő a beállítás, akkor nem pucolja őket.
# Ezáltal rengeteg fájl halmozódik fel a munkamenet könyvtárban
 
# Változók:
DOMAIN="domain.tld"                                                     # Domain nevet itt kell beállítani        
SESSION_MAXLIFETIME=3600                                                # Munkamenet élettartam másodpercekben (egyéni beállítás)
 
 
SESSION_PATH="/var/www/$DOMAIN/tmp"                                     # Webfiók tmp könyvtára az ISPConfig-os környezetben
MINUTE=$((SESSION_MAXLIFETIME / 60))                                    # kiszámítjuk a perceket a find parancs számára
 
find $SESSION_PATH -type f -name 'sess_*' -cmin "+$MINUTE" -delete      # elévült munkamenet fájlok törlése

Ha tehát egy adott weboldal esetében egyedileg szeretnénk törölni a munkamenet fájlokat, mert például más elévülési időt használunk, akkor ebben a scriptben állítsuk be a domaint, majd az elévülési időt másodpercekben, majd mentsük le valahol a webfiók dokumentum fájlstruktúrájában, és az ISPConfigban állítsuk be a webfiókhoz egy külön cron feladatként, mondjuk 10 percenkénti futással.

Én az ilyen külön script fájlokra a dokumentum gyökér alatti private/bin könyvtárat szoktam használni, így nem keverednek más dolgokkal a saját programjaim.

A cron beállításoknál pedig az alábbi módon állítsuk be a futtatandó parancsot:

/var/www/domain.tld/private/bin/scriptneve

Ahol a domain.tld a webfiók domain, és a scriptneve pedig amilyen néven lementettük a fenti scriptet.

Ezzel tehát egy adott weboldalhoz állíthatunk be PHP munkamenet törlést egyedi időkorlát beállítással.

 

 

PHP munkamenet fájlok törlése globálisan

A másik variáció, ha egyetlen helyről töröljük az összes webfiók elévült PHP munkamenet fájlját. Ennek előnye, hogy csak egy helyen kell létrehozni, és egyszer kell beállítani a cron-ban is. Hátránya, hogy az itt beállított időlimit lesz érvényes minden webfiók esetén, ami persze az esetek túlnyomó többségében lényegtelen, tehát ennek inkább csak előnye van az előző változathoz képest. A program tehát:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#! /bin/bash
# ISPConfig fiókok tmp könyvtárainak vizsgálata
SESSION_MAXLIFETIME=3600                                                                # Munkamenet élettartam másodpercekben (globális beállítás)
CLIENT_DIRS="/var/www/clients"                                                          # Kiindulási könyvtár: a kliens fájlstruktúra főkönyvtára
 
MINUTE=$((SESSION_MAXLIFETIME / 60))                                                    # kiszámítjuk a perceket a find parancs számára
 
 
echo "SESSION_MAXLIFETIME értéke: "$SESSION_MAXLIFETIME                                   # Kiiratás
 
 
# Fő ciklus: kliens könyvtárak
find $CLIENT_DIRS -maxdepth 1 -type d -name "client[0-9]*" |                            # A find megkeresi a clientX könyvtárakat, majd
    while read client_dir; do                                                           # ciklust készít a kapott eredményhalmazból
        echo "Kliens: $(basename $client_dir)"                                          # kiiratás
        WEB_DIRS=$client_dir                                                            # A web könyvtárakat beállítjuk az aktuális kliens könyvtárra.
                                                                                        # csak az áttekinthetőség miatt raktam ide
        # Belső ciklus: web könyvtárak
        find $WEB_DIRS -maxdepth 1 -type d -name "web[0-9]*" |                          # A find megkeresi a webY könyvtárakat, majd
            while read web_dir; do                                                      # ciklust készít a kapott eredményhalmazból
                echo "Web: $(basename $web_dir)"                                        # kiiratás
                tmp_dir=$(realpath $web_dir/tmp)                                        # A tmp könyvtárat a teljes útvonallal állítjuk össze, 
                                                                                        # ezt a realpath paranccsal nyerjük ki a relatív útvonalból, amit a find-től kaptunk.
                echo "tmp könyvtár: $tmp_dir"                                         # tmp könyvtár kiiratása
                
                session_files=$(find $tmp_dir -type f -name 'sess_*' | wc -l)           # munkamenet fájlok megkeresése, majd a kapott lista elemek megszámolása
                echo "PHP munkamenet fájlok száma a törlés előtt: "$session_files      # darabszám kiiratás a törlés előtt
                
                find $tmp_dir -type f -name 'sess_*' -cmin "+$MINUTE" -delete           # elévült munkamenet fájlok törlése                
                
                session_files=$(find $tmp_dir -type f -name 'sess_*' | wc -l)           # munkamenet fájlok megkeresése, majd a kapott lista elemek megszámolása
                echo "PHP munkamenet fájlok száma a törlés után: "$session_files       # darabszám kiiratás a törlés után
 
                echo                                                                    # üres sor a webkönyvtárak között
            done
        echo                                                                            # plusz üres sor a kliensek között, hogy áttekinthetőbb legyen a kimenet, ha több kliens van.
    done

Itt a leírás első részében bemutatott automatizált könyvtárellenőrzéses résznél használt dupla ciklusos könyvtárbejárást használjuk keretrendszernek, amibe beágyazzuk az előző változat törlő részét. Itt a domain nevek már nem játszanak, ezért az is kikerült belőle. Egyedül az időlimitet kell beállítani, amit én általában 3600 másodpercre szoktam állítani mindegyik weboldalnál. Továbbá ez a program nem vizsgál semmilyen php.ini fájlt, így ebben kell beállítanunk egyszer a megfelelő limitet.

Ez még a "debug" változat, amiben kiiratunk mindent. Nálam az eredmény:

PHP munkamenet törlő script kimenete

Mivel nálam alapból 10 percenként lefut ez a törlő program, így a 10 percenkénti futások között felgyűlt munkamenet fájlokat törli, ami jól látszik is a számokon.

Ha leteszteltük, és minden rendben működik, akkor akár ki is vehetjük belőle a kiiratásokat, illetve a számlálásokat, mivel a cron-ban történő futtatás során ezekre nem lesz többé szükségünk. Persze érdemes eltenni ezt a változatot is, ha bármikor látni szeretnénk az eredményeket.

A letisztított változat pedig:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#! /bin/bash
# ISPConfig fiókok tmp könyvtárainak vizsgálata
SESSION_MAXLIFETIME=3600                                                                # Munkamenet élettartam másodpercekben (egyéni beállítás)
CLIENT_DIRS="/var/www/clients"                                                          # Kiindulási könyvtár: a kliens fájlstruktúra főkönyvtára
 
MINUTE=$((SESSION_MAXLIFETIME / 60))                                                    # kiszámítjuk a perceket a find parancs számára
 
# Fő ciklus: kliens könyvtárak
find $CLIENT_DIRS -maxdepth 1 -type d -name "client[0-9]*" |                            # A find megkeresi a clientX könyvtárakat, majd
    while read client_dir; do                                                           # ciklust készít a kapott eredményhalmazból
        WEB_DIRS=$client_dir                                                            # A web könyvtárakat beállítjuk az aktuális kliens könyvtárra.
                                                                                        # csak az áttekinthetőség miatt raktam ide
        # Belső ciklus: web könyvtárak
        find $WEB_DIRS -maxdepth 1 -type d -name "web[0-9]*" |                          # A find megkeresi a webY könyvtárakat, majd
            while read web_dir; do                                                      # ciklust készít a kapott eredményhalmazból
                tmp_dir=$(realpath $web_dir/tmp)                                        # A tmp könyvtárat a teljes útvonallal állítjuk össze, 
                                                                                        # ezt a realpath paranccsal nyerjük ki a relatív útvonalból, amit a find-től kaptunk.
                find $tmp_dir -type f -name 'sess_*' -cmin "+$MINUTE" -delete           # elévült munkamenet fájlok törlése                
            done
        echo                                                                            # plusz üres sor a kliensek között, hogy áttekinthetőbb legyen a kimenet, ha több kliens van.
    done

Ez már mehet is a cron-ba, miután lementettük és adtunk rá futtatási jogot is.

Mivel ez nem kapcsolódik direktben egyik webtárhelyhez sem, valamint root jogosultság kell a futtatásához, így kézzel állítsuk be:

sudo nano /etc/cron.d/my_sessionclean

Majd tegyük bele az alábbi sort:

*/10    *    *    *    *    root    /scriptunk/eleresi/utja/my_sessionclean >/dev/null

Természetesen a saját útvonalunkat és script nevünket használjuk.

 

 

Konklúzió

Ezekkel a módszerekkel gondoskodhatunk róla, hogy a PHP munkamenet fájlok nem gyűlnek fel sosem az ISPConfig által létrehozott webfiókjaink tmp könyvtáraiban. Az eredeti sessionclean programot mindenképpen hagyjuk meg, mert az ISPConfig által kezelt weboldalakon kívüli egyéb Apache konfigurációkkal futtatott PHP alkalmazások, mint például a phpMyAdmin is, a php.ini fájlban meghatározott /var/lib/php/sessions könyvtárban helyezi el a PHP munkamenet fájljait, amit az eredeti takarító program tart rendben.