ugrás a tartalomhoz

PHP futtatása FastCGI módban

dtaylor · 2007. Május. 16. (Sze), 21.15
PHP futtatása FastCGI módban
Sokszor felmerül webkiszolgálókat adminisztrálók körében a kérdés, hogy hogyan lehetne a PHP futtatását biztonságosabbá tenni. Bizonyára sokunk futtat, telepített már rendszert mod_php-val (Apache), és sokan meg is tapasztaltuk ennek a hátrányait. Véleményem szerint ezeket a hátrányokat nagyon szépen meg lehet szüntetni, és lehet PHP-t futtatni biztonságosan, kompromisszumok nélkül.

A mod_php

A mod_php legnagyobb előnye, hogy nagyon egyszerű telepíteni, pillanatok alatt készen van. Debian Linux alatt a telepítése egy lépésben történik: apt-get install libapache2-mod-php5 (feltételezzük, hogy Apache 2-es kiszolgálót és PHP 5-ös verziót szeretnénk telepíteni). Ez a parancs letölti a megfelelő Apache modult, és telepíti azt. A PHP konfigurációs állományát (php.ini) alapértelmezés szerint a /etc/php5/apache könyvtárba teszi. A parancs kiadását követően újra kell indítanunk a kiszolgálót, és már használhatjuk is a PHP-t.

A mod_php előnyei

  • Egyszerű, gyors telepítés
  • Ismert a webfejlesztők körében
  • Gyors a PHP futása (mihez képest, ugye?)
  • Virtual hostonként lehetőségünk van egyedi PHP beállítások használatára
  • A PHP futási paramétereit magunk is könnyedén módosíthatjuk könyvtáranként .htaccess állományok segítségével

A mod_php hátrányai

Mindannyian dolgoztunk már mod_php-val, így ismerjük azt a tényt, hogy a PHP kiszolgálása a kiszolgálótt futtató felhasználó nevében történik (ez némely rendszeren a www-data, másokon a nobody). Ez a megoldás azért problémás, mert ha írni akarunk a fájlrendszerbe, akkor azt csak a jogosultsági rendszer meglazításával lehet: vagy az összes felhasználónak írási joggal kell rendelkeznie az adott állományra vagy könyvtárra, vagy az a www-data tulajdonában kell legyen.

Ez egy felhasználónál nem gond (fejlesztő gépe), de mi a helyzet akkor, ha többen vannak? Ha én a /home/donci/nagyontitkosallomanyok könyvtárban szeretném tárolni a nagyon titkosnak ítélt dolgaimat, akkor hogy oda tudjak írni, a www-data felhasználónak is kell tudnia oda írni. Ebből a tényből következik az, hogy ha a badboy nevű felhasználó kideríti az elérési utat (ami nem feltétlenül esik egybe a web gyökérkönyvtárral), akkor simán el tudja olvasni az én titkosnak vélt állományaimat.

Természetesen, ekkor nagyon fontos az open_basedir PHP direktíva beállítása, hogy badboy ne tudjon PHP programmal garázdálkodni a saját könyvtárán kívül (/home/badboy). Ugyanez vonatkozik a többi felhasználóra is!

De ez sem teljesen jó megoldás: én, mint átlagos felhasználó nem tudom a nagyon titkos könyvtáramat a www-data tulajdonába átadni, mivel nem tudom a jelszavát. Annyit tehetek csak, hogy az összes felhasználónak adok olvasási, írási jogot a könyvtárra (chmod o+rw), de ezután már PHP futtatási jog sem kell ahhoz, hogy valaki turkálhasson a könyvtárban. Valljuk be, ez nem túl szerencsés dolog.

Másik nagy hátránya a mod_php használatának az, hogy egy modul futtatja az összes felhasználó PHP programjait, ezért, ha a kedves badboy ír egy olyan programot, ami valamely oknál fogva működésképtelenné teszi a mod_php-t, akkor az én PHP programom futása is megakad.

Egy lehetséges megoldás: PHP futtatása mod_fastcgi segítségével

Elég sok kutatásba, próbálkozásba került, mire sikerült megoldani a PHP futtatását úgy, hogy a fentebb említett, mod_php használatából fakadó hátrányokat kiküszöböljem.

Mi ez a FastCGI?

Röviden: olyan mint a CGI, csak jobb. Nézzük kicsit leegyszerűsítve: egy CGI (Common Gateway Interface) alkalmazás esetén a program futása a következőképpen néz ki: jön a kérés a kiszolgáló felé, mire az továbbítja a kérést a CGI programnak. Jelen esetben ez a PHP értelmező lesz, ami futtatja a programot, és az eredményt visszaadja a kiszolgálónak, majd ezután eltűnik a memóriából. Egy következő kéréskor ugyanez a folyamat ismétlődik, amiből egyből láthatjuk, hogy ez a módszer nem túl hatékony, a PHP értelmezőt állandóan be kell tölteni, majd ki kell pakolni a memóriából.

A FastCGI ezt a be/ki töltögetést küszöböli ki: a PHP értelmező bent marad a memóriában addig, amíg szükség van rá. Sőt, egyszerre több értelmezőt is a memóriában tart, így egyszerre több kérést is ki tud szolgálni a szerver.

A CGI program külön szálként fut a kiszolgálón, elkülönítve tőle, és a többi hasonló száltól. Ha az egyik kedves felhasználó programja megöli a CGI értelmezőjét, akkor sincs semmi gond, az meghal, de a többi attól még vígan dolgozik, és szolgálja ki a lapokat.

PHP futtatás felhasználói jogokkal? Lehetséges?

Igen, lehetséges, az Apache suEXEC szolgáltatását használva. A suEXEC biztonsága azon alapul, hogy egy wrapperként (befoglaló programként) más felhasználói jogokkal tud indítani alfolyamatokat. Ezzel a módszerrel megoldhatjuk, hogy a CGI módban futó PHP programunk felhasználói jogokkal fusson. Meg kell említenünk a teljesség kedvéért, hogy léteznek még más PHP futtatási megoldások is: például a SuPHP, de a fellelhető információk alapján ennek a sebessége messze elmarad a FastCGI sebességétől (mérések szerint akár 70× lassabb is lehet!).

