# PHP-FPM paaiškinta: procesų valdytojas, baseinai ir darbiniai procesai

> PHP-FPM paaiškinta: kaip veikia master, baseinai (pool) ir darbiniai procesai, ką reiškia pm static, dynamic ir ondemand ir kurie baseino nustatymai didina saugumą.

Šaltinis: https://phpsos.de/lt/php/php-fpm-erklaert/  
Būsena: 2026-10-25  
Teikėjas: PHP SOS, PHP avarinė pagalba ir serverio sauga. Skubi pagalba per „WhatsApp“: https://wa.me/491736494914?text=Sveiki%2C%20PHP%20SOS%2C%20mums%20reikia%20pagalbos%20su%20m%C5%ABs%C5%B3%20PHP%20serveriu.%20%C4%AEmon%C4%97%3A%20%E2%80%A6%20Svetain%C4%97%3A%20%E2%80%A6

**Trumpai:** PHP-FPM (FastCGI Process Manager) paleidžia PHP kaip atskirą tarnybą šalia žiniatinklio serverio. Master procesas valdo baseinus (pool), o kiekvienas baseinas paleidžia darbinius procesus (worker), kurie apdoroja užklausas per FastCGI. Baseinus galima eksploatuoti kiekvienai svetainei su savu naudotoju, savomis ribomis ir užrakintais PHP nustatymais. Kadangi darbiniai procesai nuosekliai apdoroja daug užklausų, po PHP atnaujinimo juos visus reikia paleisti iš naujo.

## Kas yra PHP-FPM?

PHP vadovas FPM apibūdina kaip pagrindinį PHP FastCGI įgyvendinimą su funkcijomis, naudingomis visų pirma labai apkrautoms svetainėms. FPM į PHP įtrauktas su PHP 5.3.3 kaip atskira SAPI, t. y. atskiras veikimo režimas. Jo SAPI pavadinimas yra `fpm-fcgi`.

