Dabartinė padėtis: PHP2Shell. Du kritiniai PHP pažeidžiamumai (CVSS 9,2) leidžia vykdyti kenkėjišką kodą be prisijungimo. Pataisos nuo 2026-10-21.Ką dabar daryti →

PHP eksploatavimas konteineriuose

PHP konteineryje reikia tinkamo atvaizdo varianto, produkcijos konfigūracijos, prasmingų atminties ribų ir proceso, kuris atvaizdus perkuria su kiekvienu saugumo leidimu.

Būsena 4 min. skaitymoPHP žinios

Trumpai: Norėdami PHP eksploatuoti konteineriuose, pasirenkate tinkamą oficialaus atvaizdo variantą (fpm, apache ar cli), aktyvuojate produkcijos php.ini, diegiate tik reikalingus plėtinius ir nustatote atminties bei procesų ribas, kurios tarpusavyje dera. Konteineriai nekeičiami: PHP saugumo atnaujinimas, kaip dėl PHP2Shell, pradeda veikti tik tada, kai atvaizdas perkurtas ir kiekvienas konteineris paleistas iš naujo. Todėl šis perkūrimas kiekvienoje konteinerių veikloje turi būti nuolatinis procesas.

Kodėl PHP konteineriuose?

Konteineriai supakuoja PHP, plėtinius ir konfigūraciją į atvaizdą, kuris kiekviename serveryje veikia vienodai. Įmonėms tai reiškia: mažiau netikėtumų tarp testavimo ir produkcijos, greitesnis atkūrimas ir aiškios versijų būsenos. Saugumui tai reiškia ir naują pareigą: konteineryje niekas atnaujinimų automatiškai neįdiegia.

Šis puslapis aprašo einamąją eksploataciją. Kaip esamus konteinerius konkrečiai pataisyti nuo PHP2Shell, aprašyta puslapyje PHP pataisymas Docker konteineriuose.

Tinkamo atvaizdo varianto pasirinkimas

Variantas Turinys Tipinis naudojimas
php:<version>-fpm PHP-FPM, reikalingas prieš jį esantis žiniatinklio serveris produkcija su Nginx, Caddy ar Ingress
php:<version>-apache Apache su mod_php, pagal numatymą mpm_prefork paprastos sandaros, senesnės programos
php:<version>-cli komandinė eilutė, vienintelis variantas, turintis ir php-cgi cron užduotys, eilių darbiniai procesai, build žingsniai
…-alpine ant Alpine Linux su musl maži atvaizdai, kai kuriems plėtiniams reikia pritaikymų
…-bookworm, …-trixie ant nurodytos Debian versijos tvirtas pagrindas atkuriamiems build

Naujiems projektams paprastai rekomenduojamas fpm variantas su atskiru žiniatinklio serverio konteineriu. Esant mod_php, PHP komanda dėl PHP2Shell mato didžiausią riziką; kas naudoja apache atvaizdą, eksploatuoja būtent šį veikimo režimą.

Produkcijos atvaizdo kūrimas

Lieknas pavyzdys programai su prieiga prie MySQL:

FROM php:8.4-fpm-alpine

# Aktyvuoti produkcijos konfigūraciją (pagal atvaizdo dokumentaciją primygtinai rekomenduojama)
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# Tik reikalingi plėtiniai
RUN docker-php-ext-install -j"$(nproc)" pdo_mysql

# Savi nustatymai
COPY zz-sicherheit.ini "$PHP_INI_DIR/conf.d/"

# Kodas priklauso root; FPM darbiniai procesai veikia kaip www-data ir gali jį tik skaityti
COPY . /var/www/html

Atvaizdo pagalbiniai skriptai perima plėtinių kompiliavimą: docker-php-ext-configure parinktims, docker-php-ext-install kompiliavimui, docker-php-ext-enable aktyvavimui, pavyzdžiui, po pecl install. Jei su docker-php-source išpakuojamas pirminis kodas, pasak dokumentacijos, jį reikėtų ištrinti tame pačiame sluoksnyje. Failas zz-sicherheit.ini galėtų atrodyti taip:

expose_php = Off
display_errors = Off
log_errors = On
session.use_strict_mode = 1
session.cookie_httponly = 1

Dar du principai daro atvaizdus patvaresnius. Pirma, pateikiamame atvaizde yra tik tai, ko reikia vykdymo metu; kompiliatorius, paketų talpyklos ir testų failai priklauso atskirai build pakopai. Antra, naudotojas, su kuriuo veikia PHP, rašyti turi tik ten, kur būtina, pavyzdžiui, įkėlimų ar talpyklos kataloguose prijungtuose tomuose (volumes). Daug komandų konteinerį papildomai eksploatuoja su tik skaitoma failų sistema. Įterptam PHP failui tuomet gerokai sunkiau išlikti, o kiekvienas paleidimas iš naujo atkuria švarią atvaizdo būseną. Tai neatstoja tyrimo po incidento, bet pastebimai sumažina atakos paviršių.

Procesai, atmintis ir žurnalai konteineryje