A kiszolgáló beállítása

A környezet kialakításához szükségünk lesz a mod_fastcgi (emellett a mod_cgi és mod_actions) és mod_suexec modulokra a kiszolgálóhoz, és CGI módú (--enable-fastcgi opcióval fordított) PHP-ra.

A fentebb említett modulok betöltését a következő sorok az Apache konfigurációs állományába történő beírásával érhetjük el:

LoadModule actions_module /usr/lib/apache2/modules/mod_actions.so
LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so
LoadModule fastcgi_module /usr/lib/apache2/modules/mod_fastcgi.so
Debian rendszer alatt elég a mods-available könyvtárból a megfelelő .load állományokat linkelni a mods-enabled könyvtárba.

A FastCGI konfigurációs állomány

Nálam ez egy fastcgi nevű állományban van az Apache 2 conf.d könyvtárában:

FastCgiIpcDir /var/lib/apache2/fastcgi
FastCgiWrapper /usr/lib/apache2/suexec2
SuExecUserGroup www-data www-data
ScriptAlias /cgi/ /var/www/

<Location /cgi/>
    Options +ExecCGI
    SetHandler fastcgi-script
</Location>
A wrapper a suexec2 program, amely indítani fogja a CGI programokat, és alapértelmezésben a www-data felhasználó/csoport jogokkal fog futni a PHP értelmező. Ezt követően a kiszolgáló /cgi könyvtárára biztosítunk CGI futtatási lehetőséget.

Ezután már csak a virtuális kiszolgáló beállítása következik, mely két részből áll: a konfigurációs állományból, és egy PHP-t indító shell scriptből, melyre a suEXEC miatt van szükség. Nézzük meg ez utóbbit először.

A PHP-t indító shell script

A suEXEC biztonsági beállításai olyanok, hogy csak a /var/www könyvtárból enged suid-elt program futtatást. Ezért egy apró programot kell ebben a könyvtárban elhelyezni, amely majd a CGI módú PHP értelmezőt indítja. Erre a programra a suEXEC biztosítja a kiszolgálótól eltérő felhasználói jogokat.

Virtuális kiszolgáló beállítása

A host neve legyen a példa kedvéért foo.bar, a felhasználó pedig foo. Ennek érdekében a /var/www alatt hozzunk létre egy foo.bar könyvtárat, melynek tulajdonosa foo:foo legyen. Ebbe a könyvtárba kell tenni a PHP-t indító scriptet php-fcgi néven, szintén foo:foo jogokkal. A könyvtárat azért csináljuk, hogy a virtuális kiszolgálók konfigurációs állományait elkülönítsük egymástól.

#!/bin/sh
PHPRC="."
export PHPRC
PHP_FCGI_CHILDREN=4
export PHP_FCGI_CHILDREN
exec /usr/lib/cgi-bin/php5 $*


A fenti kis programocska a /usr/lib/cgi-bin/php5 programnak fogja átadni a vezérlést, amely feldolgozza majd a mi PHP szkriptünket. A PHPRC beállítás pedig lehetővé teszi, hogy ebben a könyvtárban elhelyezzünk egy php.ini-t, így lehetőségünk van virtuális kiszolgálónként egyedileg konfigurált PHP-t használni. Ezt a php.ini-t már lehet root jogokkal odatenni, ha nem akarjuk, hogy a felhasználó módosíthassa.

A szokásos dolgokon kívül a következőket kell beállítani:

SuexecUserGroup foo foo

ScriptAlias /fcgi/ /var/www/foo.bar.fcgi/
<Location /fcgi/>
    SetHandler fastcgi-script
</Location>
<Directory /home/foo/webroot/ >
    Options FollowSymLinks Indexes ExecCGI

    Order deny,allow
    allow from all

    AddType application/x-httpd-fastphp .php
    Action application/x-httpd-fastphp /fcgi/php-fcgi
</Directory>
A SuexecUserGroup után adjuk meg azt a felhasználót, akinek a nevében fog futni a PHP. Ezután már csak néhány FastCGI beállítás jön, ahol megadjuk, hogy egy php kiterjesztésű állomány kiszolgálásakor a fent elkészített szkriptünk fusson (de már felhasználói jogokkal).

A FastCGI módszer hátrányai

  • Lassabb mint a mod_php. Részben igaz csak, igazából csak a CGI hívás miatt van egy pici konstans overhead (pár ms). Némely esetben a FastCGI PHP a gyorsabb
  • Nem lehet .htaccess-ben php.ini beállításokat használni, cserébe viszont van egy saját php.ini-nk, ahol tényleg mindent be tudunk állítani virtuális kiszolgálónként (azt is, hogy milyen modulokat használhat az adott host)
  • Ha nem a felhasználó tulajonában van a PHP program, nem fut...
  • Az Apache által biztosított könyvtár autentikáció csak külön beállításokkal működik

A FastCGI módszer előnyei

Azt hiszem a fentiekből már teljesen világos lehet, de azért kiemelném a legfontosabbakat:
  • Biztonságosabb, mint a mod_php, mivel felhasználói jogokkal fut a PHP programunk
  • Hostonként teljes a kontroll a PHP felett a saját php.ini miatt
  • Mivel a /var/www-ben elhelyezett kis szkriptek bármilyen programot indíthatnak, ezért hostonként más verziójú PHP futtatható!
  • Nem kell foglalkozni a könyvtárak jogainak átadásával: ahova a felhasználó írhat, oda írhat a PHP is, ezáltal sokkal átláthatóbb a jogrend

Az eredmény

A kiszolgálónkon a ps -axfu parancsot kiadva valami hasonló kimenetet kell kapnunk:

