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 →

CI/CD: automatinis PHP atvaizdų perkūrimas

Atvaizdas pasensta ir be kodo pakeitimų. Su pagal grafiką vykdomais kūriniais, versijos patikra ir diegimu pagal santrauką PHP pataisos patikimai patenka į gamybą.

Būsena 5 min. skaitymoHostingas ir distribucijos

Trumpai: Docker atvaizde PHP yra jo sukūrimo momento būsenos ir pasensta net be kodo pakeitimų. Kas atvaizdus perkuria automatiškai, pagal grafiką ir gavus saugumo pranešimus, vamzdyne tikrina PHP versiją ir diegia pagal santrauką, tas tokias pataisas kaip nuo PHP2Shell į gamybą pristato planuotai. Žalias kūrinys vienas nėra įrodymas; svarbi yra versija veikiančiame konteineryje.

Kodėl atvaizdai pasensta be kodo pakeitimų

Daugelyje komandų kūrimo vamzdynas pasileidžia tik tada, kai kas nors pakeičia kodą. Programai tai logiška. Saugumui tai problema, nes atvaizde esantis PHP ateina iš bazinio atvaizdo, kuris buvo paskutinio kūrinio dieną.

PHP2Shell tai padarė matomą. Ištaisytos versijos 8.5.12, 8.4.27, 8.3.36 ir 8.2.35 pasirodė 2026 m. spalio 21 d. Projektas, prie kurio tomis dienomis niekas nedirbo, naujo kūrinio negavo ir toliau veikė su senu PHP, nors bazinis atvaizdas jau seniai buvo atnaujintas. Rankinį kelią iš šios padėties aprašo PHP pataisymas Docker konteineriuose. Šis straipsnis parodo, kaip jį automatizuoti.

Docker atvaizdų automatinis perkūrimas: trys paleidikliai

Tvirtas procesas derina kelis paleidiklius, kad nė vienam nereikėtų vienam viso nešti.

Paleidiklis Įgyvendinimas Į ką atkreipti dėmesį
Grafikas pagal grafiką vykdoma darbo eiga, pvz., kas savaitę pataisas paima ir be kodo pakeitimų
Naujas bazinis atvaizdas įrankis, stebintis bazinius atvaizdus ir siūlantis pakeitimus daugiausia veikia esant fiksuotoms versijų žymėms
Saugumo pranešimas rankinis vamzdyno paleidimas eksploatavimo komandos reikia aiškaus atsakingo asmens

GitHub Actions grafiką perima įvykis schedule. Pagal GitHub dokumentaciją, jis naudoja cron sintaksę su penkiais laukais, veikia UTC ir tik numatytojoje šakoje. Planuojami paleidimai esant didelei apkrovai gali prasidėti vėluodami, o viešuose saugyklose GitHub juos išjungia po 60 dienų be veiklos. Būtent pastarasis dalykas liečia ramius projektus, taigi tuos, kuriems automatinio perkūrimo reikia labiausiai.

Antram paleidikliui pagal GitHub dokumentaciją Dependabot palaiko ekosistemą docker ir naujas bazinių atvaizdų būsenas siūlo kaip Pull Request. Verta žinoti du apribojimus. Pirma, kažkas turi peržiūrėti ir sujungti Pull Request, kitaip jis lieka gulėti. Antra, esant šakos žymei, pavyzdžiui, php:8.3-fpm, Dockerfile nieko nesikeičia, kai bazinis atvaizdas perkuriamas. Įrankiui, siūlančiam teksto pakeitimus, tada nėra ką siūlyti. Būtent todėl papildomai reikia pagal grafiką vykdomo perkūrimo.

Trečias paleidiklis skamba banaliai, bet praktikoje dažnai strigia ties klausimu, kas jį paleidžia. Nustatykite, kas seka PHP saugumo pranešimus ir kam leista paleisti vamzdyną, taip pat savaitgalį. Esant PHP2Shell tarp išankstinio pranešimo ir pataisos buvo tik viena para.

Vamzdynas, sulaikantis pasenusį PHP

Toliau pateiktas GitHub Actions pavyzdys atvaizdą perkuria kas savaitę ir paspaudus mygtuką, patikrina PHP versiją ir nutraukia darbą, jei ji žemesnė už ištaisytą. Registrą, pavadinimus ir minimalią versiją pritaikykite.

name: php-image-rebuild
on:
  schedule:
    - cron: "0 3 * * 1"      # pirmadieniais 03:00 UTC
  workflow_dispatch: {}      # rankinis paleidimas gavus saugumo pranešimus

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Image ohne Cache und mit frischem Basis-Image bauen
        run: docker build --pull --no-cache -t app:${{ github.run_id }} .
      - name: PHP-Version prüfen (Mindeststand des Zweigs 8.3)
        run: |
          docker run --rm app:${{ github.run_id }} php -v
          docker run --rm app:${{ github.run_id }} \
            php -r 'exit(version_compare(PHP_VERSION, "8.3.36", ">=") ? 0 : 1);'

Versijos patikra veikia oficialiems PHP atvaizdams, kurių versijos numeris rodo tikrąją būseną. Jei jūsų atvaizdas naudoja distribucijos PHP paketus, numeris po atgalinio perkėlimo dažnai lieka toks pat. Tuomet vietoj numerio patikrinkite paketo pakeitimų žurnalą dėl CVE numerių, kaip aprašyta straipsnyje CVE numerių įrodymas paketo pakeitimų žurnale.

