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 pataisymas Docker konteineriuose

Konteineriai patys nesipataiso. Nuo PHP2Shell turite perkurti arba iš naujo atsisiųsti PHP atvaizdą ir kiekvieną konteinerį sukurti iš naujo atvaizdo.

Būsena 4 min. skaitymoPHP2Shell

Trumpai: PHP Docker atvaizdo atnaujinimas nuo PHP2Shell yra privalomas ir savaime nevyksta. Turite atvaizdą su ištaisyta PHP versija perkurti arba atsisiųsti, iš jo kiekvieną konteinerį sukurti iš naujo ir patikrinti, kad veikiančiame konteineryje veikia 8.5.12, 8.4.27, 8.3.36 arba 8.2.35. Vien konteinerio paleidimo iš naujo nepakanka.

Kodėl konteineriai nėra automatiškai saugūs

Docker atvaizdas yra sustingdytas momentinis vaizdas. PHP jame lieka tokios būsenos, kokios buvo kuriant, net jei pagrindinėje sistemoje (host) seniai įdiegti atnaujinimai. Paketų atnaujinimas pagrindinėje sistemoje konteinerio PHP nepakeičia.

Be to, yra tipinių spąstų: atvaizdai, sukurti prieš mėnesius ir nuo to laiko neliesti, pagrindiniai atvaizdai su fiksuota žyma, pavyzdžiui, php:8.3.35-fpm, vietinės talpyklos, kurios kuriant pakartotinai naudoja seną pagrindinį atvaizdą, ir konteineriai, kurie paleisti iš naujo, bet niekada nesukurti iš naujo. Paveikti visi konteineriuose įprasti veikimo režimai: PHP-FPM, Apache su mod_php ir FrankenPHP.

Papildomai kyla atsakomybės klausimas. Daugelyje įmonių atvaizdą kartą sukūrė agentūra ar kūrėjas, o eksploatuoja jį vidinė IT ar talpintojas. Tada niekas nesijaučia atsakingas už PHP būklę atvaizde. Todėl pirmiausia išsiaiškinkite, kas atvaizdą kuria, kur guli Dockerfile ir kas gali išleisti naujus atvaizdus.

PHP versijos konteineryje patikrinimas

Tikrinkite veikiantį konteinerį, o ne tik Dockerfile. Komandos tik skaito.

docker ps --format "table {{.Names}}\t{{.Image}}\t{{.CreatedAt}}"
docker exec <container> php -v
docker exec <container> php -i | grep -E "^PHP Version|Server API"
docker image inspect <image> --format "{{.Created}}"

Jei atvaizdas naudoja distribucijos paketus, o ne oficialius PHP darinius, tikrinkite paketų būseną konteineryje. Paketų pavadinimai skiriasi pagal pagrindinę distribuciją:

docker exec <container> sh -c "apt policy php8.3-fpm 2>/dev/null || apk info -v 2>/dev/null | grep php"

Esant distribucijos paketams, atgalinis perkėlimas (backport) gali būti įdiegtas, nors versijos numeris lieka senas. Tada svarbus paketo pakeitimų žurnalas (changelog). Oficialūs PHP atvaizdai PHP dažniausiai atsineša patys sukompiliuotą; ten lemiama reikšmė yra versijos numeris iš php -v. Kaip atpažinti atgalinius perkėlimus, aprašo Kaip teisingai patikrinti PHP versiją ir pataisų būseną.

PHP Docker atvaizdo atnaujinimas: perkurti ir išleisti

Nuosavas atvaizdas ant PHP atvaizdo pagrindo: pagrindinį atvaizdą atsisiųsti iš naujo ir kurti be talpyklos.

docker build --pull --no-cache -t meine-app:2026-10-25 .
docker run --rm meine-app:2026-10-25 php -v      # patikrinti versiją prieš išleidžiant

Su Docker Compose: atvaizdus atsisiųsti ar sukurti ir konteinerius sukurti iš naujo.

docker compose pull
docker compose build --pull --no-cache
docker compose up -d --force-recreate

Po to dar kartą patikrinkite su docker exec <container> php -v, ar veikia nauja versija. Jei konteinerio Dockerfile yra fiksuota versijos žyma, pavyzdžiui, FROM php:8.3.35-fpm, žymą turite pakelti. Šakos žyma, pavyzdžiui, php:8.3-fpm, gauna naujas pataisų būsenas, bet tik jei atsisiunčiate iš naujo.