root         9767  0.0  0.3  12748  6308 ?        Ss   Jun06   0:08 /usr/sbin/apache2 -k start -DSSL
www-data     7792  0.0  0.2  12748  4632 ?        S    Jun29   0:01  \_ /usr/sbin/fcgi-pm -k start -DSSL
donci        7794  0.0  0.2  14016  5228 ?        Ss   Jun29   0:00  |   \_ /usr/lib/cgi-bin/php5
donci        7795  0.1  1.3  39448 28724 ?        S    Jun29   2:11  |   |   \_ /usr/lib/cgi-bin/php5
donci        7796  0.1  1.3  39452 28736 ?        S    Jun29   2:11  |   |   \_ /usr/lib/cgi-bin/php5
donci        7797  0.1  1.3  38928 28200 ?        S    Jun29   2:11  |   |   \_ /usr/lib/cgi-bin/php5
donci        7799  0.1  1.4  41208 30520 ?        S    Jun29   2:06  |   |   \_ /usr/lib/cgi-bin/php5
user1        7845  0.0  0.2  14012  5224 ?        Ss   Jun29   0:00  |   \_ /usr/lib/cgi-bin/php5
user1        7846  0.0  0.6  25068 14236 ?        S    Jun29   0:35  |   |   \_ /usr/lib/cgi-bin/php5
user1        7847  0.0  0.6  24980 14196 ?        S    Jun29   0:35  |   |   \_ /usr/lib/cgi-bin/php5
user1        7848  0.0  0.6  25040 14184 ?        S    Jun29   0:35  |   |   \_ /usr/lib/cgi-bin/php5
user1        7849  0.0  0.6  24956 14168 ?        S    Jun29   0:34  |   |   \_ /usr/lib/cgi-bin/php5
Szépen látszik, hogy a FastCGI fő folyamatot még a www-data indította el, de a többi alfolyamat már felhasználóként fut.

Források

 
1

Ubuntu alatt van DEB

janoszen · 2007. Május. 17. (Cs), 04.55
Ha valaki esetleg Ubuntu szerverben utazik, újabban van FastCGI modul is a mod_php mellé, alternatívaként megjelölve a dependenciákban tehát a telepítés némileg leegyszerűsödik.

Minden esetre valószínűleg megspóroltatok nekem 2-3 nap szívást a közeljövőben mert pont most akarom végre valahára megcsinálni a saját szerveremet, természetesen FastCGI-vel.
2

fenntartások

vbence · 2007. Május. 17. (Cs), 08.21
A felhasználónként 4 (de akár 1) process tűnik nekem a legnagyobb hátránynak. A másik, hogy így (gondolom) nem működik a Zend Optimizer (és hasonló cache-megoldások).

Egy spekuláció: a php-fcgi szkriptük minden egyes kiszolgáláskor lefut, vagy csak a szerver indításaokor? Az ezt futtató /bin/sh rendszerszinten van jelen. Nem kéne felhasználónként külön változatot használni, azaz nem teszi ez sebezhetővé a rendszert a konkurencia-támadásokkal szemben? (a suexec és shellskript kombinációjára gondolok)

Én egy működő chroot-ban látom a biztonság zálogát. Épp ideje lenne megoldniuk (ahelyett, hogy további szükségtelen funkciókat tömnek az apache-ba).

A cikk amúgy szép összképet ad. Ha még is szükségem lenne a dologra mostmár tudom hol kezdjem a nézelődést.
3

Pontosítok

dtaylor · 2007. Május. 17. (Cs), 09.40
1; processzek: azért vannak, hogy kiszolgáljanak. Ha nem csinál semmit, nem visz erőforrást. Sikerült már megoldanom, hogy host-onként csak 1 db. legyen.

2; Zend optimizer természetesen megy. Szerintem a többi is. A debug (zend féle tutti) nem megy együtt fastcgi-s php-vel.

3; Egyszer fut le a php-fcgi. Látszik a process listában. Ez az sh is juzerként megy, illetve sh scriptet nem lehet suexec-elni, ahogy én tudom :D

4; Egyébként nálam chroot-al fut a rendszer: juzerek egy jail-ba vannak bezárva. Az apache pedig egy könyvtárjukba kívülről "benyúl" a webes tartalomért.

Én mióta átalakítottam a szerverem tized annyit szívok. Nincsenek world-wide irható dir-ek, www-data által létrehozott állományok, semmi. Csak felmásolom a tartalmat, és fut. Ez benn a legnagyobb dolog, szerintem. + hostonként állítom a modulokat, sőt, mindent, mert minden hostnak saját php.ini-je van. Még az upload_dir-t is a juzer könyvtárába rakom. A php error log is neki megy, nézegesse nyugodtan, hogy mit kefélt el... Ugyis csak a saját virt.host logja megy oda.

Mint írtam, sebesség tesztet nem volt időm csinálni, igazából nem is tudom, hogy kellene nekifogni. Ugyanolyan gépen ugyanaz a teszt fusson le, stb... Szemre nincs lassulás, de ez nem jelent semmit. Nagyobb terhelésnél kellene megnézni, hogy mi a helyzet.

Igazából írtam egy programot, ami paraméterekből legenerálja nekem a virtuális szerver konfigot + a php.ini-t is, létrehozza a könyvtárakat, user tulajdonába adja az állományokat, stb. 0 munka szervert konfigurálni. (Ez egy következő írás témája lesz, de nem itt.)

Saját, fejlesztői gépemen is ezt a mődszert használom, annyira bejött a dolog. :D
4

chroot és hasonlók

vbence · 2007. Május. 17. (Cs), 10.06
A nyugvó processek is esznek, ha mást nem, memóriát. Nem tudom, hogy melyik része lesz rezidens ilyenkor a PHP-nek, mekkora footprintel, ha a azt mondod, hogy ez kevés, én elhizsem :)

A chroot-ot hostonként gondoltam. Ez is megoldható, de szintén csak CGI módban. (Plusz a libraryket minden hostba be kell másolni, ami nagyon béna dolog).
5

process és a chroot

dtaylor · 2007. Május. 17. (Cs), 10.57
Szia!

Igen eszik, de a fastcgi rugdossa ki azt a process-t ami már nem dolgozik. Mindig van néhány, ami csak "vár" egy kérésre. A memória meg azért van, hogy használjuk. A webszerveren pont erre, hogy ott figyeljen valami a kérésre... :D Most néztem, nálam 30K-t eszik egy ilyen process.

Igazából, a memória foglalást is érdemes lenne összehasonlítani a mod_php-s megoldással...

A chroot nálam juzer szinten van, ami gyakorlatilag virt. host szint is. Megoldható lenne, hogy egyenként legyen mindenkinek egy chroot-ja, de az tényleg több meló.
18

chroot