Skirtumas nuo mod_php: PHP veikia ne žiniatinklio serveryje, o kaip atskira tarnyba. Nginx, Apache ar kitas žiniatinklio serveris PHP užklausas perduoda per FastCGI protokolą ir gauna paruoštą atsakymą. Todėl žiniatinklio serverį ir PHP galima nepriklausomai paleisti iš naujo, konfigūruoti ir apsaugoti. Kaip iš esmės veikia FastCGI, aprašyta skyriuje [CGI ir FastCGI](https://phpsos.de/lt/php/cgi-und-fastcgi/).

## Master, baseinai ir darbiniai procesai: procesų modelis

PHP-FPM turi tris lygius:

1. **Master procesas:** skaito konfigūraciją, atidaro lizdus (sockets) ir paleidžia arba baigia darbinius procesus. Pats programos kodo nevykdo.
2. **Baseinai (pool):** kiekvienas baseinas turi pavadinimą, savą lizdą ar prievadą, savą Unix naudotoją ir savus PHP nustatymus. Vadove aiškiai minimi skirtingi uid, gid, chroot, aplinka ir php.ini kiekvienam baseinui.
3. **Darbiniai procesai (worker):** baseino procesai, kurie priima ir vykdo užklausas. Darbinis procesas prieš pakeičiamas nuosekliai apdoroja daug užklausų.

Kiek darbinių procesų veikia, nustato procesų valdytojas direktyva `pm`:

| Režimas | Elgsena | Svarbios direktyvos |
|---|---|---|
| `static` | fiksuotas darbinių procesų skaičius | `pm.max_children` |
| `dynamic` | darbiniai procesai tarp apatinės ir viršutinės ribos | `pm.start_servers`, `pm.min_spare_servers`, `pm.max_spare_servers` |
| `ondemand` | darbiniai procesai tik pagal poreikį, nutraukiami po tuščios eigos | `pm.process_idle_timeout` (numatytoji 10s) |

`pm.max_children` visais režimais riboja vienu metu apdorojamų užklausų skaičių. `pm.max_requests` pakeičia darbinį procesą po nustatyto užklausų skaičiaus; numatytoji 0 reiškia neribota.

Kuris režimas tinka, priklauso nuo apkrovos. `static` visada laiko paruoštą vienodą skaičių darbinių procesų ir tinka tolygiai intensyviai naudojamoms programoms, kai pakanka operatyviosios atminties. `dynamic` yra kompromisas daugumai svetainių. `ondemand` taupo atmintį serveriuose su daug mažų svetainių, nes baseinai be lankytojų darbinių procesų neužima; užtat pirmoji užklausa po pertraukos trunka kiek ilgiau. Per aukštai nustatytas `pm.max_children` apkrovos pikų metu gali nustumti serverį į atminties stygių, per žemas sukelia laukimo laiką ir žiniatinklio serverio klaidų pranešimus.

## Baseinas su saugiais pagrindiniais nustatymais

Pavyzdys, kaip sukurti atskirą baseiną kiekvienai svetainei, su direktyvomis iš PHP vadovo. Keliai ir reikšmės yra pavyzdžiai:

```ini
; /etc/php/8.3/fpm/pool.d/kunde-a.conf
[kunde-a]
user = kunde-a
group = kunde-a

listen = /run/php/kunde-a.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s

request_terminate_timeout = 60s
security.limit_extensions = .php
clear_env = yes

php_admin_value[open_basedir] = /var/www/kunde-a:/tmp
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[error_log] = /var/log/php/kunde-a.error.log
```

Pasak vadovo, reikšmes, nustatytas per `php_value` ir `php_flag`, vykdymo metu galima keisti per `ini_set()`, o reikšmių per `php_admin_value` ir `php_admin_flag` negalima. `security.limit_extensions` pagal numatymą yra `.php .phar` ir nustato, kokius failų plėtinius FPM vykdo kaip pagrindinį skriptą. `clear_env = yes` yra numatytoji reikšmė ir išvalo darbinių procesų aplinką.

Stebėsenai yra būsenos puslapis per `pm.status_path` ir ping puslapis per `ping.path`. Abu turėtų būti pasiekiami tik viduje. Lėtas užklausas FPM registruoja su atgaliniu sekimu (backtrace), kai nustatyti `request_slowlog_timeout` ir `slowlog`.

> **Svarbu:**
> PHP vadovas įspėja: kas gali atidaryti FastCGI ryšį su PHP-FPM, tas valdo užklausos konfigūraciją ir taip gali vykdyti bet kokį kodą. PHP-FPM niekada neturi būti pasiekiamas iš nepatikimo tinklo. Naudokite Unix lizdą arba `listen.allowed_clients`.

## Koks PHP-FPM vaidmuo esant PHP2Shell?

PHP-FPM priklauso paveiktiems veikimo režimams. Procesų modelis ypač aiškiai matomas esant CVE-2026-109619: prie užklausos priklausanti vidinė būsena gali išlikti atlaisvinus atmintį, ir vėlesnė užklausa tame pačiame darbiniame procese gali ją panaudoti, kol ji dar neatstatyta. Tai įmanoma tik todėl, kad darbiniai procesai nuosekliai apdoroja daug užklausų.

Iš to kyla trys pareigos:

1. **Įdiegti atnaujinimą:** PHP 8.5.12, 8.4.27, 8.3.36 ar 8.2.35 arba patvirtintas distribucijos backport.
2. **Iš naujo paleisti visus darbinius procesus:** nauji failai diske nieko nekeičia, kol veikia seni darbiniai procesai. Tai galioja kiekvienai įdiegtai FPM versijai ir kiekvienam baseinui. Komandos pateiktos skyriuje [PHP-FPM ir visų darbinių procesų paleidimas iš naujo](https://phpsos.de/lt/php2shell/php-fpm-neustart/).
3. **Pereinamąsias reikšmes nustatyti užrakintas:** php.net priemonės, pavyzdžiui, `session.upload_progress.enabled=0`, per `php_admin_value` ar `php_admin_flag` priklauso baseinui, o ne `.user.ini`.

Atskyrimas baseinais atnaujinimo neatstoja, bet riboja žalą: jei kiekviena svetainė veikia su savu naudotoju, užpuolikas po įsilaužimo automatiškai nepasiekia kitų failų. Kaip tai atrodo konkrečiai, aprašo [PHP-FPM baseinų atskyrimas kiekvienai svetainei](https://phpsos.de/lt/blog/php-fpm-pools-isolieren/); integracija su Nginx aprašyta skyriuje [Nginx su PHP-FPM apsauga](https://phpsos.de/lt/server/nginx-php-fpm/).

## Kaip PHP SOS padeda konkrečiai?

- **Baseinų surinkimas:** išvardijame visas jūsų serverio FPM versijas, baseinus, naudotojus ir lizdus.
- **Pataisyti ir paleisti iš naujo:** atnaujiname PHP ir pagal paleidimo laikus įrodome, kad nebeveikia joks senas darbinis procesas.
- **Baseinų atskyrimas:** [serverio sutvirtinimo](https://phpsos.de/lt/leistungen/server-haertung/) rėmuose kiekvienai svetainei įrengiame baseiną su savu naudotoju ir užrakintais nustatymais.
- **Pasiekiamumo patikra:** tikriname, kad FastCGI lizdai ir būsenos puslapiai nėra pasiekiami iš išorės.


## Dažni klausimai

**Ką reiškia FPM?**  
FPM reiškia FastCGI Process Manager. PHP vadovas jį apibūdina kaip pagrindinį PHP FastCGI įgyvendinimą su funkcijomis, naudingomis visų pirma labai apkrautoms svetainėms. Į PHP įtrauktas su PHP 5.3.3.

**Kuo skiriasi baseinas (pool) ir darbinis procesas (worker)?**  
Baseinas yra darbinių procesų grupė su bendra konfigūracija: naudotoju, lizdu (socket), ribomis ir PHP nustatymais. Darbinis procesas yra pavienis procesas, kuris nuosekliai apdoroja užklausas. Serveris gali turėti daug baseinų, pavyzdžiui, po vieną kiekvienai svetainei.

**Ar PHP-FPM turėtų būti pasiekiamas per TCP, ar per Unix lizdą?**  
Jei žiniatinklio serveris veikia tame pačiame kompiuteryje, PHP vadovas rekomenduoja Unix lizdą. Naudojant TCP reikia nustatyti listen.allowed_clients, nes kitaip jungtis gali bet kuris adresas. Atvirai pasiekiamas FastCGI prievadas, pasak vadovo, leidžia vykdyti bet kokį kodą.

**Ar pm.max_requests apsaugo nuo tokių spragų kaip PHP2Shell?**  
Ne. pm.max_requests pakeičia darbinį procesą po nustatyto užklausų skaičiaus ir padeda daugiausia nuo atminties nutekėjimų plėtiniuose. Nuo interpretatoriaus spragos padeda tik atnaujinimas su vėlesniu visų darbinių procesų paleidimu iš naujo.

## Šaltiniai

- [PHP vadovas: FastCGI Process Manager](https://www.php.net/manual/en/install.fpm.php)
- [PHP vadovas: FPM konfigūracija](https://www.php.net/manual/en/install.fpm.configuration.php)
- [php.net: PHP 5.3.3 leidimas](https://www.php.net/releases/5_3_3.php)
- [php.net: saugumo pranešimai](https://www.php.net/)