Ankstesnį atvaizdą laikykite paruoštą, kol nauja versija išbandyta. Klaidos atveju galėsite grįžti, neišjungę programos ilgam. Tačiau senasis atvaizdas vėl turi pažeidžiamą PHP; grįžimo kelias todėl priimtinas tik trumpai ir su pereinamosiomis priemonėmis.

Kas naudoja Kubernetes, naują atvaizdą išleidžia per Deployment. Išsamiau puslapyje PHP pataisymas Kubernetes. FrankenPHP atvaizdams galioja ta pati eiga; nuorodų apie veikimo režimą rasite puslapyje FrankenPHP apsauga.

Svarbu

Nepamirškite šalutinių konteinerių: cron ir eilių darbiniai procesai, administravimo įrankiai ar bandomosios (staging) aplinkos dažnai naudoja tą patį PHP atvaizdą, bet veikia savo konteineriuose. Kiekvienas iš jų turi būti sukurtas iš naujo.

Pereinamosios priemonės konteineryje

Jei atnaujinimas dar neįmanomas, php.net pereinamosios priemonės galioja ir konteineryje. Jos nėra visiška apsauga. Atminties riba čia priklauso konteineriui, nes php.net ją rekomenduoja per konteinerį ar cgroup, o ne per RLIMIT_AS ar RLIMIT_DATA:

; pvz., kaip failas atvaizde: /usr/local/etc/php/conf.d/zz-uebergang.ini
memory_limit = -1
post_max_size = 8M
upload_max_filesize = 6M
session.upload_progress.enabled = 0
docker run --memory=1g ...         # arba Compose: deploy.resources.limits.memory

Reikšmę pritaikykite savo programai. Pasirūpinkite, kad programa pati memory_limit negalėtų perrašyti; esant PHP-FPM reikšmes tam nustatykite baseine su php_admin_value. Nauja konfigūracija suveikia tik kai konteineris sukurtas iš naujo ar paleistas iš naujo; paleidimo iš naujo pagrindai aprašyti puslapyje PHP-FPM ir visų darbinių procesų paleidimas iš naujo.

Kad kitą kartą vyktų greičiau

  • Atvaizdus reguliariai ir automatiškai kurti iš naujo, ne tik pasikeitus kodui.
  • Naudoti pagrindinius atvaizdus su šakos žyma ir sukurtą būseną versijuoti su data ar santrauka (digest).
  • Atvaizdus prieš išleidžiant tikrinti dėl žinomų spragų ir konteinerius eksploatuoti be root teisių.
  • Tvarkyti inventorių, kurie konteineriai kokį atvaizdą naudoja.

Kaip PHP SOS padeda konkrečiai?

  • Surašyti esamą padėtį: Tikriname visus veikiančius konteinerius, jų atvaizdus ir PHP versijas, taip pat šalutinius konteinerius ir bandomąsias aplinkas.
  • Perkurti ir išleisti: Per PHP pataisų paslaugą kuriame atvaizdus su ištaisyta versija ir kontroliuojamai sukuriame konteinerius iš naujo.
  • Apsaugoti pereinamuoju laikotarpiu, kai atnaujinimas priklauso nuo programos: php.net reikšmės, atminties riba konteineriui.
  • Nuolat stebėti: Su saugumo stebėsena sekame atvaizdų būsenas ir neįprastą konteinerių elgesį.

Dažni klausimai

Ar po atnaujinimo pakanka docker restart?

Ne. docker restart paleidžia konteinerį iš naujo su tuo pačiu, senu atvaizdu. Turite sukurti arba atsisiųsti naują atvaizdą ir iš jo sukurti konteinerį iš naujo, pavyzdžiui, su docker compose up -d --force-recreate.

Ar oficialiame PHP atvaizde jau yra ištaisyta versija?

Tai geriausia patikrinti tiesiogiai: iš naujo atsisiųskite atvaizdą ir jame paleiskite php -v. Tikimasi 8.5.12, 8.4.27, 8.3.36 arba 8.2.35. Jei atvaizdas rodo senesnį numerį, jis dar neatnaujintas arba paimtas iš talpyklos.

Ar PHP konteineryje mažiau pavojingas nei pagrindiniame kompiuteryje (host)?

Pati spraga konteineryje veikia lygiai taip pat. Gerai sukurtas konteineris gali apriboti įsilaužimo pasekmes, pavyzdžiui, naudotojas be root teisių ir tik skaitomas failų sistema. Pataisos tai nepakeičia.

Š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