kiuka · 2007. Szep. 27. (Cs), 15.55
hello

ha van idod leirhatnad hogy csinaltad meg ezt a userenkenti chrootolast mert regota keresek hozza jo leirast es nem talaltam meg ezidaig.
19

SSH

janoszen · 2007. Szep. 27. (Cs), 16.39
Ha SSH, az egyszerű, olyan shellt kell használni ami támogatja. Ha meg PHP, akkor a FastCGI wrapperből vagy hasonló helyből kell megoldani.
20

php

kiuka · 2007. Szep. 28. (P), 01.50
PHP-ra gondoltam nem SSH-ra. Igen valami ilyesmire gondoltam en is, de azon belul nem nagyon talaltam megoldast ra
21

wrapper

janoszen · 2007. Szep. 28. (P), 04.31
Hmmm... szvsz a wrapperből kellene valahogy megoldani. Én személy szerint megelégszem az open_basedir-rel, mert nekem minden domain dedikált useren fut, úgy csak azt tudja szétbarmolni amire a kedves domain tulajdonos nyúzer neki jogot adott.
22

sehogy

dtaylor · 2007. Szep. 28. (P), 08.10
Nem userenként csináltam chroot-ot. Bár meg lehetne csinálni. Tobb user van egy közös jailben, de csak a shell juzerek. A php a cgi-n keresztül "csak" juzerként fut, nincs külön chroot-olva.
23

ok

kiuka · 2007. Szep. 29. (Szo), 14.33
ertelek, nalam is open_basedir van, csak chroot valamivel szebb megoldas szerintem:) azert koszi
24

Félreértesz, imho

dtaylor · 2007. Okt. 1. (H), 07.02
Van chroot-om. Minden juzerem egy jail-ban van, amiben gyakorlatilag nincs semmi.
+ van open_basedir is.
25

chroot

kiuka · 2007. Okt. 1. (H), 12.37
gondolom van egy alap chrootod pl: /var/www es azon belul egy /kispista.hu/ open_basedir en azt szeretnem megoldani hogy minden user a /var/www/valamilyendomain.valami/ legyen a / vagyishat persze mindenkinek a sajat domainja:) pl atw-nel igy van megoldva csak jo kerdes hogy:)
26

php

kiuka · 2007. Okt. 1. (H), 12.45
most latom amit irtal lejjebb, igazabol en arra torekszem hogy php ugy fusson hogy nyugodt szivvel tudjak aludni:) ha kap egy chrootot a sajat konyvtarjara, akkor sokat nem tud kezdeni csinalhat barmit open_basedir hasonlok nekem prependbol vannak, ami nem a legjobb szerintem
6

Erre a cikkre vártam már vagy egy éve.

sajt · 2007. Május. 18. (P), 10.13
Végre :)
7

WOW, grat

pp · 2007. Május. 19. (Szo), 04.32
Dönci mester ismét villantott!

pp
8

Nyilvános a php5-fcgi

janoszen · 2007. Szep. 18. (K), 21.57
Egyetlen gond van ezzel a módszerrel, méghozzá hogy a php-fcgi szép nyilvános lesz (legalábbis nekem az lett, lehet hogy ez csak a mod_vhost_alias hibája) és azt nem szeretnénk. A megoldás - úgy tűnik - hogy ez:

RewriteEngine on
RewriteCond %{ENV:REDIRECT_STATUS} !=200
RewriteRule /fcgi/php-fcgi - [F]
9

azért ezen lehet reszelni

amonrpg · 2007. Szep. 20. (Cs), 06.35
Mi ezt úgy oldottuk meg, hogy a következő könyvtárszerkezetet alakítottuk ki:
/userhome
/userhome/php-fcgi
/userhome/siteroot/log
/userhome/siteroot/web/

ftp home:
/userhome/siteroot

docroot:
/userhome/siteroot/web/

Így a felhasználók - mivel nincs nekik SSH (mer' minek? :) ) - nem tudják elérni a bash scriptet. Pontosabban az tudja elérni, akinek van.
10

És a cgi alias dir?

janoszen · 2007. Szep. 20. (Cs), 07.21
És ha beütöd azt, hogy http://userdomainje.hu/fcgi/php-fcgi akkor mi történik?

Egyébként én kevésbé félek a felhasználóktól, mert aki kap SSH-t az bizonyítottan bánni is tud vele, inkább attól hogy a php-fcgi indító scriptben benne van hogy hol van a kedves PHP bináris, ami majdnem triviális mégis kényelmetlen nekem hogy valaki csak úgy meg tudja hívni.

Amit sokkal nagyobb problémának érzek, hogy vagy a mod_vhost_alias, vagy a FastCGI vagy a PHP (vagy mind a három együtt) elbarmol három változót a PHP-ben, nevezetesen a $_SERVER tömbben a DOCUMENT_ROOT-ot, a SCRIPT_NAME-t és a SCRIPT_FILENAME-t. Egyes gyengébb képességű scriptek pedig használják ezeket, ami nem túl szerencsés. Sajnálatomra ezt csak egy auto_prepend-elt PHP scripttel tudtam megoldani, ami ugye azért nem az igazi megoldás.
11

bocs reggel volt

amonrpg · 2007. Szep. 20. (Cs), 08.06
kicsit félreértettem a dolgot, kora reggel volt még, bocs... a rewritetal se tűnt fel, hogy webes nyilvánosságról szólsz. :D hamuafejemre

No igen, ez valóban lehet probléma, viszont szerintem nem túl nagy. Mit tud vele kezdeni bárki is? Mármint azon túl, hogy valóban megtudja, hogy a /usr/lib/cgi-bin/php5 (debian esetében pl) a futtató?
Ha nincs elérése a szerverre, akkor semmit imho. Persze ettől még elrejtjük mi is, sose lehet tudni :D.

Nálam egyedül a DOCUMENT_ROOT nem mutat jó helyre, de az a mod_vhost_alias miatt van. Az eredeti DOCUMENT_ROOT-ot adja vissza, nem az alias-ét. Viszont a SCRIPT_FILENAME jó, és abból ki lehet parse-olni a valódi docroot-ot, feltéve, ha a gyenge képességű programom hívása (ahogy szoktam) egy darab index.php-n keresztül érkezik.
12

Akkor

janoszen · 2007. Szep. 20. (Cs), 09.00
Akkor nem sikerült nektek sem megoldást találni erre... én ott fogom hagyni a javító PHP-t, aki szeretné majd berakja a php.ini-jébe... :)
27

