Írtam már a mod_cgi/mod_cgid és a mod_fcgid modulokról, amikkel a PHP több verzióját futtathatjuk egyszerre. A PHP FPM viszont egy ezeknél is jobb megoldás. Azért mégsem tejesen új, mivel a mod_fastcgi vagy mod_fcgid Apache modulok egyike kell hozzá. Bár előbbiről nem esett még külön szó az említés szintjén felül, most ezt is telepítjük, mivel az Apache HTTPD 2.2 nem támogatja a szükséges mod_proxy_fcgi modult a mod_fcgid használatához.
A fejezet végén tehát már ismerni fogjuk mindkét lehetőséget és mindkét webszerver képes lesz bármely PHP verziót FPM-en keresztül futtatni tetszőleges felhasználó nevében.
Előbb azonban mindenképp javaslom a PHP telepítéséről szóló fejezet elolvasását, ahol az FPM telepítéséhez szükséges konfigurálásról írtam. Valamint az előző CGI megoldásokról szólót is.
Előkészületek, előismeret
Már az eddigiek után talán mondanom sem kell, de root jogra szükség lesz a sudo su
vagy su - root
parancsok egyikével. Amelyik működik.
Miért?
Mielőtt bármit állítgatnánk, értsük meg, hogy miért is tesszük és hogy ellenőrizzük a sikerességét! Azt a tényt, hogy ezzel több PHP verziót is lehet egyidejűleg használni, már kellően sokat emlegettem. És ez már FPM nélkül is működött. Ahhoz viszont, hogy a PHP egy tetszőleges felhasználó nevében futhasson, további intézkedések kellenek. Ez szintén megoldható lenne FPM nélkül, az FPM viszont ennél többről szól.
Egy helyen menedzselhetők a processek kezelésének tulajdonságai, a felhasználó és különböző környezeti változók. De akár egy chroot-olt környezet is használható vele. Illetve jó sebességet is el lehet érni. Profikat megszégyenítő beállításokat nem fogunk itt végezni, de nem is ez a cél.
Az, hogy a PHP-t egy adott felhasználó nevében lehet futtatni, azért lényeges, mert olykor a PHP-nek is tudnia kell fájlokat kezelni. Ehhez viszont kell, hogy legyen rá joga. Amihez pedig legalább a könyvtárak csoportját kell megfelelőre állítani, vagy mindenkinek kell rá jogot adni. Vagy egyszerűen a php-t kell tulajdonosnak kijelölni. Ekkor viszont a saját felhasználóval nem lehet könnyen szerkeszteni.
Ráadásul két teljesen független PHP alkalmazás, akár ( de nem feltétlenül) különböző valós személyek kezében ( chroot nélkül ) képes belelesni vagy akár belemódosítani a másik fennhatósága alatt álló fájlokba. Ha ezt körülményesen is fogalmaztam, annyi érezhető, hogy bonyodalmakat okoz az egyfelhasználós megoldás.
Tesztelés
Hogy ne csak "beszéljünk" erről, mutatok egy példát. Indítsuk el a 2.4-es szervert:
Elsőként ellenőrizzük le, hogy jelenleg mi is a felhasználója a PHP-nek! Ezt a következő módon: Készítünk egy whoami.php -t a p5414-es aldomain dokumentum gyökérebe.
Tartalomként pedig írunk egy sort, ami a shell-t használva kiírja az aktuális felhasználót:
echo exec('whoami');
Az eredménye nálam "daemon". Ez az Apache felhasználója. Ha lefuttatjuk parancssorban a
parancsot, hasonló kimenetet ad:
drwxr-xr-x 4 root root 4096 Apr 20 20:55 ..
-rw-r--r-- 1 root root 14 Apr 21 10:44 index.html
-rw-r--r-- 1 root root 17 Apr 27 16:46 index.php
-rw-r--r-- 1 root root 144 May 5 19:03 whoami.php
Látható, hogy minden fájl és könyvtár tulajdonosa a "root" felhasználó. Ezzel hoztam létre a könyvtárakat és a fájlokat. Készítsünk egy touch.php fájlt, ami csak megpróbál létrehozni egy teszt.txt fájlt:
A tartalma
touch('teszt.txt');
Az eredménye pedig:
A PHP-nek nincs hozzá joga. Jó, akkor adjuk át a tulajdoni jogot a mappára a daemon felhasználónak!
Az "ls" parancsot használva most ez látszik az aktuális könyvtárnál:
A touch.php pedig hiba nélkül lefut és létrehozza a teszt.txt fájlt.
Viszont innentől minden virtuális hosztnak van hozzá joga. A fájlt csak daemon vagy root userként lehet módosítani, de daemon-ként is csak root-ból lehet belépni. Ha pedig az olvasási jogot is elvenném az idegen felhasználóktól, akkor olvasni is csak így tudnám. Ez akár lehet cél is. Amikor helyi gépen, SSH-n keresztül vagy FTP-n dolgozunk, könnyen kopaszodáshoz vezethet manuális beavatkozással.
Apache 2.4
Most, hogy már remélhetőleg világosabb, miért és hová tartunk, jöhet az első szerver felkészítése mindhárom PHP verzióra. Az 5.3 és 5.4 -es PHP-val még könnyű dolgunk lesz. Az 5.2-nél trükközni kell.
Két modulra mindenképpen szükség lesz, amiket engedélyezni kell a httpd.conf-ban. Ezek a mod_proxy és a mod_proxy_fcgi. Ez teszi lehetővé, hogy megszólítsuk az FPM-et.
A
és a
sorok elejéről kell kivenni a kettőskeresztet
PHP 5.4.14
Ha megnézzük a phpinfo kimenetét, még "CGI/FastCGI" látható a "ServerAPI" mellett. Ez az FPM beállítása után meg fog változni "FPM/FastCGI" -ra. Lássuk!
Virtuális hoszt konfiguráció
Az előző megoldásoknál is mindig volt pár sor a virtuális hoszt definíciójában, ami valahogyan hivatkozott a használandó PHP-re. Itt most TCP-n keresztül IP és port segítségével történik a kommunikáció. A PHP-hez tartozik egy "php-fpm" program, ami a háttérben figyel adott IP-port párokon. Ezeket hívjuk pool-oknak. Amikhez egyedi beállításokat szabhatunk.
Ahhoz, hogy socket-en keresztül működjön a kommunikáció, meg kéne hackelni az Apache-ot. Erre egy patch-re lenne szükség, amit jómagam nem próbáltam ki, de a következő oldalon írnak róla:
https://issues.apache.org/bugzilla/show_bug.cgi?id=54101
Haladók saját felelősségre ügyeskedhetnek.
Nyissuk meg a p5414 aldomainhez tartozó virtuális hoszt definíció fájlját:
A <Directory>
blokk elé kerüljön a következő sor:
A korábbi, cgi wrapper-t használó megoldáshoz tartozó sorokat törölni lehet. Vagy csak megjegyzésbe tenni. A fenti sor a "ProxyPassMatch" után írt reguláris kifejezésre illeszkedő fájlokat fogja elküldeni az FPM-nek feldolgozásra a jobb oldalon megadott IP-n és porton.
Az IP-port párosoknak minden pool-ban egyedinek kell lennie és nyilván más alkalmazás sem foglalhatja őket együtt. A virtuális hosztok fájljaihoz hasonlóan adtam meg az IP-t. Azaz a fix 127-es után 0.0.2 következik, ahogy a vhost fájl neve is 002-vel kezdődik. A port pedig az alapértelmezett 9000. Ezt persze ugyanígy lehetne a port változtatásával is megoldani.
A port után a futtatandó fájl útvonalát kell írni a szerver gyökeréhez viszonyítva. Ennek a végén egy $1 található, ami a reguláris kifejezésben levő zárójeles rész behelyettesítését jelenti. Abban pedig a / jelet szándékosan tettem a zárójelen kívülre, mivel az útvonal tartalmazni fogja. A $1 előtti útvonal a virtuális hoszt gyökere, így ahhoz képest keres minden fájlt.
Gyanakodva, hogy mi van, ha "../"-rel könyvtárt váltok az url-ben, kipróbáltam, ki lehet-e szökni a gyökérből. De nem lehet.
A világosság kedvéért megmutatom, nekem hogy néz ki a teljes virtuális hoszt definícióm:
ServerName p5414.a24.vm1
ServerAlias www.p5414.a24.vm1
DocumentRoot "/var/www/vhosts/vm1/a24/p5414/www"
ErrorLog "/var/www/vhosts/vm1/a24/p5414/_logs/error.log"
CustomLog "/var/www/vhosts/vm1/a24/p5414/_logs/access.log" common
php_flag engine off
# mod_cgid -vel
# Action application/x-httpd-php /php/php-5414
# mod_fcgid -vel
# <FilesMatch "\.php$">
# SetHandler fcgid-script
# Options +ExecCGI
# FcgidWrapper /var/www/cgi-bin/php-5414 .php
# </FilesMatch>
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.2:9000/var/www/vhosts/vm1/a24/p5414/www/$1
<Directory "/var/www/vhosts/vm1/a24/p5414/www">
Require all granted
</Directory>
</VirtualHost>
Ha most újraindítjuk a szervert,
A következő hibaüzenet fogad bármely PHP futtatásakor a p5414.a24.vm1 domainen
The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.
Jelzi, hogy a túloldalon az FPM még nem figyel. Így nem tudja lefuttatni a PHP szkripet.
FPM konfiguráció
A telepített PHP könyvtárában van egy "etc" mappa, abban pedig egy "php-fpm.conf.default" nevű fájl. Ez egy alap konfigurációt ad az FPM-hez "ini" szintaktikával. Ahhoz viszont, hogy figyelembe vegye az FPM, át kell másolni php-fpm.conf nevűként egy új fájlba.
Fontos, hogy megmaradjon az eredeti is érintetlenül, ha később vissza kell nyúlni valamiért, amit az élesből már töröltünk. Így NE LECSERÉLJÜK a fájlt, csak másoljuk!
Nem idézem az egész fájlt, mert nagyon hosszú. Viszont a lényeg a következő:
CTRL+W -vel ( nano szövegszerkesztőben ) keressünk rá a [www]
sorra! Ez a pool neve. A hozzá tartozó beállítások ez alatt lesznek. A lényeg számunkra az elején van:
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = nobody
group = nobody
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses on a
; specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = 127.0.0.1:9000
A "user" és "group" az, ahol a php felhasználóját és csoportját megadhatjuk. A "listen" meghatározza az IP-t és a portot, amin figyel. Ez az, amire a szerver beállításban hivatkoztunk. Megjegyzések nélkül a helyes beállítások a következők:
group = web
listen = 127.0.0.2:9000
Most viszont el kell indítani az FPM-et is. A PHP könyvtárában az "sbin" könyvtárban levő "php-fpm" programot kellene lefuttatni. FIGYELEM! Csak KELLENE.
Igen, csak ennyi. Nincs "start" argumentum. Ez okozna is majd gondot, ugyanis a leállításhoz tudni kellene az FPM process azonosítóját. Viszont pid fájl használata nélkül ezt valahogy így lehetne megoldani:
Majd itt a "root" utáni számot, ami a process id-je, felhasználni a következő módon:
Ahol az 1845 nálam az azonosító volt. A PHP fordítása után viszont létrejött egy daemon szkript is, amivel ez leegyszerűsödik. Csak át kell másolnunk a php sbin könyvtárába és futattási jogot kell adni a root usernek hozzá:
chmod 0700 /opt/php/5.4.14/sbin/php-fpmd
Ezek után az indítás így néz ki:
A leállítás pedig:
Vagy újraindítás:
Tehát indítsuk el most az FPM-et és nézzük meg a whoami.php kimenetét! Nálam már "web" -et ír ki. A phpinfo kimenete pedig a ServerAPI mellett már az "FPM/FastCGI"-t mutatja. Remélem, mindenki hasonló sikerrel járt.
Viszont ezt a hatalmas fájlt végigpásztázni minden alkalommal, amikor bele kell nyúlni bármelyik pool-ba, nem egyszerű mulatság. Mivel a default beállítások le vannak mentve, megtehetjük a következőket:
A php-fpm.conf fájl eleje felé van egy ilyen sor:
A pontosvessző a megjegyzés jele. Tehát vegyük ki az elejéről! Ez annyit tesz, hogy az fpm.d könyvtárban beolvassa a pool definíciókat, ahogyan azt a virtuális hosztok leírásánál is hasonlóképpen mutattam. A default "www" pool-ra nem lesz szükség. Így azt teljesen töröljük ki! A törlést "nano" fájlszerkesztővel a [www]
sorára állva lehet megoldani a CTRL+K billentyűkombinációt nyomva tartva, amíg el nem fogynak a sorok.
A php-fpm.conf mellett hozzuk létre az fpm.d mappát:
Majd a pool nevével megegyező névű fájlba mentsük el az első pool leírását! A pool neve legyen a virtuális hoszt neve!
A www lehetett volna a fődomain-, azaz az alap virtuális hoszt pool-ja, de azt megtartjuk arra az esetre, amikor szándékosan a mod_php modullal akarjuk a PHP-t működtetni.
A tartalma pedig:
listen = 127.0.0.2:9000
listen.allowed_clients = 127.0.0.2
user = web
group = web
pm = ondemand
pm.max_children = 5
Rendesen lecsupaszítottam a pool tartalmát. A figyelt IP-port párost tartalmazza, a felhasználót és a csoportot, valamint a "pm" és "pm.max_children" opciókat, amik kötelezőek még.
A "pm" a processzek létrehozásának és megszüntetésének módja. A "pm.max_children" pedig azt mondja meg, hány gyerekfolyamatot indíthat egyszerre maximum.
Az "ondemand" lehetőség a PHP 5.3 óta létezik. A processzeket nem hozza létre előre az induláskor, csak szükség esetén. És ha már nem kellenek, megszünteti őket
Extraként még a "listen.allowed_clients" opcióval megadtam, hogy kizárólag a 127.0.0.2 -es IP-ről fogadjon el az FPM kéréseket. Ez nem feltétlenül egyezik meg a listen után írt IP-vel, de ha 127.x.x.x IP-t választunk, akkor a remote IP is az lesz.
Ha a php.ini beállításait kellene módosítani, azt így lehet:
Végül adjuk át a dokumentum gyökeret és az összes tartalmát a web felhasználónak és csoportjának:
PHP 5.3.24
A beállítások nagyon hasonlók. Virtuális hoszt kiegészítése és új pool létrehozása kell. Valamint az init script másolása.
Virtuális hoszt konfiguráció
A p5324-es aldomainhez tartozó virtuális hoszt definíciót
kiegészítjük a <Directory>
blokk előtt a következő sorral:
Újraindítjuk a szervert.
FPM konfiguráció
Másoljuk a default fájlt:
Kitöröljük a php-fpm.conf következő sora elől a pontosvesszőt.
Töröljük a [www]
sorától a pool teljes tartalmát a CTRL+K billentyűkombináció segítségével.
Létrehozzuk az fpm.d mappát és a pool definíciót:
nano /opt/php/5.3.24/etc/fpm.d/p5324.a24.vm1.conf
A tartalma
listen = 127.0.0.3:9000
listen.allowed_clients = 127.0.0.3
user = web
group = web
pm = ondemand
pm.max_children = 5
Majd másoljuk az init szkriptet:
chmod 0700 /opt/php/5.3.24/sbin/php-fpmd
Majd adjuk át a dokumentum gyökeret és az összes tartalmát a web felhasználónak és csoportjának:
PHP 5.2.17
Virtuális hoszt konfiguráció
Ez még ugyanaz, mint eddig.
A <Directory>
blokk elé beszúrandó sor:
FPM konfiguráció
És most jön a neheze. Ugyanis PHP 5.2-nél még nem létezett beépített FPM. De az FPM készítői gyártottak hozzá egy patch fájlt, ami a PHP forráskódjában változtatandó sorokat tartalmazza. Ennek alkalmazására létezik a "patch" program, tehát kézzel semmit nem kell majd módosítani. A patch fájlt viszont be kell szerezni a http://php-fpm.org/downloads/ oldalról és sajnos újra kell fordítani az 5.2.17-es verziójú PHP-t. Nagy gond nincs, mert például a bemásolt php.ini nem fog eltűnni, tehát csendben újrafordul a PHP és folytatjuk a munkát.
Feltételezve, hogy a php forráskódja már ( vagy még ) ott van a "/opt/php/php-5.2.17" könyvtárban, a következőket kell tenni:
wget http://php-fpm.org/downloads/php-5.2.17-fpm-0.5.14.diff.gz
gunzip php-5.2.17-fpm-0.5.14.diff.gz
patch -p1 < php-5.2.17-fpm-0.5.14.diff
Az utolsó sor a patch alkalmazása. A balra mutató relációs jeltől jobbra a használandó fájl neve. A "-p1" pedig leveszi az első per jelet a fájlok útvonala elől a patch fájlban. Ha belenéznénk, ilyesmiket látnánk, hogy:
+++b/configiure
Az "a" jelöli az eredeti forrást. A "b" pedig a változtatottat. A többi az útvonal. Az "a" és "b" nem zavar semmit. De nekünk csak a "configure" kell "/" nélkül, mert épp a forráskód könyvtárában állunk.
A PHP telepítésénél létrehozott configure szkriptet másoljuk át "conf-php52-fpm" néven.
Írjuk hozzá a lista végére akár, vagy az --enable-fastcgi után, hogy "--enable-fpm"!
Ha a lista végére kerül, akkor az előző sor végére kell egy backslash. Ha korábban szúrjuk be, akkor pedig rögtön utána kell a backslash.
Most pedig újrafordítjuk:
make clean
make
make install
Szembetűnő különbség, hogy nem egy ".default" végű fpm konfigurációs fájl jön létre, hanem rögtön "php-fpm.conf". Ezt rögtön mentsük el default-nak!
A másik szembetűnő, és egyben bosszantó is, hogy itt még nem "ini" szintaktika volt, hanem "xml". Másik konfigurációs fájl include-jára pedig nincs lehetőség. Talán ez kevésbé probléma, mivel ez a PHP verzió már elavult. És csak át nem írható, régi programok futtatására érdemes használni.
A pool definiciója a <section name="pool">
blokkban található. Minden pool ezzel kezdődik és tartalmazza blokkon belül a nevét és annak beállításait is. Ha úgy tetszik, ez a section blokk felel meg egy egyedi fájlnak az előző két PHP verziónál.
Egyetlen ilyen blokk van. Keressük meg és töröljük ki, majd a következőt írjuk a helyére:
<value name="name">p5217.a24.vm1</value>
<value name="listen_address">127.0.0.4:9000</value>
<value name="allowed_clients">127.0.0.4</value>
<value name="user">web</value>
<value name="group">web</value>
<value name="pm">
<value name="style">static</value>
<value name="max_children">5</value>
</value>
<value name="php_defines">
<value name="doc_root">/var/www/vhosts/vm1/a24/p5217/www</value>
<value name="cgi.fix_pathinfo">0</value>
<value name="auto_prepend_file">/var/www/fix_pathinfo.php</value>
</value>
</section>
A fenti sorokhoz egy kis magyarázat. Minden "value" blokkokból áll, amiknek van egy nevük a "name" attribútumban és egy értékük.
- name: A pool neve
- listen_address: Az IP-port páros
- allowed_clients: Azok az IP-k vesszővel elválasztva, ahonnét hajlandó kéréseket fogadni az FPM.
- user és group: A felhasználó és csoport.
- pm: A processzek tulajdonságai.
- style: Mint az előző verzióknál a szimpla "pm" opció. De itt csak "static" és "apache-like" lehet.
- max_children: A max gyermekfolyamatok száma
- php_defines: A PHP beállításai.
- doc_root: Bár a ProxyPassMatch után itt is megadtuk az útvonalát a fájlnak, ezt figyelmen kívül hagyja az 5.2.17-es PHP-hez tartozó FPM. Meg kell adni a doc_root-ot, hogy ahhoz képest az url-ben kért fájlt tudja feldolgozni.
- cgi.fix_pathinfo: Ez az opció a php.ini-ben 1-esre van állítva. Azaz helyreállítja a SCRIPT_FILENAME környezeti változóban az útvonalat. Tehát például nem kerül bele a CGI wrapper útvonala, sem pedig a proxy-ra utaló hivatkozás. Mint jelen esetben megtörténik. Ha viszont ezt bekapcsolva hagyjuk, akkor egyáltalán nem fog működni az FPM.
- auto_prepend_file: Ez egy kis trükk lesz, ugyanis ezzel minden php program előtt lefuttathatunk egy másik PHP szkriptet, ami beállítja a $_SERVER és $_ENV változókban a SCRIPT_FILENAME értékét. Felhasználva azt az útvonalat, amit maga az FPM figyelmen kívül hagy.
Létrehozzuk a fix_pathinfo.php-t
$_SERVER['SCRIPT_FILENAME'] = $_ENV['SCRIPT_FILENAME'] = preg_replace('/^proxy:fcgi:\/\/\d+\.\d+\.\d+\.\d+:\d+(\/.*)/', '$1',$_SERVER['SCRIPT_FILENAME']);
FONTOS, hogy a végére ne tegyünk php záró címkét és a nyitó címke előtt se legyen szóköz, sortörés. Így elkerülhetjük a HTTP fejlécek akadályozását.
Jó hír, hogy ennek a verziónak a php-fpm programja már eleve ismeri a start, stop, restart argumentumokat. Valójában ez a fajta FPM egy kicsit más. Belenézve a szkriptbe, látható, hogy a php-cgi binárissal dolgozik közvetlenül. Ha elindítjuk az FPM-et:
És megnézzük a hozzá tartozó index.php-t, benne a phpinfo kimenetével, a "ServerAPI" továbbra is "CGI/FastCGI" maradt. Viszont a beállítás sikeressége leellenőrizhető azzal, ha rákeresünk az "Environment" -re és, látjuk a "web" user-t és a home könyvtárát.
Végül adjuk át a dokumentum gyökeret és az összes tartalmát a web felhasználónak és csoportjának:
Apache 2.2
Ha az 5.2-es PHP FPM-esítése nehéz volt, akkor ez hasonló lesz. Ugyanis le kell fordítani külön a mod_fastcgi modult is. Amit a www.fastcgi.com oldalról kell letölteni. Utána pedig egy ProxyPassMatch helyett FastCGIExternalServer -t fogunk használni. Ráadásként pedig egy halom nem létező dologra kell hivatkozni a virtuális hoszt beállításánál.
Modulokat viszont mást nem kell engedélyezni.
mod_fastcgi beállítása
wget http://www.fastcgi.com/dist/mod_fastcgi-SNAP-0910052141.tar.gz
tar xf mod_fastcgi-SNAP-0910052141.tar.gz
cd mod_fastcgi-SNAP-0910052141
/opt/apache/2.2/bin/apxs -n fastcgi -o mod_fastcgi.so -i -a -c *.c
Ezzel létre is jön a modul a modules könyvtárban és a httpd.conf -ban is engedélyezve lesz.
A "-o" és az utána levő név elhagyásával az utolsó sorban "fcgi_buf.so" néven jönne létre a modul.
Verziófüggetlen beállítások
És itt jött el a nem létezők ideje. De nézzük sorban. Elvileg a virtuális hosztokban ilyesmit is elég volna írni:
Igen, itt nem IP-t és portot, hanem socketet használunk. Útvonalként pedig a hoszt dokumentum gyökerét adjuk meg, bár más is lehetne, csak hosztonként egyedi legyen.
Az IP-s megoldás is használható volna a "-socket" helyett a "-host" paraméter megadásával. De a 2.4-es szerverben megadott porttal való ütközést el kell kerülni.
FastCGIExternalServer /dokumentumgyökér -host 127.0.0.2:9001
Igen ám, de így az összes fájlra érvényes lesz, hogy az FPM kezelje. Beleértve a html fájlokat is. Az eredménye így a html fájlok esetén egy "Access denied" üzenet lenne a tartalom helyett. Ahogy az fcgid-nél is korlátozni kellett PHP fájlokra az FPM-et, itt is ezt kellene tenni. Viszont A FastCGIExternalServer direktíva nem írható be a FilesMatch blokkba. Ami megnehezíti a megoldást és itt jön valami eszement trükközés.
A httpd.conf végére a következőt kell írni:
<Location "/$">
Order Deny,Allow
Deny from all
Allow from env=REDIRECT_STATUS
</Location>
Action application/x-httpd-php /$
Itt a Location utáni "/$" egy útvonalat jelent, ami nem létezik. Nincs ilyen mappa se fájl. Mégis megmondjuk rá, hogy mindenki számára legyen tiltott a megnyitása webről. Viszont megengedjük, hogy amennyiben létezik egy REDIRECT_STATUS nevű környezeti változó, akkor hozzáférhető legyen. Ez kell a webszervernek.
Ez után egy Action sor következik, ahol egy handler és egy útvonal lenne a paraméter. A handler gyakorlatilag akármi lehetne. "kismacska" is. Csak legyen hozzárendelve a .php kiterjesztésű fájlokhoz. Egy korábbi fejezetben ezt már megtettem. De emlékeztetőül: A fenti "Location" blokk elé még kerüljön be a következő, akinél nincs ott:
SetHandler application/x-httpd-php
</FilesMatch>
Na most az Action utáni útvonal ugyanaz a nem létező útvonal, amit a Location-ben meg kellett adni. Ez is lehetne bármi hamis elérési út. De a dollár jel épp elég valószínűtlen, hogy valós url-ben szerepelne. Márpedig ezt el lehetne érni böngészőből is, ha azt le nem tiltottuk volna épp a Location blokkban.
Valójában az történik, hogy előre hivatkozunk egy nem létező útvonalra, ami valamikor létrejön a virtuális hosztokon. Persze ott is csak virtuálisan. Az Action egy bizonyos handler hatására ( amit itt kiterjesztés alapján állítottunk be ) átadja a kért fájl kezelését egy programnak. Na ez a program lesz az, amit a virtuális hoszton beállítunk. Vagyis elérjük, hogy a rendszer azt lássa, hogy az útvonalon egy program van. Aki még emlékszik a CGI wrapperekre, ott is hasonló történt. De ott a fájlok tényleg léteztek.
PHP 5.4.14
Virtuális hoszt konfiguráció
A <Directory>
blokk elé most elég ennyit írni:
Alias /$ /var/www/vhosts/vm1/a22/p5414/$
FastCGIExternalServer /var/www/vhosts/vm1/a22/p5414/$ -socket /tmp/php-fpm-p5414.a22.vm1.sock
Itt az Alias -szal egy url-t lehet átirányítani egy, a fájlrendszeren levő útvonalra, aminek nem kell a dokumentum gyökérben lennie. Átirányítjuk egy szintén nem létező fájlra. Azért, mert a FastCGIExternalServer virtuálisan elkészíti ezt a fájlt úgy, hogy ezt írjuk első paraméterének. Majd pedig a socket útvonalát. Teljes a káosz. Tudom. De sajnos így működik.
Ez a virtuális program lehetne bármilyen útvonalon, viszont egyedinek kell lennie. Erre pedig pont alkalmas, ha a virtuális egyedi útvonalaihoz kötjük.
Szerver újraindítása
FPM konfiguráció
Az 5.4.14 -es PHP -hez kell még egy pool:
A tartalma
listen = /tmp/php-fpm-$pool.sock
user = web
group = web
pm = ondemand
pm.max_children = 5
Érdekesség, hogy a pool nevét a $pool változóval helyettesítem be a socket fájl nevébe.
Idítsuk újra az 5.4.14-es PHP-hez tartozó FPM-et:
Fájlrendszer felhasználó és csoport beállítása
PHP 5.3.24
Virtuális hoszt konfiguráció
A <Directory>
blokk elé a következő sorok kerülnek:
Alias /$ /var/www/vhosts/vm1/a22/p5324/$
FastCGIExternalServer /var/www/vhosts/vm1/a22/p5324/$ -socket /tmp/php-fpm-p5324.a22.vm1.sock
Szerver újraindítása
FPM konfiguráció
Az 5.3.24 -es PHP -hez kell még egy pool:
A tartalma
listen = /tmp/php-fpm-$pool.sock
user = web
group = web
pm = ondemand
pm.max_children = 5
Az előzőhöz képest tehát csak a pool neve változott.
Indítsuk újra az 5.3.24-es PHP-hez tartozó FPM-et:
Fájlrendszer felhasználó és csoport beállítása:
PHP 5.2.17
Itt most újra az XML-lel kell dolgozni, de a nehezén már túl vagyunk.
Virtuális hoszt konfiguráció
A <Directory>
blokk elé a következő sor kerül:
Alias /$ /var/www/vhosts/vm1/a22/p5324/$
FastCGIExternalServer /var/www/vhosts/vm1/a22/p5324/$ -socket /tmp/php-fpm-p5324.a22.vm1.sock
Szerver újraindítása
FPM konfiguráció
Az 5.2.17 -es PHP -hez kell még egy pool:
Egy új section-t vegyünk fel. Aminek a tartalma:
<value name="name">p5217.a22.vm1</value>
<value name="listen_address">/tmp/php-fpm-p5217.a22.vm1.sock</value>
<value name="user">web</value>
<value name="group">web</value>
<value name="pm">
<value name="style">static</value>
<value name="max_children">5</value>
</value>
</section>
Nem használható a $pool változó, de cserébe nem is kell a php_defines részt megadni. Az FPM működik és a SCRIPT_FILENAME értéke is jó.
Indítsuk újra az 5.2.17-es PHP-hez tartozó FPM-et:
Fájlrendszer felhasználó és csoport beállítása:
Összegzés
Ezzel készen is vagyunk. Van tehát 3 PHP verziónk FPM-mel meghajtva, 2 Apache HTTPD webszerverrel mögöttük. A webszervereket eddig is könnyen indítottuk és állítottuk le, a PHP 5.3 és PHP 5.4 -es FPM-hez viszont a forráskönyvtárból átmásolhattuk az indító szkriptet. PHP 5.2-höz erre nem volt szükség, de az IP-port-os megoldásnál a Proxy modullal külön kellett gondoskodni a SCRIPT_FILENAME változó helyességéről.
Nyilván még ez is lehetne szebb és könnyebben kezelhető, hiszen most minden programot ( PHP, Apache, MySQL ) külön kell elindítani. Ezek kezelése viszont nem ennek a fejezetnek a témája. Később azonban szó lesz róla.
Bár a felhasználót és csoportot beállítottuk, a fájlok jogosultságait nem módosítottuk. Így az olvasási jog megmaradt a PHP fájlokra más felhasználók számára is. Tesztkörnyezetben ez nem különösebben probléma, de éles helyzetben már az. Viszont a lehetőség már megvan az olvasási jog megvonására. Illetve chroot alkalmazásával fájljogok nélkül kivédhető ez a probléma.
Bár most mindegyik virtuális hoszt a web felhasználó tulajdonában van, ez igény szerint különböző is lehetne. A pool definícióban kell megváltoztatni a felhasználót és csoportot, valamint a fájlrendszeri tulajdonosi viszonyról kell gondoskodni.
Végül mentsük el a virtuális gépet "wtk-vm1-v8-fpm" néven. v8, mert már több, mint a sima cgi megoldások, de az fpm-et még mögé írhatjuk, hogy mégis beszédesebb legyen a fájlnév. Hiszen ez egy nagyobb állomása a tesztkörnyezet elkészítésének.
Források
- Building mod_fastcgi For Apache 2
- PHP Manual: FastCGI Process Manager (FPM), hozzászólás
- Bug #24614 php as cgi always report 'No input file specified.'
- Alkalmazásonkénti chroot PHP-FPM-mel (Pásztor János)
- High-performance PHP on apache httpd 2.4.x using mod_proxy_fcgi and php-fpm.
- Module mod_fastcgi
- PHP FPM wiki: Documentation
- Re: here is an example of config for php-fpm, apache, mod_fastcgi, and a virtual host (forum.nginx.com)
Hozzászólások
Köszönöm szépen!
Ez egy nagyon hasznos és átfogó leírás, nekem nagyon sokat segített! Köszönöm a munkádat vele!
Köszönöm a visszajelzést!
Köszönöm a visszajelzést! Örülök, hogy segítettem.
php 5.6 +php 7 FPM beállítás
próbáltam a leírások alapján a php 5.6.15 és a legújabb php 7.0.0RC8 verziót telepíteni
5.6 ppa-ból, 7.0 tar.gz forrásból, az 5.6 működik, de a 7.0.0 -val nem tudom működésre bírni, ebben kellene segítség,
köszönöm!
a teljes kívánt konfig: /apache 2.4.17 +php 5.6.15 (FPM, PDO_mysql) + php 7.0.0 (FPM, PDO_mysql) + MySQL5.6]/ (a mysql-le és phpmyadminnal való összehangolás se tiszta :/ )
Részletek
Üdv. Ha adsz több infót arról, hogy meddig jutottál, mit jelent, hogy nem tudtad működésre bírni, hibaüzenet volt-e, stb, akkor talán tudok segíteni.
http://pastebin.com/Nzgfri74
http://pastebin.com/Nzgfri74
a php7.0.0-t ez alapján
a php7.0.0-t ez alapján telepítettem:
https://www.howtoforge.com/tutorial/install-php-7-on-debian-8-jessie/
a libjpeg62-turbo-dbg nem lett telepítve, mert nem találta
a
pid = run/php-fpm.pid
helyett
pid = run/php7-fpm.pid
-t állítottam be, hogy egyértelműbb legyen
listen = 127.0.0.1:8999 helyett:
listen = 127.0.0.2:8999
insserv php-7.0.0-fpm ( insserv: parancs nem található)
systemctl daemon-reload ( systemctl: parancs nem található)
$ sudo service apache2 restart && sudo service php5-fpm stop && sudo service php-7.0.0-fpm start
[sudo] password for adam:
* Restarting web server apache2 [ OK ]
php5-fpm stop/waiting
Starting php-fpm ................................... failed
Ránézek majd később. Most
Ránézek majd később. Most nincs időm, de addig esetleg próbáld meg megtalálni, hova logol az fpm ilyenkor, ha nem tud elindulni. Vagy hogy indítható úgy, hogy kiírja az okát. Mintha lenne valami kapcsoló. De nem vagyok benne biztos.
ez a vonal már tárgytalan...
ez a vonal már tárgytalan, elkezdtem nulláról az egészet a leírások alapján:
http://rimelek.hu/webtesztkornyezet/apache-telepitese
http://rimelek.hu/webtesztkornyezet/mysql-telepitese
http://rimelek.hu/webtesztkornyezet/php-telepitese
apache gond nélkül indul mindkettő (párhuzamosan is)
php5.6 és php7 is indul külön-külön modulként (apache 2.4-ben)
mysql is megy
az FPM beállítással viszont gondok vannak:
mindent beállítottam ahogy kell (szerintem), de mikor indítanám a php-fpm-et akkor hibával leáll:
# /opt/apache/2.4/bin/apache24 -k start
# /opt/php/5.6.16/sbin/php-fpmd start
Starting php-fpm [01-Dec-2015 22:24:28] ERROR: [pool www] unable to set listen address as it's already used in another pool 'p5616_test.a24.home'
[01-Dec-2015 22:24:28] ERROR: failed to post process the configuration
[01-Dec-2015 22:24:28] ERROR: FPM initialization failed
failed
ugyanennyit ír be az error.log-ba is + mindenhol a php Apache modulként
a beállítások:
http://pastebin.com/q9ZvcQ6w
http://pastebin.com/38RgLFsL
http://pastebin.com/wi4k3C5W
Minden FPM pool-nak különböző
Minden FPM pool-nak különböző IP-port kombinációt kell beállítani. Nem figyelhet a www és a p5616_test.a24.home is ugyanazon az ip-n, ugyanazon a porton.
Nálad a php-fpm.conf-ban is be van állítva egy pool. Én a példában kiszedtem abból a fájlból az alapbeállítást és csak a külön fájlokban voltak beállítva fpm pool-ok az etc/fpm.d mappában.
már közel a cél, de...
már közel a cél, de még mindig nem tökéletes:
apache 2.4.17 + php 5.6.16 FPM gond nélkül megy
apache 2.2.31 + php 5.6.16 FPM (mod_fastcgi befordítva) -> Error 500
apache 2.2 mod_fcgid php-vel működött, FPM-el már nem
konfig:
mod_fcgid(ezzel megy): http://pastebin.com/k48bhsCp
fpm (error 500): http://pastebin.com/w0KUkLsh
+ még egy cikk hiba (http://rimelek.hu/webtesztkornyezet/apache-php-cgi/fpm):
A PHP-nek nincs hozzá joga. Jó, akkor adjuk át a tulajdoni jogot a mappára a daemon felhasználónak!
chmod daemon:daemon /var/www/vhosts/vm1/a24/p5414/www/
> "chown -R" kell a "chmod" helyett!
Köszönöm a hibajelentéseket!
Köszönöm a hibajelentéseket! Hm... Lehet, te vagy az első, aki végigolvassa. Javítottam.
Az 500-as hiba megfejtéséhez viszont kellene a hiba oka. A szerver logban valószínűleg jobban részletezi, hogy mi okozta az 500-as hibát. Sajnos annyira nem megy fejből a dolog, hogy config alapján kiszúrjam mindig a problémát.
virtualhost (apache 2.2)
virtualhost (apache 2.2) error_log: http://pastebin.com/DWwv00qN
apache 2.2 error_log vége (a teljes több, mint 24ezer sor - lehet nem ártana próbálkozás közben néha ránézni :) )
http://pastebin.com/XsahsFx3
php-fpm log-ban semmi hiba nincs
Nem biztos, csak gyanú, de én
Nem biztos, csak gyanú, de én a példáimban nem a document root-ban definiáltam a virtuális útvonalat, hanem azon kívül, a www mappa mellett. Neked a public a documentroot-od és a public-ban van a dollár útvonal is definiálva. Mikor bejön egy kérés, amit a szerver a php-nek ad át, akkor a (domain)/$ -ra irányítja át, ami viszont a docroot-on belül van és oda lett definiálva a virtuális fájl is a dollárral.
Így próbáld:
FastCGIExternalServer /opt/www/vhost/teszt/$ -socket /tmp/php-fpm-teszt.localhost22.home.sock
külön van:
külön van:
a22 docroot: /opt/www/a22/public
a24 docroot: /opt/www/a24/public
vhost: /opt/www/vhost/...
de kis keresés után meg van a megoldás:
a virtualhost pool konfigba hozzá kell adni a következő 3 sort és működik :)
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
most már csak a phpMyAdmin-t
most már csak a phpMyAdmin-t kellene beilleszteni a rendszerbe, hogy mindegyikkel működjön (ja még a php 7 nincs telepítve, de szerintem túlságos különbség nem lesz a konfigban az 5.6-hoz képest :) )