Trumpai: SAPI reiškia Server Application Programming Interface, t. y. sąsają, per kurią PHP bendrauja su savo aplinka. Tipinės SAPI yra fpm-fcgi (PHP-FPM), apache2handler (mod_php), cgi-fcgi (php-cgi), litespeed ir cli komandinei eilutei. SAPI lemia, kaip ateina užklausos, kuris php.ini galioja ir kuriuos procesus po atnaujinimo reikia paleisti iš naujo. Esant PHP2Shell nuo jos priklauso net rizikos įvertinimas.
Kas yra SAPI?
PHP pats yra programa, kuri vykdo kodą. Kad galėtų pateikti tinklalapius, jam reikia ryšio su žiniatinklio serveriu, komandine eilute ar kita programa. Šis ryšys ir yra SAPI. Ji priima užklausos duomenis, perduoda juos Zend Engine ir grąžina išvestį.
SAPI galima įsivaizduoti kaip kištuką: variklis lieka tas pats, bet priklausomai nuo kištuko jis tinka Apache, Nginx per FastCGI, LiteSpeed ar terminalui. Kiekvienas variantas turi savo stipriąsias puses, savus konfigūravimo kelius ir savas spąstus.
SAPI daugiausia nulemia tris kasdienybėje svarbius dalykus:
- Procesų modelis: ar PHP veikia žiniatinklio serveryje, kaip atskira tarnyba su nuolatiniais darbiniais procesais (worker), ar kaip trumpalaikis procesas kiekvienam iškvietimui?
- Konfigūracija: kuris php.ini skaitomas ir kur gali būti papildomi nustatymai, pavyzdžiui,
.htaccess,.user.iniar FPM baseine? - Teisės ir atskyrimas: kokiu naudotoju vykdomas kodas ir ar galima atskirti kelias svetaines viena nuo kitos?
Hostingo valdymo skydeliuose SAPI pasirodo kitais pavadinimais. Pavyzdžiui, Plesk kalba apie PHP tvarkykles, tokias kaip „FPM application“, „FastCGI application“ ar „Apache module“. Turimi omenyje tie patys veikimo režimai, kuriuos aprašo šis puslapis. Abejojant padeda toliau pateiktas patikros failas, rodantis tikrąjį SAPI pavadinimą.
Kokios yra PHP SAPI?
PHP vadove php_sapi_name() grąžinamos reikšmės, be kita ko, yra šios: apache, apache2handler, cgi (iki PHP 5.3), cgi-fcgi, cli, cli-server, embed, fpm-fcgi, litespeed ir phpdbg. Sąrašas aiškiai nėra baigtinis.
| SAPI pavadinimas | Veikimo režimas | Tipinis naudojimas | Procesų modelis |
|---|---|---|---|
fpm-fcgi |
PHP-FPM | Nginx, Apache su proxy_fcgi, hostingo skydeliai |
atskira tarnyba su darbinių procesų baseinais |
apache2handler |
mod_php | senesni Apache serveriai, paprasti Docker atvaizdai | PHP Apache procese |
cgi-fcgi |
php-cgi | senos sąrankos, kai kurios Windows sąrankos | procesas kiekvienai užklausai arba FastCGI |
litespeed |
LSAPI | LiteSpeed žiniatinklio serveris, daug bendrinamo hostingo teikėjų | savi PHP procesai |
cli |
komandinė eilutė | cron užduotys, Composer, priežiūros skriptai | vienas procesas kiekvienam iškvietimui |
cli-server |
įtaisytasis žiniatinklio serveris | tik vietinė kūryba (php -S) |
vienas kūrimo serveris |
embed |
įterptasis | PHP kitose programose | priklauso nuo programos |
phpdbg |
derintuvas | klaidų paieška | interaktyvus |
FrankenPHP yra šiuolaikinis programų serveris, kuris PHP įterpia tiesiogiai. Jį taip pat veikia PHP2Shell ir jis turi savus atnaujinimo kelius; išsamiau skyriuje FrankenPHP apsauga.
Kaip patikrinti savo serverio SAPI
Svetainės SAPI sužinosite tik per žiniatinklio serverį, o ne per komandinę eilutę. Pakanka mažo patikros failo:
<?php
// sapi-check.php: po iškvietimo iškart vėl ištrinkite
header('Content-Type: text/plain');
echo PHP_SAPI, "\n", PHP_VERSION, "\n", php_ini_loaded_file(), "\n";
Komandinėje eilutėje įdiegtus variantus ir tarnybas galima surinkti tik skaitant:
php -r 'echo PHP_SAPI, PHP_EOL;' # visada "cli"
ls /usr/sbin/php-fpm* 2>/dev/null # įdiegtos FPM versijos
systemctl list-units --type=service | grep -i -E "php|lsws|apache2|httpd"
apachectl -M 2>/dev/null | grep -i php # ar įkeltas mod_php?
Kodėl kiekviena SAPI gali turėti savo php.ini
Pasak PHP vadovo, PHP pirmiausia ieško failo php-SAPI.ini, pavyzdžiui, php-cli.ini, ir tik po to php.ini. Distribucijos, tokios kaip Debian ir Ubuntu, eina toliau ir kiekvienai SAPI sukuria savus aplankus, pavyzdžiui, /etc/php/8.3/fpm/ ir /etc/php/8.3/cli/.
Skiriasi ir laikas: serverio moduliams PHP, pasak vadovo, konfigūraciją nuskaito tik vieną kartą paleidžiant žiniatinklio serverį, o CGI ir CLI atveju per kiekvieną iškvietimą. Todėl kas keičia nustatymą, turi žinoti, kuri SAPI paveikta. Daugiau skyriuje php.ini paaiškinta.
SAPI ir saugumas: ką parodė PHP2Shell
Pasak pranešimų, PHP2Shell paveikti PHP-FPM, Apache su mod_php, php-cgi, FrankenPHP ir LiteSpeed. PHP komanda didžiausią riziką priskiria mod_php, nes ten parodytas exploit dar prieš pradedant vykdyti programos kodą. Priežastys aprašytos skyriuje Kodėl mod_php kelia didžiausią riziką.
Eksploatavimui SAPI visų pirma reiškia vieną dalyką: ji nusprendžia, ką po atnaujinimo reikia paleisti iš naujo.
- PHP-FPM: visi kiekvienos įdiegtos versijos baseinai ir darbiniai procesai
- mod_php: visa Apache tarnyba, ne tik perkrovimas (reload)
- php-cgi ir FastCGI sąrankos: visi likę PHP procesai
- LiteSpeed: žiniatinklio serverio PHP procesai pagal teikėjo instrukciją
- CLI: nuolatinių procesų nėra, bet paketą atnaujinkite, kad patikros rodytų teisingai
Vidutiniu laikotarpiu verta atsisakyti mod_php. PHP vadovas naujiems Apache diegimams rekomenduoja PHP-FPM su mod_proxy_fcgi. Pagrindus aprašo PHP-FPM paaiškinta.
Kaip PHP SOS padeda konkrečiai?
- SAPI surinkimas: kiekvienam serveriui nustatome, kokie veikimo režimai ir PHP versijos iš tikrųjų aktyvūs.
- Teisingas paleidimas iš naujo: per PHP pataisų paslaugą atnaujiname kiekvieną SAPI ir įrodome, kad visi procesai paleisti iš naujo.
- Konfigūracijos priskyrimas: parodome, kurie php.ini ir baseino nustatymai galioja jūsų svetainei.
- Perėjimo planavimas: kur veikia mod_php ar php-cgi, planuojame ir išbandome perėjimą prie PHP-FPM.
Dažni klausimai
Kaip sužinoti, kokią SAPI naudoja mano svetainė?
Patikimiausia trumpam patalpintu patikros failu, kuris išveda PHP_SAPI arba php_sapi_name(), iškviestu per žiniatinklio serverį. Komandinėje eilutėje visada gausite cli, o tai nieko nesako apie svetainę. Po to patikros failą iškart ištrinkite.
Kuri SAPI saugiausia?
Nė viena nėra saugi pati savaime. Tačiau PHP-FPM turi daugiausia atskyrimo priemonių: atskirus baseinus, naudotojus ir užrakintus nustatymus kiekvienai svetainei. PHP vadovas naujiems Apache diegimams aiškiai pataria PHP-FPM, o ne mod_php.
Ar PHP2Shell paveikta komandinės eilutės PHP versija?
Žinomuose pranešimuose minimi PHP-FPM, mod_php, php-cgi, FrankenPHP ir LiteSpeed. CLI neapdoroja užklausų iš tinklo. Tačiau ji dažniausiai ateina iš to paties paketų šaltinio ir visada turėtų būti atnaujinama, jau vien todėl, kad patikros komandos rodytų teisingą būseną.
Ar serveris gali vienu metu naudoti kelias SAPI?
Taip, tai netgi įprasta. Beveik kiekvienas serveris greta žiniatinklio SAPI turi CLI cron užduotims ir priežiūrai. Dažnai papildomai lygiagrečiai veikia kelios PHP-FPM versijos. Kiekviena iš jų turi būti atnaujinama ir paleidžiama iš naujo atskirai.