auto_prepend

kiuka · 2007. Okt. 1. (H), 20.23
most probalgatva nem szukseges auto_prepend_filebol beallitgatni a dolgokat, egy export SCRIPT_FILENAME=amit akarsz es maris az lesz phpinfo-ban is
13

Nyilvános az fcgi shell wrapper, igen

dtaylor · 2007. Szep. 21. (P), 07.56
A suexec miatt a juzernek kell adni a futtatható file-ot.

Én úgy oldottam meg, hogy ne érje el a juzer: jail.
Az összes juzerem be van zárva egy minimál jail-be (/home/jail). Gyakorlatilag ez az Ő rendszerének a gyökere.
Innentől az igazi /var/www-t el se éri.


Az apache meg kivül fut, és "benyúl" a juzer home-jába. Innentől semmi gond a jogrenddel: juzer nem piszkálja a saját php.ini-jét.
14

Lehet így is...

janoszen · 2007. Szep. 21. (P), 08.20
Igen, lehet így is csinálni, bár mivel user jogosultságokkal fut, nem tudom mennyire akarok paranoid lenni. Személy szerint meg akarom adni a usereimnek azt a lehetőséget, hogy a php.ini-t tekergessék, de azt sem bánom túlzottan ha a futtató fájlt izélik. Shell hozzáférést meg úgyis csak az kap, akiről tudom hogy ért hozzá. A többiek meg valamilyen deployment procedúrával tudnak feltölteni (WebDAV vagy hasonlók).

Nem a nyúzereimtől félek, sokkal inkább attól hogy kívülről nyúkálnak bele a szerverbe.
15

suExec és a php-fastcgi esete

janoszen · 2007. Szep. 23. (V), 23.31
Ok, ha valaki esetleg *nem* a /var/www könyvtárban óhajtja tárolni a php-fcgi scriptet akkor jobb, ha fölkészül némi suexec forrásból fordításra, mert a suexecbe bele van gyógyítva hogy honnan legyen hajlandó indulni. Ami szerintem ökörség és a nem egyértelmű hibaüzenetek miatt el lehet játszadozni egy pár órát mint én, de inkább ne tegyük. :D
16

wo?

dtaylor · 2007. Szep. 26. (Sze), 07.42
A suEXEC biztonsági beállításai olyanok, hogy csak a /var/www könyvtárból enged suid-elt program futtatást.
17

Rájöttem...

janoszen · 2007. Szep. 27. (Cs), 15.40
Rájöttem, csak sajnos fél nap szívás árán, mert nem volt elég informatív a hibaüzenet. Kár, hogy bele van égetve fordítási időben és nem tudja config fájlból beolvasni.
28

suexec

bandi · 2008. Már. 4. (K), 20.31
Bizony, sok időt el tud venni az embertől. Kipróbáltam kicsiben mod_fcgid-vel (és rubyval, de most az nem számít, hogy tele van a hócipőm a php-val), és egész hamar ment a public_html könyvtárban, viszont amikor komolyabb helyre akartam komolyabb dolgot berakni, akkor behalt. Valahol azt írják, hogy azért vannak fordítási idejű beállítások, hogy biztonságosabb legyen. Ha nem vagy biztos, hogy mik ezek a paraméterek, akkor root-ként a -V paraméterrel futtatva kiírja, hogy /var/www a könyvtár vagy valami más.
29

ÖNTSÜNK TISZTA VIZET A FASTCGI-BE!

phpkezdo · 2010. Feb. 13. (Szo), 15.47
Találtam a neten néhány jó leírást, de ezek közül egyik sem volt alkalmas arra, hogy egy tökéletesen működő fastcgi-t be tudjak állítani.
Ezért szeretném én is leírni, hogy nekem, hogyan sikerült beállítani és mik voltak azok a problémák, ami miatt elsőre nem sikerült a leírások alapján!
Sajnos én sem fogok mindenre kitérni, de aki fastcgi-t akar telepíteni az legyen azért az alapokkal tisztában (pl mit jelent hogy az apacheban be van töltve egy modul vagy mi a cgi módban fordított php5 metapack vagy mire jó az apt-get vagy az yum parancs)
Lássuk akkor hát a fastcgi telepítésének menetét, apache2.2 alá, fcgid modul segítségével DEBIAN 5 alatt:

1. Az apache2-ben a következő moduloknak kell betöltve lenni (ha nincsenek, akkor a csomag kezelővel, apt-get-el le kell tölteni):
actions, alias, cgi, cgid, env, expires, rewrite, negotation, auth_basic, authn_file, authnz_ldap, authz_dbm, authz_default, authz_groupfile, authz_host, authz_owner, authz_user, autoindex, deflate, dir, suexec, fcgid vagy normál mod_fastcgi, headers, include, ldap, mime, mime_magic, setenvif, ssl, userdir, vhost_alias

Természetesen ezek közül sem létfontosságú mind!

2. Hozzunk létre egy UNIX felhasználót és egy csoportot. Nálam mindkettő neve PHP0 lesz és az id 1001, szintén mindkettőnek (a csoportnak és a felhasználónak is)
A www-data felhasználó éd csoport id-je 33-as lesz! A root felhasználó UserID-je és GroupID-je 0.

3. Hozzuk létre az alábbi könyvtárakat az alábbi felhasználói tulajdonságokkal:
var/www/ ---> CHMOD 755 UID:33 GID: 33
var/www/fcgi ---> CHMOD 555 UID:0 GID: 0
var/www/fcgi/main ---> CHMOD 755 UID:1001 GID: 1001
var/www/virtual/ ---> CHMOD 555 UID:0 GID: 0
var/www/virtual/main/ ---> CHMOD 770 UID:1001 GID: 33
var/www/virtual/main/cgi-bin ---> CHMOD 755 UID:1001 GID: 1001
var/www/virtual/main/htdocs ---> CHMOD 755 UID:1001 GID: 1001
var/www/virtual/main/error ---> CHMOD 775 UID:1001 GID: 1001
var/www/virtual/main/phptmp ---> CHMOD 770 UID:1001 GID: 33