Po patikros praktikoje seka dar trys žingsniai: atvaizdo nuskaitymas dėl žinomų silpnybių, jo įkėlimas į registrą su data ir santrauka bei santraukos perdavimas diegimui. Kurios žymės ir variantai tinka kaip pagrindas, paaiškina Oficialūs PHP Docker atvaizdai.

Nuo kūrinio iki veikiančio konteinerio

Dažniausia mąstymo klaida: vamzdynas žalias, vadinasi, viskas pataisyta. Iš tikrųjų naujas atvaizdas tik guli registre. Pataisa įsigalioja tik tada, kai kiekvienas konteineris iš naujo atvaizdo sukurtas iš naujo.

  1. Diegti pagal santrauką: diegimas nurodo naujo atvaizdo santrauką, o ne keliaujančią žymę.
  2. Pirmiausia staging, paskui gamyba: automatiniai testai kopijoje sulaiko pakeitimus, kuriuos sukelia nauji baziniai atvaizdai.
  3. Patikrinti veikiant: po diegimo veikiančiame konteineryje paleisti php -v ir santrauką palyginti su kūrinio.
  4. Apriboti kelią atgal: senas atvaizdas trumpam kelio atgal laikui lieka prieinamas, bet turi pažeidžiamą PHP.

Kubernetes yra savos taisyklės, pavyzdžiui, dėl Pull-Policy; jos aprašytos PHP pataisymas Kubernetes.

Tipinės grandinės spragos

  • Kūrimo talpykla vykdytuve (runner): be --pull ir --no-cache pakartotinai naudojamas senas bazinis atvaizdas.
  • Registro veidrodis: vidinė tarpinė talpykla dar pateikia senąją bazinio atvaizdo būseną.
  • Daugiapakopiai kūriniai: svarbi paskutinės pakopos PHP versija, bet dažnai tikrinama tik pirmoji.
  • Šalutiniai atvaizdai: eilių darbuotojai, cron konteineriai ir vidaus įrankiai turi savus vamzdynus arba iš viso jų neturi.
  • Fiksuotos santraukos: kartą užfiksuota bazinio atvaizdo santrauka niekada neatnaujinama, jei jos neseka joks įrankis.
Svarbu

Perkūrimas pakeičia PHP, o ne duomenis. Kenkėjiškas kodas, kuris iki pataisos pateko į tomus (volumes), įkėlimų aplankus ar duomenų bazę, išlieka ir turi būti tikrinamas atskirai.

Kas reaguoja, kai perkūrimas nepavyksta?

Automatinis perkūrimas yra toks geras, kokia yra reakcija į jo nesėkmę. Jei versijos patikra suveikia arba kūrinys nutrūksta dėl pasikeitusio bazinio atvaizdo, kažkas turi tai pastebėti. Daugelyje komandų tokie pranešimai patenka į pašto dėžutę, kurios niekas neskaito, arba į kanalą, kuriame raudoni kūriniai jau seniai kasdienybė.

Pasiteisino aiški taisyklė: nepavykęs saugumo perkūrimas yra užduotis su atsakingu asmeniu ir terminu, o ne viena iš daugelio užuominų. Be to, kiekvienam įdiegtam atvaizdui užfiksuokite datą, santrauką ir patikrintą PHP versiją. Šis sąrašas per kitą pranešimą per kelias minutes atsako, kurios programos paveiktos, o auditoriams ar draudikams tarnauja kaip įrodymas. Kaip iš to susidaro nuolatinė eiga, aprašo Pataisų valdymas kaip procesas, o ne gaisrų gesinimas.

Kaip PHP SOS padeda konkrečiai?

  • Patikrinti vamzdynus: peržiūrime jūsų kūrimo ir diegimo grandines ir parodome, kur pataisa gali strigti.
  • Automatizuoti perkūrimą: įrengiame pagal grafiką vykdomus kūrinius, versijos patikrą ir diegimą pagal santrauką.
  • Užfiksuoti visus atvaizdus: kiekvienam veikiančiam konteineriui priskiriame jo vamzdyną, taip pat šalutinius ir senus atvaizdus.
  • Prižiūrėti ilgalaikiai: saugumo priežiūros sutartyje sekame saugumo pranešimus ir inicijuojame perkūrimus.

Dažni klausimai

Kaip dažnai reikėtų perkurti PHP atvaizdą?

Fiksuoto skaičiaus nėra. Pasiteisino reguliarus pagal grafiką vykdomas kūrinys, pavyzdžiui, kas savaitę, ir nedelsiamas kūrinys gavus saugumo pranešimą. Svarbiausia, kad nauja pataisa nelauktų kito kodo pakeitimo.

Ar sėkmingo kūrinio pakanka kaip įrodymo?

Ne. Kūrinys įrodo tik tai, kad egzistuoja naujas atvaizdas. Pataisa veiksminga tik tada, kai veikiantys konteineriai iš šio atvaizdo sukurti iš naujo ir php -v juose rodo ištaisytą versiją.

Kodėl po perkūrimo vis tiek rodoma sena PHP versija?

Dažnos priežastys: kūrimo talpykla, kuri pakartotinai naudoja senąjį bazinį atvaizdą, registro veidrodis su sena būsena arba antra FROM eilutė daugiapakopiame kūrinyje. Kurkite su --pull ir --no-cache ir patikrinkite kiekvieną pakopą.

Ar Dependabot gali atnaujinti bazinius atvaizdus?

Pagal GitHub dokumentaciją, Dependabot palaiko Docker ekosistemą versijų ir saugumo atnaujinimams. Jis siūlo bazinių atvaizdų pakeitimus kaip Pull Request. Perkūrimo esant nekintančiai žymei 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