PHP käivitamine kasutaja õigustes
Sisukord
Sissejuhatus
Harilikult kõik veebiskriptid ja cgi skriptid samuti toimivad veebiserveri kasutaja õigustes. Siiski on turva ja muudel kaalutlustel vajalik saada iga php ja perli skript töötama kasutaja õigustes kellele ta kuulub.
Lahendused oleksid
Suexec - suexec on mõeldud cgi skriptide käivitamiseks kasutaja õigustes ning sellega ei saa otse php jms apache moodulite skripte startida. Selleks tuleb suunata skriptid php-cgi peale mis stardib need cgi skriptide laadis. Miinuseks sellel tehnikal on suur aeglus võrreldes mooduliga.
MPM-ITK - apache worker millepuhul valimatult kõik saab kasutaja õigused mis defineeritud virtualhostis. Plussiks on tunduvalt suurem kiirus võrreldes suexeciga.
Suexec
Apache suexec on programm, mis lisati versioonis 1.2 ja mis annab apache kasutajatele võimaluse käivitada cgi ja ssi programme kasutaja id-ga, mis erineb veebiserveri id-st. Normaalselt toimivad kõik skriptid veebiserveri õigustes. Kahjuks võimaldab see nõnda startida ainult cgi skripte.
Trellidega (#) on näidetes tähistatud käsuviip.
Teooria
Apache oskab siduda mingit laiendit teatud cgi skripti käivitamisega näiteks saame globlaalselt käivitada php lisades httpd.conf'i
ScriptAlias /php-cgi/ /usr/local/www/data/cgi-bin AddType application/x-httpd-fastphp .php Action application/x-httpd-fastphp /php-fastcgi/php5-fcgi
Apache ei oska kohe suunata faile edasi kettal olevale binaryle või skriptile. Küll aga näiteks http://mingiaadress/cgi-bin all olvevale cgi skriptile või binaarfailile.
Täpsemalt
Kõik toimub sellises järjekorras
.php -> http://nimi.ee/php-cgi/php5-fcgi -> /usr/local/bin/php-cgi
Reaga ScriptAlias /php-fastcgi/ /usr/local/www/data/cgi-bin tekitame me enda veebiserverile aliase php-cgi url'iga http://nimi/php-cgi
Järgmise reaga AddType application/x-httpd-fastphp .php Tekitame uue application tüübi nimega x-httpd-fastphp mille seome .php laiendiga
Kolmas rida Action application/x-httpd-fastphp /php-cgi/php5-fcgi määrab ,et application x-httpd-fastphp. Seetähendab kõik .php failid suunatakse automaatselt skriptile nimega php5-fcgi ehk siis http://nimi.ee/php-cgi/php5-fcgi
skript php5-fcgi ise on sellise sisuga
#!/bin/sh exec /usr/local/bin/php-cgi
Nii saame näiteks hõlsasti teha kasvõi uue application tüübi näiteks laiendiga .jms ja siduda selle cgi skriptiga mis loeb talle saadetud .jms laiendiga failidest käske ja täidab neid luues nii kasvõi endale primitiivse veebiskriptimise keele.
Tarkvara installeerimine
Installeerime apache koos suexec-ga näiteks FreeBSD's
# cd /usr/ports/www/apache2 # make WITH_SUEXEC_MODULES="YES" install
Seejärel installeerime php
PHP installeerimisel küsitakse täiendavaid parameetreid. Valida tuleb CGI ja FastCGI tugi.
Apache moodulit pole vaja, kui seda ei plaanita täiendavalt paralleelselt kasutada.
Järgneb fastcgi installeerimine:
# cd /usr/ports/www/mod_fastcgi # make install clean
Php cgi wrapperi abil suexeci üle tööle
Tegemist on natuke keerukama ja aeglasema meetodiga aga vaatame seda ,et täpsemalt mõista teooriat.
kontrollime suexec'i parameetreid selliselt:
# suexec -V -D AP_DOC_ROOT="/usr/local/www/data" -D AP_GID_MIN=1000 -D AP_HTTPD_USER="www" -D AP_LOG_EXEC="/var/log/httpd-suexec.log" -D AP_SAFE_PATH="/usr/local/bin:/usr/local/bin:/usr/bin:/bin" -D AP_UID_MIN=1000 -D AP_USERDIR_SUFFIX="public_html"
Nagu näha, soovib suexec, et kõik skriptid, mida tema abil käivitatakse, asuksid kataloogis /usr/local/www/data Ei hakka DOC_ROOT muutma ja loome testi sinna.
Apache konfiguratsioon
Serveris on kaks veebi
Esimene peab toimima kasutaja katse õigustes ja teine katse3
Muudame httpd.conf, vajadusel lisame:
LoadModule suexec_module libexec/apache2/mod_suexec.so LoadModule fastcgi_module libexec/apache2/mod_fastcgi.so
Tekitame virtualhostid httpd.conf faili
<VirtualHost *:80> SuexecUserGroup katse katse ServerAdmin kasutaja@nimi.ee DocumentRoot /usr/local/www/data/katse ServerName www.nimi.ee ScriptAlias /php-fastcgi/ /usr/local/www/data/katse/cgi AddType application/x-httpd-fastphp .php Action application/x-httpd-fastphp /php-fastcgi/php5-fcgi </VirtualHost> <VirtualHost *:80> SuexecUserGroup katse3 katse3 ServerAdmin kasutaja@nimi.ee DocumentRoot /usr/local/www/data/katse3/cgi-bin ServerName test.nimi.ee ScriptAlias /php-fastcgi/ /usr/local/www/data/katse3/cgi AddType application/x-httpd-fastphp .php Action application/x-httpd-fastphp /php-fastcgi/php5-fcgi </VirtualHost>
Loome kaustad cgi skriptidele
mkdir /usr/local/www/data/katse/cgi-bin mkdir /usr/local/www/data/katse3/cgi-bin
wrapper
Skript ise millele suunatakse .php laiendiga failid
#!/bin/sh PHPRC="/usr/local/etc/php.ini" export PHPRC PHP_FCGI_CHILDREN=4 export PHP_FCGI_CHILDREN exec /usr/local/bin/php-cgi
Loome selle faili kasutajate katse ja katse 3 alla
/usr/local/www/data/katse/cgi/php5-fcgi /usr/local/www/data/katse3/cgi/php5-fcgi
Muudame mõlema faili kasutajaõigusi chown käsuga:
chown katse:katse /usr/local/www/data/katse/cgi-bin/php5-fcgi
chown katse3:katse3 /usr/local/www/data/katse3/cgi-bin/php5-fcgi
Wrapperita
ScriptAlias /php5-cgi /usr/local/bin/php-cgi AddType application/x-httpd-fastphp .php Action application/x-httpd-fastphp /php5-cgi
Kasutada saab ka korraga nii php4'ja kui php5't näiteks on meil installitud php5 ja php4 cgi versioonid
/usr/bin/php-cgi /usr/bin/php5-cgi
Testimine
Testimiseks saab teha skripti
< ?php print "hello world< p >\n"; system("id"); php? >
www.nimi.ee skripti vaadates
hello world uid=1004(katse) gid=1004(katse) groups=1004(katse)
test.nimi.ee
hello world uid=1009(katse3) gid=1009(katse3) groups=1009(katse3)
MPM-ITK
Selleks ,et saavutada suexecile sarnane olukord kus kõik skriptid töötavad kasutaja õigustes võib kasutada apache moodulit mpm-itk. lähemalt sellest http://mpm-itk.sesse.net/
Põhimõtteliselt on see modifitseeritud MPM-prefork, mis säilitab osad roodu õigused (CAP_SETUID ja CAP_SETGID) kõikidel oma protsessidel ja siis, kui vhost on kindlaks määratud, saab vajalikuks kasutajaks ja lahendab päringu selle kasutaja õigustes. Sealhulgas kõik tavapärased apache moodulid toimivad samuti selle kasutaja õigustes (st saame jätkata mod_php kasutamist).
Hea kokkuvõttev artikkel kõikidest suPHP, suexec, MPM-perchild/Metux ja MPM-itk omadustest ja puudustest: http://mitka.us/articles/mpm-itk/
MPM-itk miinuseks on asjaolu, et kuniks vhost pole kindlaks määratud, on protsess roodu osalistes õigustes, seega igasugune haavatavus sel hetkel on roodu haavatavus. Samas kuipalju apachel endal ikka vigu sees on, mis tekivad *enne* HTTP päringu parsimist ja võimaldaksid koodi käivitda (kuni 2004. aastani GLSA-de hulgast, ei leidnud). Lisaks veel see, et isegi, kui rünne õnnestuks, saavutataks vaid võime lugeda roodu faile, kuid mitte midagi muud (siin äkki apache + chroot abiks, kui isu).
Kiirusetestid
cgi+php+suexec
ab -c 1000 -n 10000 http://193.40.0.182/test.php Requests per second: 42.69 [#/sec] (mean) Time per request: 23426.00 [ms] (mean) Time per request: 23.43 [ms] (mean, across all concurrent requests)
ab -c 100 -n 1000 http://193.40.0.182/test.php Requests per second: 40.29 [#/sec] (mean) Time per request: 2482.10 [ms] (mean) Time per request: 24.82 [ms] (mean, across all concurrent requests)
ab -c 10 -n 100 http://193.40.0.182/test.php Requests per second: 45.56 [#/sec] (mean) Time per request: 219.50 [ms] (mean) Time per request: 21.95 [ms] (mean, across all concurrent requests)
mod_php puhtalt ilma erinevate mehanismideta
ab -c 1000 -n 10000 http://193.40.0.182/test.php Requests per second: 676.41 [#/sec] (mean) Time per request: 1478.40 [ms] (mean) Time per request: 1.48 [ms] (mean, across all concurrent requests)
ab -c 100 -n 1000 http://193.40.0.182/test.php Requests per second: 715.82 [#/sec] (mean) Time per request: 139.70 [ms] (mean) Time per request: 1.40 [ms] (mean, across all concurrent requests)
ab -c 10 -n 100 http://193.40.0.182/test.php Requests per second: 694.44 [#/sec] (mean) Time per request: 14.40 [ms] (mean) Time per request: 1.44 [ms] (mean, across all concurrent requests)
cgi+php ilma suexec-ita
ab -c 1000 -n 10000 http://193.40.0.182/test.php Requests per second: 50.96 [#/sec] (mean) Time per request: 19622.50 [ms] (mean) Time per request: 19.62 [ms] (mean, across all concurrent requests)
ab -c 100 -n 1000 http://193.40.0.182/test.php Requests per second: 46.34 [#/sec] (mean) Time per request: 2157.80 [ms] (mean) Time per request: 21.58 [ms] (mean, across all concurrent requests)
ab -c 10 -n 100 http://193.40.0.182/test.php Requests per second: 52.00 [#/sec] (mean) Time per request: 192.30 [ms] (mean) Time per request: 19.23 [ms] (mean, across all concurrent requests)
cgi+mpm-itk (eraldi wrapper skripti ei kasuta otse php-cgi peale suunamine)
ab -c 1000 -n 10000 http://193.40.0.189/test.php Requests per second: 86.93 [#/sec] (mean) Time per request: 11503.70 [ms] (mean) Time per request: 11.50 [ms] (mean, across all concurrent requests)
ab -c 100 -n 1000 http://193.40.0.189/test.php Requests per second: 78.16 [#/sec] (mean) Time per request: 1279.40 [ms] (mean) Time per request: 12.79 [ms] (mean, across all concurrent requests)
ab -c 10 -n 100 http://193.40.0.189/test.php Requests per second: 79.30 [#/sec] (mean) Time per request: 126.10 [ms] (mean) Time per request: 12.61 [ms] (mean, across all concurrent requests)
mod_php ja mpm-itk ab -c 10 -n 100 http://193.40.0.183/katse.php Requests per second: 249.38 [#/sec] (mean) Time per request: 40.10 [ms] (mean) Time per request: 4.01 [ms] (mean, across all concurrent requests)
ab -c 100 -n 1000 http://193.40.0.183/katse.php Requests per second: 257.33 [#/sec] (mean) Time per request: 388.60 [ms] (mean) Time per request: 3.89 [ms] (mean, across all concurrent requests)
ab -c 1000 -n 10000 http://193.40.0.183/katse.php Requests per second: 210.65 [#/sec] (mean) Time per request: 4747.30 [ms] (mean) Time per request: 4.75 [ms] (mean, across all concurrent requests)