Ezek is eltérhetnek igény szerint. A HTDOCS nevű mappa az adott virtual host documentum rootja.

4. A var/www/fcgi/main mappába hozzuk létre a következő fájlt!

php5-fcgi-starter

Tartalma legyen:
---------------------
#!/bin/sh

umask 022

PHPRC="."
export PHPRC

TMPDIR="/var/www/virtual/main/phptmp"
export TMPDIR

PHP_FCGI_CHILDREN=2
export PHP_FCGI_CHILDREN

exec /usr/bin/php5-cgi
------------------------

Mellé rakjunk egy php init!

5. Hozzunk létre egy virtual hostot az apacheban!

Ezek a dolgok legyenek benne!
----------------------------------------------
<IfModule suexec_module>
SuexecUserGroup PHP0 PHP0
</IfModule>
#Figyelj oda hogy minden összetevő előtt legyen ott az "<IfModule akármilyen_module>" rész és a lezárója </IfModule>

ServerAdmin webmaster@main
DocumentRoot /var/www/virtual/main/htdocs

ServerName daomaineved.hu #vagy ha nincs akkor töröld ki a sort
ServerAlias www.daomaineved.hu daomaineved.hu *.daomaineved.hu php0.daomaineved.hu

Alias /errors /var/www/virtual/main/errors/

ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
ErrorDocument 503 /errors/503.html

<IfModule mod_cband.c>
CBandUser main
</IfModule>

# httpd awstats support BEGIN.

# httpd awstats support END.

# httpd dmn entry cgi support BEGIN.
ScriptAlias /cgi-bin/ /var/www/virtual/main/cgi-bin/
<Directory /var/www/virtual/main/cgi-bin>
AllowOverride AuthConfig
#Options ExecCGI
Order allow,deny
Allow from all
</Directory>
# httpd dmn entry cgi support END.

<Directory /var/www/virtual/main/htdocs>
# httpd dmn entry PHP support BEGIN.
# httpd dmn entry PHP support END.
Options -Indexes Includes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>

# httpd dmn entry PHP2 support BEGIN.
<IfModule mod_php5.c>
php_admin_value open_basedir "/var/www/virtual/main/:/var/www/virtual/main/phptmp/:/usr/share/php/"
php_admin_value upload_tmp_dir "/var/www/virtual/main/phptmp/"
php_admin_value session.save_path "/var/www/virtual/main/phptmp/"
php_admin_value sendmail_path '/usr/sbin/sendmail -f php0 -t -i'
</IfModule>
<IfModule mod_fastcgi.c>
ScriptAlias /php5/ /var/www/fcgi/main/
<Directory "/var/www/fcgi/main">
AllowOverride None
Options +ExecCGI -MultiViews -Indexes
Order allow,deny
Allow from all
</Directory>
</IfModule>
<IfModule mod_fcgid.c>
Include /etc/apache2/mods-available/fcgid_ispcp.conf
<Directory /var/www/virtual/main/htdocs>
FCGIWrapper /var/www/fcgi/main/php5-fcgi-starter .php
Options +ExecCGI
</Directory>
<Directory "/var/www/fcgi/main">
AllowOverride None
Options +ExecCGI MultiViews -Indexes
Order allow,deny
Allow from all
</Directory>
</IfModule>
------------------------------------------------------

6. Állítsuk be a fastcgid modult a configurációs állomány segítségével. Nálam ez így néz ki!

<IfModule mod_fcgid.c>
AddHandler fcgid-script .fcgi .php .php5
SocketPath /var/lib/apache2/fcgid/sock
IdleTimeout 600
IdleScanInterval 120
BusyTimeout 300
BusyScanInterval 120
ErrorScanInterval 3
ZombieScanInterval 3
ProcessLifeTime 900
SpawnScoreUpLimit 10
SpawnScore 1
TerminationScore 2
MaxProcessCount 200
DefaultMaxClassProcessCount 10
DefaultMinClassProcessCount 1
IPCConnectTimeout 900
IPCCommTimeout 900
MaxRequestsPerProcess 500
</IfModule>

7. Indítsuk újra az apache-ot!

8. Ellenőrizzük a működést

Készítsünk phpinfo,php fájlt az alábbi tartalommal:
<?php
phpinfo();
?>

Ezt futtassul le a böngészőben pl http://domained.hu/phpinfo.php

Megjegyzések!
--------------------------------
Természetesen az itt leírt elérési utak változhatnak, a felhasználó nevek, uid-k, gid-k szintén.
Figyeljünk arra, hogy a php5-fcgi-starter fájl a tulajdonosa által futtatható legyen (exec)
Fontos, hogy a modulokat IfModule tag-be zárjuk.

Ha valakinek kérdése van a leírtakkal kapcsolatban, vagy valamit elírtam, az írjon ide!
Üdv!
30

MOD-FASTCGI apache modul

phpkezdo · 2010. Feb. 24. (Sze), 15.20
Nézzük a fastcgi beállítását most a mod_fastcgi vel. DEBIAN 5 alatt. Ehhez debianon a libapache2-mod-fastcgi.deb et kell telepíteni. Ezt a csomagkezelővel lehet letölteni (apt-get)
Példa domain az srv11.ath.cx lesz.

Szokásos módon belőjük az apache-be a mod_fastcgit és kilőjük az előbb beállított mod_fcgid-t

LoadModule fastcgi_module /usr/lib/apache2/modules/mod_fastcgi.so

A virtual hostunk az SRV11-hez úgy néz ki mint a fcgid példában volt, mert ebben már minden jó php verzió benne van, még a mod_php-s <IfModule ...>
Annyit változtattam a dolgon hogy most a fastcgi wrapper a domain nevével megegyező mappában lesz.

Tehát a mappa szerkezetem így néz ki:
/var/www/virtual/srv11.ath.cx/
/var/www/virtual/srv11.ath.cx/fcgi
/var/www/virtual/srv11.ath.cx/htdocs
/var/www/virtual/srv11.ath.cx/phptmp
/var/www/virtual/srv11.ath.cx/sessions
/var/www/virtual/srv11.ath.cx/errors/
/var/www/virtual/srv11.ath.cx/.... n mappa .../

