Situația actuală: PHP2Shell. Două vulnerabilități critice PHP (CVSS 9.2) permit cod malițios fără autentificare. Patchuri din 21.10.2026.Ce este de făcut acum →

Izolarea pool-urilor PHP-FPM pentru fiecare site

Un pool propriu pentru fiecare site este începutul, nu sfârșitul. Cum verificați pool-urile existente și securizați socketurile, extensiile, paginile de stare, resursele și jurnalele.

Stadiu 6 min de cititSecurizare și configurare

Pe scurt: Fiecare site de pe un server ar trebui să aibă propriul pool PHP-FPM, cu utilizator de sistem propriu și socket propriu. Separarea devine eficientă abia prin detalii: drepturi pe socket doar pentru serverul web, security.limit_extensions pe .php, fără pagini de stare accesibile public, limite proprii pentru procese și timp de execuție, precum și jurnale separate. Împotriva PHP2Shell însuși protejează doar actualizarea; pool-urile limitează cât de departe ajunge un atac.

Un server, multe site-uri, un risc comun

Pe multe servere s-a acumulat de-a lungul anilor ceea ce nimeni nu a planificat așa. Site-ul firmei, magazinul, o pagină de campanie din 2019 și un sistem de test rulează unul lângă altul, adesea sub același utilizator și în același pool. Dacă pagina de campanie uitată este compromisă, sunt expuse și datele clienților din magazin.

PHP-FPM, managerul de procese FastCGI al PHP, rezolvă aceasta cu pool-uri: grupuri de procese worker cu setări proprii. Cum funcționează principiul de bază explică PHP-FPM explicat: managerul de procese, pool-uri și workeri. Construirea unor pool-uri separate, cu utilizator propriu, dosar temporar propriu și open_basedir, o descrie ghidul open_basedir și izolarea pentru fiecare site. Acest articol merge un pas mai departe: cum verificați pool-urile existente și ce setări fac separarea rezistentă?

Important pentru încadrare: la PHP2Shell, vulnerabilitățile CVE-2026-109618 și CVE-2026-109619 se află în interpretorul PHP, pe care îl împart toate pool-urile unei versiuni PHP. Un pool propriu nu împiedică exploatarea. Dar decide dacă un atacator ajunge apoi la un site sau la toate.

Pool-uri PHP-FPM cu utilizator propriu: verificarea stării existente

Înainte să modificați ceva, faceți-vă o imagine de ansamblu. Comenzile următoare doar citesc. Căile și numerele de versiune diferă în funcție de distribuție:

# Toate pool-urile cu utilizator și socket
grep -HE '^\s*(\[|user|group|listen)\s*' /etc/php/*/fpm/pool.d/*.conf

# Pool-urile în execuție și utilizatorii lor
ps -eo user,pid,cmd | grep '[p]hp-fpm: pool'

# Socketurile și drepturile lor
ls -l /run/php/

# Verificarea erorilor din configurație (nu modifică nimic)
sudo php-fpm8.3 -t

Fiți atenți la trei tipare: mai multe site-uri în același pool, pool-uri care rulează ca www-data sau chiar ca root, și socketuri care pot fi scrise de toți utilizatorii. Fiecare dintre acestea subminează separarea.

Dacă pe server rulează mai multe versiuni PHP, fiecare are propriul serviciu FPM, cu directoare de pool-uri proprii. Verificați-le pe toate, nu doar versiunea configurată cel mai recent. Tocmai versiunile vechi, cu pool-uri uitate, sunt un risc, pentru că adesea nu sunt nici întreținute, nici repornite după actualizări. Indicații în acest sens găsiți la Mai multe versiuni PHP pe un server. Consemnați rezultatul într-un tabel mic: site, pool, utilizator, socket, versiune PHP. Această privire de ansamblu este totodată baza oricărei modificări ulterioare.

Cele mai importante setări pentru fiecare pool

Prezentarea următoare se bazează pe configurația FPM din manualul PHP. Valorile pentru procese și durate depind de încărcarea și aplicația dumneavoastră:

Setare Scop Recomandare
user, group utilizatorul workerilor utilizator propriu pentru fiecare site, niciodată root
listen.owner, listen.group, listen.mode drepturile pe socket doar grupul serverului web, modul 0660
listen.acl_users acces prin ACL în loc de proprietar introduceți doar utilizatorul serverului web
security.limit_extensions extensii executabile limitați la .php (implicit .php .phar)
clear_env golirea variabilelor de mediu lăsați pe valoarea implicită yes
pm.max_children numărul maxim de workeri limitați astfel încât un site să nu încarce complet serverul
request_terminate_timeout întreruperea cererilor blocate stabiliți în funcție de cea mai lungă cerere legitimă
pm.status_path, ping.path pagina de stare și de ping setați doar dacă este nevoie și securizați intern
slowlog, request_slowlog_timeout jurnalul cererilor lente câte un fișier propriu pentru fiecare pool

Un extras pentru un pool securizat arată astfel:

; /etc/php/8.3/fpm/pool.d/shop.conf (extras)
[shop]
user = shop
group = shop
listen = /run/php/shop.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
request_terminate_timeout = 60s

security.limit_extensions = .php
clear_env = yes

slowlog = /var/log/php/shop.slow.log
request_slowlog_timeout = 10s
php_admin_value[error_log] = /var/log/php/shop.error.log

Setări precum memory_limit sau session.upload_progress.enabled le stabiliți pentru fiecare pool cu php_admin_value și php_admin_flag. Potrivit manualului, aceste valori nu pot fi suprascrise prin ini_set(). Mai multe la php_admin_value: blocarea setărilor împotriva suprascrierii.

Încadrarea corectă a paginilor de stare și a înlocuirii workerilor

pm.status_path și ping.path sunt active doar dacă sunt setate. Pagina de stare arată cererile în curs, procesele și gradul de încărcare. Pentru monitorizare este utilă, dar accesibilă public este o sursă inutilă de informații pentru atacatori. Transmiteți aceste căi în serverul web doar pentru adrese interne. Cum colaborează în siguranță Nginx și PHP-FPM descrie Securizarea Nginx cu PHP-FPM.

pm.max_requests stabilește după câte cereri se repornește un worker; valoarea implicită este 0, deci niciodată. O valoare mai mare decât zero ajută împotriva consumului de memorie care crește lent. Ca protecție împotriva PHP2Shell nu este gândită: php.net nu o menționează printre măsurile provizorii și subliniază că doar actualizarea protejează complet. După actualizare se mai aplică și următoarele: toți workerii din toate pool-urile trebuie reporniți, pentru că altfel procesele vechi continuă să ruleze cu codul vulnerabil.

Sfat

Întrețineți un șablon pentru pool-urile noi și creați fiecare site nou cu el. Astfel separarea apare automat, în loc să fie adăugată peste ani.

Greșeli tipice la trecere

Cea mai frecventă greșeală este un pool nou care rulează sub utilizator propriu, dar ale cărui fișiere aparțin în continuare lui www-data. Atunci pool-ul nu are voie să scrie unde trebuie, iar cineva stabilește drepturile prea generos. Clarificați dinainte ce dosare trebuie să fie scriibile. A doua greșeală sunt sarcinile programate care continuă să ruleze sub vechiul utilizator și creează fișiere cu proprietar greșit. A treia este un dosar comun de sesiuni pentru toate pool-urile, care anulează din nou separarea.

După fiecare trecere, testați autentificarea, încărcările, cache-urile și sarcinile programate ale site-ului și urmăriți jurnalul de erori al pool-ului.

Cum ajută PHP SOS concret?

  • Inventariem toate pool-urile, utilizatorii, socketurile și setările și arătăm unde își împart astăzi site-urile procese sau drepturi.
  • Configurăm pentru fiecare site un pool securizat, cu drepturi pe socket, limită pentru extensii, limite de resurse și jurnale proprii.
  • Securizăm paginile de stare, repornim controlat toți workerii și testăm fiecare site.
  • În cadrul securizării serverului documentăm separarea ca șablon pentru proiectele viitoare.

Întrebări frecvente

De ce ar trebui fiecare site să aibă propriul pool PHP-FPM?

Un pool propriu, cu utilizator de sistem propriu, separă site-urile la nivelul proceselor și al drepturilor de fișiere. Dacă un site este compromis, codul nu poate citi fără probleme fișierele celorlalte. În plus, limitele și setările pot fi stabilite separat pentru fiecare site.

Mă protejează un pool propriu de PHP2Shell?

Nu. Vulnerabilitățile se află în interpretorul PHP însuși, pe care toate pool-urile îl folosesc în comun. Protecție oferă doar actualizarea la o versiune corectată, cu repornirea tuturor workerilor. Pool-urile separate limitează însă cât de departe ajunge un atac reușit.

Ce face security.limit_extensions?

Potrivit manualului PHP, setarea limitează ce extensii de fișier execută PHP-FPM ca script principal. Implicit sunt .php și .phar. Cine o limitează la .php împiedică, de exemplu, executarea ca PHP a fișierelor imagine încărcate, dacă serverul web este configurat greșit.

Este periculoasă pagina de stare a PHP-FPM?

Ea dezvăluie detalii despre procesele și cererile în curs. Dacă este accesibilă public, fără protecție, le ușurează atacatorilor orientarea. Potrivit manualului, este activă doar dacă este setat pm.status_path. Atunci serverul web ar trebui să restrângă calea la adrese interne.

Surse

Contact imediat

Fiecare oră contează. Scrieți-ne acum.

Descrieți pe scurt sistemul, versiunea PHP și ce ați observat. Ne vom face auziți, clarificăm situația și lucrăm la distanță până când incidentul este încheiat și documentat.

Ajutor imediat