Trys reguliavimo varžtai lemia, ar PHP konteineris veikia stabiliai.

  1. Darbinių procesų skaičius: pm.max_children FPM baseine nustato, kiek užklausų apdorojama vienu metu. Kiekvienas darbinis procesas gali užimti iki memory_limit.
  2. Konteinerio atminties riba: ji riboja visus procesus kartu. Apytikslė taisyklė: darbinių procesų skaičius, padaugintas iš atminties vienam darbiniam procesui, plius rezervas turi tilpti po riba, antraip sistema nutraukia procesus.
  3. Žurnalai: konteineriai žurnalus rašo į standartinę išvestį. PHP-FPM catch_workers_output = yes darbinių procesų išvestis nukreipia į pagrindinį žurnalą; be šio nustatymo, pasak vadovo, jos dingsta tuštumoje.

Be to, naudingas request_terminate_timeout, kuris atskiras užklausas nutraukia po laiko tarpo, kai max_execution_time neveikia. Kaip konteinerius eksploatuoti klasteryje, aprašo PHP pataisymas Kubernetes.

Konteineriai ir saugumas: ką parodė PHP2Shell

Esant PHP2Shell, konteineriai vaidina dvigubą vaidmenį. Viena vertus, jie yra pagalba: php.net kaip pereinamąją priemonę dėl CVE-2026-109618 rekomenduoja memory_limit=-1 derinti su atminties riba per konteinerį ar cgroup, geriausia taip, kad būtų nutraukiamas tik paveiktas darbinis procesas. RLIMIT_AS ir RLIMIT_DATA tam, pasak php.net, netinka. Ši priemonė nėra visiška apsauga ir neatstoja atnaujinimo.

Kita vertus, konteineriai yra spąstai, jei atvaizdai neperkuriami. Atvaizdas su PHP 8.4.26 lieka pažeidžiamas, kad ir kiek kartų konteineris būtų paleistas iš naujo. Tik perkūrimas iki 8.4.27 ar naujesnės versijos ir visų veikiančių konteinerių pakeitimas uždaro spragą. Būseną galima patikrinti tiesiai veikiančiame konteineryje:

docker exec <container> php -v
docker exec <container> php-fpm -v
docker exec <container> php -r 'var_dump(ini_get("memory_hard_limit_percent"));'

Jei paskutinė komanda grąžina bool(false), PHP nepažįsta su ištaisytomis versijomis įvestos direktyvos; pasak vadovo, tuomet versija yra paveikta. Ilgalaikiai padeda tik automatinis perkūrimas, kaip aprašyta CI/CD: automatinis PHP atvaizdų perkūrimas.

Patarimas

Dockerfile nustatykite tikslią PHP versiją žymėje ir didinkite ją sąmoningai. Taip kode galima atsekti, kada kuri versija buvo išdiegta.

Kaip PHP SOS padeda konkrečiai?

Per PHP žiniatinklio serverių sutvirtinimą rūpinamės ir konteineriais:

  • Patikrinti atvaizdus: kiekvieno atvaizdo bazinis atvaizdas, PHP versija, plėtiniai ir konfigūracija.
  • Sutvirtinti konfigūraciją: produkcijos ini, lieknas plėtinių sąrašas, tinkamos darbinių procesų ir atminties ribos.
  • Įrengti perkūrimą: eiga, kuri atvaizdus perkuria ir išdiegia išleidus naujus PHP leidimus.
  • Kontroliuoti vykdymo aplinką: įrodome, kad kiekviename veikiančiame konteineryje veikia ištaisyta versija.

Dažni klausimai

Kuris PHP atvaizdo variantas teisingas?

Nginx ar kitam tarpiniam serveriui fpm variantas, paprastai sandarai su Apache apache variantas, skriptams ir cron užduotims cli variantas. Alpine variantai mažesni, bet remiasi musl vietoj glibc, o tai kai kuriems plėtiniams būna pastebima.

Ar PHP konteineryje atnaujinamas automatiškai?

Ne. Veikiantis konteineris nesikeičia. Atvaizdą su nauja PHP versija turite perkurti ir konteinerius paleisti iš naujo. Tik tada veikia ištaisyta versija.

Kaip elgiasi memory_limit ir konteinerio riba?

memory_limit riboja kiekvieną atskirą PHP užklausą, konteinerio riba visą konteinerį. Abi turi derėti: darbinių procesų (worker) skaičius, padaugintas iš atminties vienam darbiniam procesui, turėtų būti mažesnis už konteinerio ribą.

Ar konteineriuose man reikia php.ini?

Taip. Oficialūs atvaizdai kaip šablonus pateikia php.ini-development ir php.ini-production. Produkcijai atvaizdų dokumentacija aiškiai rekomenduoja produkcijos šabloną; savi nustatymai dedami į conf.d.

Šaltiniai

Skubus kontaktas

Kiekviena valanda svarbi. Parašykite mums dabar.

Trumpai aprašykite sistemą, PHP versiją ir pastebėjimus. Mes atsakysime, išsiaiškinsime padėtį ir dirbsime nuotoliu, kol incidentas bus užbaigtas ir dokumentuotas.

Skubi pagalba