A phptmp tulaja a vu2002-es user csoportja www-data (GID : 33), a sessionnak is.

A virtual hostot tegyük bele mondjuk a httpd.conf -ba vagy akár egy külön fájlba
----------------------------------------------------------------------------------------------
<VirtualHost 192.168.0.121:80>

<IfModule suexec_module>
SuexecUserGroup vu2002 vu2002
</IfModule>

ServerAdmin webmaster##kukac##srv11.ath.cx
DocumentRoot /var/www/virtual/srv11.ath.cx/htdocs

ServerName srv11.ath.cx
ServerAlias www.srv11.ath.cx srv11.ath.cx *.srv11.ath.cx vu2002.srv10.ath.cx

Alias /errors /var/www/virtual/srv11.ath.cx/errors/

ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
ErrorDocument 503 /errors/503.html

<IfModule mod_cband.c>
CBandUser srv11.ath.cx
</IfModule>

# httpd awstats support BEGIN.

# httpd awstats support END.

# httpd dmn entry cgi support BEGIN.
ScriptAlias /cgi-bin/ /var/www/virtual/srv11.ath.cx/cgi-bin/
<Directory /var/www/virtual/srv11.ath.cx/cgi-bin>
AllowOverride AuthConfig
#Options ExecCGI
Order allow,deny
Allow from all
</Directory>
# httpd dmn entry cgi support END.

<Directory /var/www/virtual/srv11.ath.cx/htdocs>
# httpd dmn entry PHP support BEGIN.
# httpd dmn entry PHP support END.
Options -Indexes Includes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>

# httpd dmn entry PHP2 support BEGIN.
<IfModule mod_php5.c>
php_admin_value open_basedir "/var/www/virtual/srv11.ath.cx/:/var/www/virtual/srv11.ath.cx/phptmp/:/usr/share/php/"
php_admin_value upload_tmp_dir "/var/www/virtual/srv11.ath.cx/phptmp/"
php_admin_value session.save_path "/var/www/virtual/srv11.ath.cx/phptmp/"
php_admin_value sendmail_path '/usr/sbin/sendmail -f vu2002 -t -i'
</IfModule>

#EZ LESZ MOST HASZNÁLVA
<IfModule mod_fastcgi.c>
ScriptAlias /php5/ /var/www/virtual/srv11.ath.cx/fcgi/
<Directory "/var/www/virtual/srv11.ath.cx/fcgi">
AllowOverride None
Options +ExecCGI -MultiViews -Indexes
Order allow,deny
Allow from all
</Directory>
</IfModule>

<IfModule mod_fcgid.c>
Include /etc/apache2/mods-available/fcgid_ispcp.conf
<Directory /var/www/virtual/srv11.ath.cx/htdocs>
FCGIWrapper /var/www/virtual/srv11.ath.cx/fcgi/php5-fcgi-starter .php
Options +ExecCGI
</Directory>
<Directory "/var/www/virtual/srv11.ath.cx/fcgi">
AllowOverride None
Options +ExecCGI MultiViews -Indexes
Order allow,deny
Allow from all
</Directory>
</IfModule>
# httpd dmn entry PHP2 support END.

Include /etc/apache2/ispcp/srv11.ath.cx.conf

</VirtualHost>
--------------------------------------------------------

A wrapper a /var/www/virtual/srv11.ath.cx/fcgi mappában egy php5-fcgi-starter fájlban van, aminek a tulaja vu2002 , Futtatható a fájl. Mellette van egy php2002.ini fájl (Az user azonosítóját raktam a fájlhoz, de lehetne php-userneve.ini is)

A php5-fcgi-starter tartalma
---------------------------------------------------------
#!/bin/sh

umask 022

PHPRC="php2002.ini"
export PHPRC

TMPDIR="/var/www/virtual/srv11.ath.cx/phptmp"
export TMPDIR

PHP_FCGI_CHILDREN=4
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=10000
export PHP_FCGI_MAX_REQUESTS

exec /usr/bin/php5-cgi
------------------------------------------------------

A fastcgi.conf -ot a következő tartalommal töltöttem fel!
------------------------------------------------------------
<IfModule mod_fastcgi.c>
#OLD fastcgi
#AddHandler fastcgi-script .fcgi
#FastCgiWrapper /usr/lib/apache2/suexec
#FastCgiIpcDir /var/lib/apache2/fastcgi

FastCgiWrapper On
FastCgiIpcDir /var/lib/apache2/fastcgi

FastCgiConfig -minProcesses 1 \
-maxProcesses 400 \
-maxClassProcesses 100 \
-multiThreshold 80 \
-killInterval 60 \
-startDelay 5
# -singleThreshold 100 \
# -autoUpdate \
# -pass-header HTTP_AUTHORIZATION

#FastCgiServer /var/www/fcgi/master/php5-fcgi-starter -user www-data -group www-data -idle-timeout 300

AddHandler php-fastcgi .php .php5

<Location /php5/php5-fcgi-starter>
SetHandler fastcgi-script
Options +ExecCGI
</Location>

Action php-fastcgi /php5/php5-fcgi-starter
AddType application/x-httpd-php .php .php5
</IfModule>

---------------------------------------------------------------
Ez itt található /etc/apache2/mods-available és a /etc/apache2/mods-enabledbe egy szinbolikus linket teszek rá ha használni akarom, ha nem kell már akkor törlöm a szimbolikus linket!

Apache újraindítsás <? phpinfo(); ?> tartalmú fájlal gyönyörködünk az eredményben. Ha kell a php inivel finomhangolhatjuk a virtualhostra szabott php beállításainkat

Ha van némi előtapasztalatod a leírtak alapján tudod beállítani a fastcgit mod_fastcgi -vel

Ha valamit elírtam / valami nem világos / akkor kérdezni lehet.
31

PHP5

phpkezdo · 2010. Feb. 24. (Sze), 15.23
Látható hogy /php5/ alias mindíg az adott virtualhost wrapperének elérési útvonala lesz, tehát mindíg különböző wrappert fogja meghívni, hátránya, hogy a wrapper fájl neve így mindíg ugyan az kell hogy legyen. (Adott esetben most csak php5-fcgi-starter lehet)
32

