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 →

CI/CD: reconstruirea automată a imaginilor PHP

O imagine se depășește și fără modificări de cod. Cu build-uri programate, o verificare a versiunii și un rollout prin digest, patchurile PHP ajung sigur în producție.

Stadiu 6 min de cititHosting și distribuții

Pe scurt: O imagine Docker conține PHP în nivelul momentului construirii și se depășește și fără modificări de cod. Cine reconstruiește automat imaginile, programat și la anunțuri de securitate, verifică versiunea PHP în pipeline și o distribuie prin digest, aduce în producție patchuri precum cel împotriva PHP2Shell într-un mod planificabil. Un build verde singur nu este o dovadă; contează versiunea din containerul care rulează.

De ce se depășesc imaginile fără modificări de cod

În multe echipe, pipeline-ul de build pornește doar când cineva modifică codul. Pentru aplicație, aceasta este logic. Pentru securitate este o problemă, deoarece PHP-ul din imagine provine din imaginea de bază de la data ultimului build.

PHP2Shell a făcut acest lucru vizibil. Versiunile corectate 8.5.12, 8.4.27, 8.3.36 și 8.2.35 au apărut pe 21 octombrie 2026. Un proiect la care nu a lucrat nimeni în acele zile nu a primit un build nou și a continuat să ruleze cu vechiul PHP, deși imaginea de bază fusese actualizată de mult. Calea manuală din această situație o descrie Patch PHP în containere Docker. Acest articol arată cum o automatizați.

Reconstruirea automată a imaginilor Docker: trei declanșatoare

Un proces robust combină mai multe declanșatoare, pentru ca niciunul să nu trebuiască să poarte singur greul.

Declanșator Implementare De reținut
Program workflow programat, de ex. săptămânal preia patchurile și fără modificări de cod
Imagine de bază nouă unealtă care monitorizează imaginile de bază și propune modificări acționează mai ales la taguri fixe de versiune
Anunț de securitate pornirea manuală a pipeline-ului de către echipa de operare necesită un responsabil clar

La GitHub Actions, evenimentul schedule preia programarea. Conform documentației GitHub, folosește sintaxa cron cu cinci câmpuri, rulează în UTC și doar pe ramura implicită. Rulările programate pot porni cu întârziere la încărcare mare, iar în depozitele publice GitHub le oprește după 60 de zile fără activitate. Tocmai aceasta din urmă lovește proiectele liniștite, adică exact pe cele care au cea mai mare nevoie de reconstruirea automată.

Pentru al doilea declanșator, Dependabot acceptă, conform documentației GitHub, ecosistemul docker și propune niveluri noi ale imaginilor de bază ca pull request. Ar trebui să cunoașteți două limitări. Prima: cineva trebuie să verifice și să îmbine pull request-ul, altfel rămâne neatins. A doua: la un tag de ramură precum php:8.3-fpm, în Dockerfile nu se schimbă nimic când imaginea de bază este reconstruită. O unealtă care propune modificări de text nu are atunci nimic de propus. Tocmai de aceea este necesară suplimentar reconstruirea programată.

Al treilea declanșator sună banal, dar în practică eșuează adesea la întrebarea cine îl declanșează. Stabiliți cine urmărește anunțurile de securitate PHP și cine are voie să pornească pipeline-ul, inclusiv în weekend. La PHP2Shell, între preanunț și patch a fost doar o zi.

Un pipeline care prinde PHP-ul depășit

Exemplul următor pentru GitHub Actions construiește imaginea săptămânal și la cerere, verifică versiunea PHP și se oprește dacă este sub nivelul corectat. Registry-ul, numele și versiunea minimă le adaptați.

name: php-image-rebuild
on:
  schedule:
    - cron: "0 3 * * 1"      # lunea la 03:00 UTC
  workflow_dispatch: {}      # pornire manuală la anunțuri de securitate

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);'

Verificarea versiunii funcționează la imaginile PHP oficiale, al căror număr de versiune indică nivelul real. Dacă imaginea dumneavoastră folosește pachete PHP ale unei distribuții, numărul rămâne adesea același după un backport. Atunci verificați, în loc de număr, changelog-ul pachetului pentru numerele CVE, așa cum descrie articolul Dovedirea numerelor CVE în changelog-ul pachetului.

După verificare urmează în practică încă trei pași: scanarea imaginii pentru vulnerabilități cunoscute, trimiterea ei în registry cu dată și digest și transmiterea digest-ului către distribuire. Ce taguri și variante sunt potrivite ca bază explică Imaginile Docker PHP oficiale.

