Trumpai: Administratoriams be kūrėjo patirties saugiam PHP eksploatavimui pakanka penkių pagrindų: PHP sudaro kelios programos (komandinė eilutė, PHP-FPM, Apache modulis), kiekviena su sava versija; nustatymai veikia lygmenimis nuo php.ini iki programos; PHP-FPM užklausas paskirsto darbiniams procesams (worker) baseinuose; atnaujinimas pradeda veikti tik paleidus iš naujo visus procesus; o žurnalai yra svarbiausias ženklas, kai kas nors neteisinga. Kas šiuos punktus žino, tokias spragas kaip PHP2Shell gali uždaryti greitai ir įrodomai.
Iš ko PHP sudarytas serveryje
PHP nėra viena programa. Tipiniame Linux serveryje yra keli variantai, kurie prijungiami per serverio sąsają (SAPI):
| Variantas | Tipinis pavadinimas | Kam skirta |
|---|---|---|
| Komandinė eilutė (CLI) | php, php8.3 |
cron užduotys, Composer, priežiūros skriptai |
| PHP-FPM | php-fpm, php-fpm8.3 |
žiniatinklio užklausos už Nginx ar Apache |
| Apache modulis | mod_php, libphp |
žiniatinklio užklausos tiesiai Apache procese |
| CGI | php-cgi |
senesnės sandaros |
Kiekvienas variantas gali turėti kitą versiją ir kitą php.ini. Daugelyje serverių lygiagrečiai veikia ir kelios PHP versijos, pavyzdžiui, 8.2 ir 8.4. Atnaujinant kiekvieną reikia vertinti atskirai. Kaip veikia sąsajos, paaiškina PHP-FPM paaiškintas.
Kuris variantas iš tikrųjų aptarnauja jūsų svetaines, sužinosite iš veikiančių procesų ir žiniatinklio serverio konfigūracijos:
ps -eo pid,user,lstart,cmd | grep -E "php|httpd|apache2" | grep -v grep
apachectl -M 2>/dev/null | grep -i php # ar Apache įkelia PHP modulį?
ls /run/php/ 2>/dev/null # FPM lizdai (sockets), dažnai kiekvienai versijai ir baseinui
Stulpelis su paleidimo laiku vėliau svarbus paleidžiant iš naujo: visi PHP procesai turi būti paleisti po atnaujinimo laiko. Jei procesai veikia su skirtingais naudotojais, tai rodo atskirus baseinus, o tai gerai. Jei Apache rodomas PHP modulis, nors visos svetainės turėtų veikti per FPM, tai ženklas, kad liko senas paveldas, kurį reikia pašalinti. Hostingo sąsajoms, tokioms kaip Plesk ar cPanel, galioja tas pats principas, tik sąsaja kiekvienai svetainei rodo versijas ir tvarkykles; vis dėlto lemia tai, kas iš tikrųjų veikia kaip procesas.
Svarbiausios komandos administratoriams
php -v # komandinės eilutės versija
php --ini # įkeltas php.ini ir papildomai skaitomi katalogai
php --ini=diff # nuo PHP 8.5: nukrypimai nuo numatytųjų
php -m # sukompiliuoti ir įkelti moduliai
php --ri session # plėtinio nustatymai
php -l datei.php # sintaksės patikra nevykdant
php-fpm8.3 -v # FPM vykdomojo failo versija (pavadinimas priklauso nuo distribucijos)
php-fpm8.3 -t # FPM konfigūracijos testas be paleidimo iš naujo
systemctl status php8.3-fpm
Dvi vadovo pastabos: php -l randa sintaksės klaidas, bet ne klaidas, kurios atsiranda tik vykdant. O php -i iškviečia phpinfo(); išvestis neturi būti viešuose failuose žiniatinklio kataloge.
Kaip veikia PHP nustatymai
Nustatymą galima nurodyti keliose vietose. Kas ką kur gali keisti, nustato kiekvienos direktyvos keitimo režimas:
- php.ini ir conf.d: bazinė konfigūracija kiekvienam variantui, skaitoma paleidžiant.
- FPM baseinas:
php_valueirphp_admin_valuekiekvienam baseinui. Suphp_admin_valuenustatytų reikšmių programa, pasak vadovo, suini_set()perrašyti negali. - Katalogo lygis:
.user.inisu FPM arba.htaccesssu mod_php, tik direktyvoms su režimuINI_PERDIRarINI_ALL. - Programa:
ini_set()vykdymo metu, tik direktyvoms su režimuINI_ALL.
Pavyzdys: memory_limit turi režimą INI_ALL, taigi programa jį gali pakeisti. post_max_size turi INI_PERDIR ir su ini_set() jo pakeisti negalima. Todėl php.net per PHP2Shell pereinamąsias priemones reikalauja reikšmes nustatyti taip, kad programos jų negalėtų perrašyti. Išsamiau apie lygius paaiškina php.ini paaiškintas.
PHP-FPM baseinai trumpai
Baseinas yra darbinių procesų grupė su savu naudotoju, savu lizdu ir savais nustatymais. Svarbiausios direktyvos pagal vadovą:
[shop]
user = shop
group = shop
listen = /run/php/shop.sock
pm = dynamic ; static, dynamic arba ondemand
pm.max_children = 20 ; daugiausia 20 vienu metu vykdomų užklausų
pm.max_requests = 500 ; darbinį procesą atnaujinti po 500 užklausų
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/shop-slow.log
php_admin_value[error_log] = /var/log/php-fpm/shop-error.log
php_admin_flag[log_errors] = on
Atskiras baseinas kiekvienai svetainei su savu naudotoju atskiria svetaines viena nuo kitos. security.limit_extensions pagal numatymą nustatytas į .php .phar ir neleidžia FPM vykdyti kitų nei PHP failų plėtinių. clear_env pagal numatymą įjungtas ir neleidžia aplinkos kintamųjų patekti pas darbinį procesą.
Žurnalai: kur žiūrėti administratoriams
PHP klaidas rašo į tikslą, nustatytą per error_log, PHP-FPM papildomai į savo žurnalą, o lėtas užklausas į slowlog su atgaliniu sekimu (backtrace). Be to, yra žiniatinklio serverio prieigos ir klaidų žurnalai. Pasirūpinkite, kad produkcijoje display_errors būtų išjungtas, o log_errors įjungtas: klaidos turi būti žurnale, o ne tinklalapyje. Žurnalai taip pat turėtų būti rotuojami ir saugomi nustatytą laikotarpį, kad kritiniu atveju vis dar egzistuotų. Po PHP2Shell specializuota spauda pataria saugoti serverio žurnalus nuo 2026-10-20. Stiprus įspėjamasis ženklas yra PHP-FPM ar žiniatinklio serverio procesas, paleidžiantis shell; kaip tai atpažinti, aprašyta Įspėjamasis ženklas: žiniatinklio serveris paleidžia shell.
Administratoriaus patikros sąrašas po PHP2Shell
- Išvardyti visus PHP variantus ir versijas serveryje, taip pat nenaudojamus.
- Patikrinti paketo būseną; esant distribucijos backport, paketo pakeitimų žurnale ieškoti CVE-2026-109618 ir CVE-2026-109619.
- Atnaujinti iki 8.5.12, 8.4.27, 8.3.36 ar 8.2.35 arba patvirtinto backport.
- Paleisti iš naujo PHP-FPM, Apache ir LiteSpeed ir patikrinti procesų paleidimo laikus.
- Kontrolinis bandymas su
php -r 'var_dump(ini_get("memory_hard_limit_percent"));';bool(false), pasak vadovo, reiškia paveiktą versiją. - Išsaugoti žurnalus ir patikrinti dėl neįprastumų.
Kaip patikimai įrodyti versiją ir pataisų būseną, aprašyta Kaip teisingai patikrinti PHP versiją ir pataisų būseną.
Kaip PHP SOS padeda konkrečiai?
Pagal saugumo priežiūros sutartį PHP pagrindinę priežiūrą perimame kartu su jūsų komanda:
- Inventorius: visi PHP variantai, versijos, baseinai ir konfigūracijos vietos kiekviename serveryje.
- Konfigūracija: saugumui svarbios reikšmės nustatytos su
php_admin_value, baseinai kiekvienai svetainei atskirti. - Atnaujinimai: įdiegimas, paleidimas iš naujo, kontrolė ir dokumentavimas per kiekvieną saugumo leidimą.
- Perduoti žinias: paaiškiname jūsų administratoriams, ką pakeitėme ir kodėl.
Dažni klausimai
Kodėl php -v rodo kitą versiją nei svetainė?
Komandinė eilutė, PHP-FPM ir Apache modulis yra atskiros programos su sava versija ir savu php.ini. php -v rodo tik komandinę eilutę. Svetainei svarbi vykdomojo failo, kuris iš tikrųjų apdoroja užklausas, versija.
Koks php.ini galioja mano serveryje?
Tai parodo php --ini komandinei eilutei. PHP-FPM dažniausiai turi savo php.ini ir papildomus baseinų failus. Nuo PHP 8.5 php --ini=diff parodo, kurios reikšmės nukrypsta nuo numatytųjų.
Kuo skiriasi php_value ir php_admin_value?
Abu nustato parametrus FPM baseine. Pasak vadovo, reikšmių, nustatytų su php_admin_value, programa su ini_set() perrašyti negali. Saugumui svarbiems nustatymams todėl tinka php_admin_value.
Ar pakanka atnaujinimo be paleidimo iš naujo?
Ne. Veikiantys PHP procesai laiko seną kodą atmintyje. Po atnaujinimo PHP-FPM, Apache su mod_php ar LiteSpeed reikia paleisti iš naujo, antraip toliau veikia pažeidžiama versija.