FASTCGI

phpkezdo · 2010. Feb. 24. (Sze), 15.42
Bocs marhaságot mondtam

Ha a
Action php-fastcgi /php5/php5-fcgi-starter
aort kivágom és beteszem az adott vhosthoz akkor már tudom változtatni, de akkor ezt külön mindegyiknél meg kell csinálni, ez csak akkor gáz ha sok 100 domain van a szervereden, mert akkor lesz mit irogatni :)
33

Végülis ...

phpkezdo · 2010. Feb. 26. (P), 19.38
Végülis ez is egy mód a vhost php használatának ki / be kapcsolására :D
34

PHP CGI FUTTATÁS SUPHP MODULLAL

phpkezdo · 2010. Már. 7. (V), 14.51
A PHP CGI módban való hasznmálatára a fastcgi, és az fcgid modulon kívül a suPHP-val van még lehetőségünk.

Mint előzőekben most is következő környezetben dolgozunk: debian5, apache2 és php5.
Ezt is egy példán keresztül szeretném bemutatni.

srv10.ath.cx lesz a fihktív virtual hostunk, aminek a tartalmát a /var/www/virtual/SRV10/htdocs elérési útvonalon tároljuk.

Betöltöm a suphp modot a2enmod suphp

LoadModule suphp_module /usr/lib/apache2/modules/mod_suphp.so


Felhasználónk, akinek a nevében futa a php-cgi: SRV10.ATH
A html fájlokat www-data felhasználó futtatja (Az apach felhasználó)
Rendszergazda felhasználó : root

A következő mappa szerkezetünk van

/var/www/ => Tulajdonos: root csoport: root
... /virtual/ => Tulajdonos: root csoport: root
... ... /SRV10/ => Tulajdonos: SRV10.ATH csoport: www-data
... ... ... /cgi-bin => Tulajdonos: SRV10.ATH csoport: SRV10.ATH
... ... ... /errors => Tulajdonos: SRV10.ATH csoport: SRV10.ATH
... ... ... /fcgi => Tulajdonos: SRV10.ATH csoport: SRV10.ATH
... ... ... /htdocs => Tulajdonos: SRV10.ATH csoport: www-data
... ... ... /phptmp => Tulajdonos: SRV10.ATH csoport: www-data
... ... ... /session => Tulajdonos: SRV10.ATH csoport: www-data (CHMOD : 1733)


/var/www/virtual/SRV10/fcgi mappában lesz a php ini php-SRV10.ini néven (CHMOD 644)
Itt mindent beállíthatunk: memória limit, open_basedir, stb ...

Beállíthuk a virtual hostot (Erre akár egy külön fájlt is beállíthatunk)
-------------------------------------------------------------------------
ServerAdmin webmaster@SRV10
DocumentRoot /var/www/virtual/SRV10/htdocs
ServerName srv10.ath.cx

#Alias /errors /var/www/virtual/SRV10/errors/

#ErrorDocument 401 /errors/401.html
#ErrorDocument 403 /errors/403.html
#ErrorDocument 404 /errors/404.html
#ErrorDocument 500 /errors/500.html
#ErrorDocument 503 /errors/503.html

<IfModule suexec_module>
SuexecUserGroup SRV10.ATH SRV10.ATH
</IfModule>

ScriptAlias /cgi-bin/ /var/www/virtual/SRV10/cgi-bin/
<Directory /var/www/virtual/SRV10/cgi-bin>
AllowOverride AuthConfig
#Options ExecCGI
Order allow,deny
Allow from all
</Directory>


<Directory /var/www/virtual/SRV10/htdocs>
Options -Indexes Includes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>

#Így töltöm be az egyedi php ini-t minden felhasználónak egyedi php lehetőségeket adva
<IfModule mod_suphp.c>
suPHP_ConfigPath /var/www/virtual/SRV10/fcgi/php-SRV10.ini
</IfModule>

----------------------------------------------------------------------
Az apache /etc/apache2/mods-enabled/suphp.conf fájlt az alábbi módon állítotttam be!
------------------------------------------------------------------------------------
<IfModule mod_suphp.c>
AddType application/x-httpd-suphp .php .php3 .php4 .php5 .phtml
suPHP_AddHandler application/x-httpd-suphp

<Directory />
suPHP_Engine on
</Directory>

# By default, disable suPHP for debian packaged web applications as files
# are owned by root and cannot be executed by suPHP because of min_uid.
<Directory /usr/share>
suPHP_Engine off
</Directory>

# # Use a specific php config file (a dir which contains a php.ini file)
# suPHP_ConfigPath /etc/php4/cgi/suphp/
# # Tells mod_suphp NOT to handle requests with the type <mime-type>.
# suPHP_RemoveHandler <mime-type>
</IfModule>

--------------------------------------------------------------------------------------

A suphp-hez használunk még egy globális beállítás fájlt is amit a suphp telepítő alapértelmezetten az /etc/suphp könyvtárba tesz,
aminek a tartalát az alábbi módon állítom be:
-----------------------------------------------------
[global]
;Path to logfile
logfile=/var/log/apache2/suphp.log

;Loglevel
loglevel=info

;User Apache is running as
webserver_user=www-data

;Path all scripts have to be in
docroot=/var/www/virtual


;Path to chroot() to before executing script
;chroot=/var/www/virtual/*

; Security options
allow_file_group_writeable=false
allow_file_others_writeable=false
allow_directory_group_writeable=false
allow_directory_others_writeable=false

;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=true

;Send minor error messages to browser
errors_to_browser=true

;PATH environment variable
env_path=/bin:/usr/bin

;Umask to set, specify in octal notation
umask=0077

; Minimum UID
min_uid=100

; Minimum GID
min_gid=100


[handlers]
;Handler for php-scripts
application/x-httpd-suphp="php:/usr/bin/php-cgi"

;Handler for CGI-scripts
x-suphp-cgi="execute:!self"

-------------------------------------------------------------

Ha mindent jól csináltunk, akkor újra indítom az apache-ot.
<?php phpinfo(); ?> fájlal ellenőrzöm a működést:
KÉP ITT