De la build la containerul care rulează

Cea mai frecventă eroare de gândire: pipeline-ul este verde, deci totul este actualizat. În realitate, imaginea nouă se află doar în registry. Patchul devine eficient abia când fiecare container a fost recreat din imaginea nouă.

  1. Distribuiți prin digest: Distribuirea referențiază digest-ul noii imagini, nu un tag care se mută.
  2. Mai întâi staging, apoi producție: Testele automate pe o copie prind rupturile cauzate de imaginile de bază noi.
  3. Verificați în operare: După rollout rulați php -v în containerul care rulează și comparați digest-ul cu cel de la build.
  4. Limitați calea de întoarcere: Vechea imagine rămâne disponibilă pentru o scurtă întoarcere, dar conține PHP vulnerabil.

În Kubernetes se aplică reguli proprii, de exemplu privind politica de pull; ele se găsesc la Patch PHP în Kubernetes.

Lacune tipice în lanț

  • Cache de build pe runner: Fără --pull și --no-cache se reutilizează vechea imagine de bază.
  • Oglindă de registry: O memorie intermediară internă livrează încă vechiul nivel al imaginii de bază.
  • Build-uri în mai multe etape: Contează versiunea PHP din ultima etapă, dar adesea se verifică doar prima.
  • Imagini secundare: Workerii de coadă, containerele cron și instrumentele interne au pipeline-uri proprii sau deloc.
  • Digest-uri înscrise fix: Un digest al imaginii de bază fixat o dată nu este actualizat niciodată dacă nicio unealtă nu îl monitorizează.
Important

O reconstruire înlocuiește PHP-ul, nu datele. Codul malițios care a ajuns înainte de patch în volume, directoare de upload sau în baza de date rămâne și trebuie verificat separat.

Cine reacționează dacă reconstruirea eșuează?

O reconstruire automată este la fel de bună ca reacția la eșecul ei. Dacă verificarea versiunii declanșează o alarmă sau build-ul se oprește din cauza unei imagini de bază modificate, cineva trebuie să observe. În multe echipe, astfel de mesaje ajung într-o căsuță pe care n-o citește nimeni sau într-un canal în care build-urile roșii sunt de mult o banalitate.

S-a dovedit utilă o regulă clară: o reconstruire de securitate eșuată este un tichet cu responsabil și termen, nu o notificare printre multe. Consemnați în plus pentru fiecare imagine distribuită data, digest-ul și versiunea PHP verificată. Această listă răspunde la următorul anunț în câteva minute la întrebarea ce aplicații sunt afectate și servește ca dovadă față de auditori sau asigurători. Cum rezultă de aici un flux permanent descrie Managementul patchurilor ca proces în loc de pompieri.

Cum ajută PHP SOS concret?

  • Verificarea pipeline-urilor: Ne uităm la lanțurile dumneavoastră de build și rollout și arătăm unde se poate bloca un patch.
  • Automatizarea reconstruirii: Configurăm build-uri programate, verificarea versiunii și rollout prin digest.
  • Inventarierea tuturor imaginilor: Atribuim fiecărui container care rulează pipeline-ul său, inclusiv imaginile secundare și vechi.
  • Îngrijire permanentă: În contractul de mentenanță de securitate urmărim anunțurile de securitate și declanșăm reconstruirile.

Întrebări frecvente

Cât de des ar trebui reconstruită o imagine PHP?

Nu există un număr fix. S-a dovedit utilă o reconstruire programată regulat, de exemplu săptămânal, plus una imediată la anunțuri de securitate. Decisiv este ca un patch nou să nu trebuiască să aștepte următoarea modificare de cod.

Este un build reușit suficient ca dovadă?

Nu. Un build dovedește doar că există o imagine nouă. Abia când containerele care rulează sunt recreate din această imagine și php -v arată în ele versiunea corectată, patchul este eficient.

De ce apare totuși vechea versiune PHP după reconstruire?

Cauze frecvente sunt un cache de build care reutilizează vechea imagine de bază, o oglindă de registry cu nivel vechi sau un al doilea rând FROM într-un build în mai multe etape. Construiți cu --pull și --no-cache și verificați fiecare etapă.

Poate Dependabot să actualizeze imaginile de bază?

Conform documentației GitHub, Dependabot acceptă ecosistemul Docker pentru actualizări de versiune și de securitate. Propune modificări ale imaginilor de bază ca pull request. Reconstruirea la un tag neschimbat nu o înlocuiește.

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