# Zakrpa PHP-a u Kubernetesu

> Zakrpa Kubernetes PHP imagea nakon PHP2Shella: pronađite ranjive podove, iznova izradite imagee, izvedite rollout svih workloada i dokažite stanje po podu.

Izvor: https://phpsos.de/hr/server/kubernetes/  
Stanje: 25.10.2026  
Pružatelj: PHP SOS, PHP hitna pomoć i sigurnost poslužitelja. Hitna pomoć putem WhatsAppa: https://wa.me/491736494914?text=Pozdrav%20PHP%20SOS%2C%20trebamo%20pomo%C4%87%20s%20na%C5%A1im%20PHP%20poslu%C5%BEiteljem.%20Tvrtka%3A%20%E2%80%A6%20Web-stranica%3A%20%E2%80%A6

**Ukratko:** U Kubernetesu je PHP smješten u imageu kontejnera, a ne u klasteru. Nakon PHP2Shella svaki Kubernetes PHP image morate iznova izraditi s ispravljenom PHP verzijom, ponovno izvesti rollout svih pogođenih workloada i zatim u svakom podu koji radi provjeriti stanje. Ažurirani osnovni image u registryju sam ne mijenja ništa na podovima koji rade.

## Zašto klaster sam ne zakrpava

Kubernetes upravlja kontejnerima, ali se ne brine za softver u njima. Svaki pod radi s imageom iz kojeg je pokrenut, sve dok ne bude zamijenjen. Tko u klasteru pokreće PHP aplikacije, stoga snosi odgovornost za imagee, čak i ako klaster radi kao upravljana usluga kod pružatelja oblaka. Pružatelj tipično održava upravljačku razinu i čvorove, a ne imagee korisnika.

PHP2Shell obuhvaća CVE-2026-109618 i CVE-2026-109619, svaki s CVSS v4.0 9,2. Pogođeni su, među ostalim, PHP-FPM, Apache s mod_php i FrankenPHP, dakle uobičajeni načini rada u PHP imageima. Ispravljeni su PHP 8.5.12, 8.4.27, 8.3.36 i 8.2.35.

## Popis postojećeg stanja: koji Kubernetes PHP image radi gdje?

Počnite popisom svih imagea u klasteru. Sljedeće naredbe samo čitaju. Nazivi namespaceova, deploymenata i kontejnera su primjeri.

```bash
# Svi imagei svih podova, grupirano
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}'

# Digest imagea koji stvarno radi po kontejneru
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{range .status.containerStatuses[*]}{.imageID}{" "}{end}{"\n"}{end}'

# PHP verzija u podu koji radi
kubectl exec -n shop deploy/web -c php -- php -v
```

Uz deploymente mislite i na StatefulSetove, DaemonSetove, CronJobove i init kontejnere. U većim klasterima pomažu skeneri imagea koji imagee pretražuju zbog poznatih CVE-ova. Kod paketa distribucije unutar imagea vrijedi kao i svugdje: backport može ostaviti broj verzije nepromijenjenim, tada se računa zapisnik promjena paketa.

## Iznova izradite imagee

Najprije ažurirajte osnovni image. Koristite li službene PHP imagee, odaberite varijantu s ispravljenom PHP verzijom. Zatim iznova izradite vlastiti image, bez preuzimanja stare osnovne razine iz predmemorije.

```bash
# Primjer: iznova izraditi image, osnovni image aktivno ponovno preuzeti
docker build --pull --no-cache -t registry.example.com/shop/web:2026-10-25 .

# Provjerite PHP verziju u novom imageu prije rollouta
docker run --rm registry.example.com/shop/web:2026-10-25 php -v
```

Ne oslanjajte se na tagove poput `latest` ili samo na glavnu verziju. U manifestu po mogućnosti referencirajte digest novog imagea kako bi bilo jednoznačno koje se stanje izvodi. Ako isporuka ide putem GitOpsa ili Helma, promijenite image tamo kako se stanje pri sljedećem usklađivanju ne bi vratilo.

## Rollout i kontrola

Novi rollout postupno zamjenjuje sve podove workloada. Nakon toga provjerite stanje u podovima koji rade. Tek tada je zakrpa djelotvorna, jer nove datoteke pomažu samo ako stari PHP procesi više ne rade.

```bash
# Rollout s novim imageom (nazivi kao primjer)
kubectl -n shop set image deploy/web php=registry.example.com/shop/web@sha256:<digest>
kubectl -n shop rollout status deploy/web

# Kontrola: jesu li svi podovi ponovno pokrenuti, je li aktivan novi digest?
kubectl -n shop get pods -o wide
kubectl -n shop exec deploy/web -c php -- php -v
```

Ako je image ponovno poslan pod istim tagom, `kubectl rollout restart` pokreće ponovno pokretanje; podovi image ipak ponovno preuzimaju samo ako to predviđa `imagePullPolicy`. Sigurnija je promjena na novi digest.

> **Važno:**
> Osigurajte zapisnike prije nego što zamijenite podove. Sa starim podom nestaju i njegovi lokalni zapisnici. Sačuvajte zapisnike web-poslužitelja i aplikacije od 20. 10. 2026., idealno na središnjoj platformi za zapisnike.

## Privremene mjere u klasteru

Ako za Vašu PHP verziju još nije dostupan ispravljeni image, php.net preporučuje privremene mjere bez potpune zaštite. U klasteru ograničenja memorije postavite putem ograničenja resursa kontejnera koja se temelje na cgroupima. To odgovara preporuci da se memorija ograničava putem kontejnera ili cgroupa, a ne putem `RLIMIT_AS` ili `RLIMIT_DATA`.

```ini
; php.ini ili FPM pool u imageu, npr. uključen putem ConfigMapa
session.upload_progress.enabled = 0
post_max_size = 8M
upload_max_filesize = 6M
```

Uz funkciju uploada php.net navodi `post_max_size = 32M`. Na PHP-u 8.5 dodaje se `fatal_error_backtraces=0`. Nakon promjene konfiguracije potreban je novi rollout. Dodatno NetworkPolicyji ograničavaju odlazne veze PHP podova, a Ingress sa zaštitnim pravilima može otežati pokušaje napada. Pravila samo na temelju podataka zahtjeva prema Cloudflareu ipak nisu dovoljna.

## Bolje postavljanje za dugoročno

Planirajte redovite automatske ponovne izrade svih PHP imagea, provjeru imagea u lancu izrade i pravila koja dopuštaju samo potpisane ili provjerene imagee. Ako PHP kontejneri rade s korisnikom bez root prava i sa zaštićenim datotečnim sustavom samo za čitanje, šteta uspješnog napada se smanjuje. Napomene za pojedinačne kontejnere nalaze se u članku [Zakrpa PHP-a u Docker kontejnerima](https://phpsos.de/hr/php2shell/docker-container-patchen/), za FrankenPHP u članku [Zaštita FrankenPHP-a](https://phpsos.de/hr/server/frankenphp/).

U mnogim klasterima PHP aplikacije ne rade same. Često postoje sidecar kontejneri za zapisivanje ili metrike, pomoćni imagei za migracije baze podataka i jobovi koji se pokreću samo noću. I imagei trećih strana, primjerice za wiki, sučelje za nadzor ili sustav tiketa, mogu sadržavati PHP, a da se to ne vidi iz naziva. Zato ne provjeravajte samo vlastite aplikacije, nego svaki image u klasteru. Za tuđe imagee vrijedi: pričekajte ažuriranu inačicu proizvođača, provjerite njegove podatke o ugrađenoj PHP verziji i ograničite dostupnost dok ona ne bude dostupna. Ako takav sustav radi samo interno, to smanjuje rizik, ali ne zamjenjuje ažuriranje.

## Kako PHP SOS konkretno pomaže?

- Popisujemo sve workloade s PHP-om, njihove imagee i digeste te provjeravamo PHP verziju u podovima koji rade.
- Putem [usluge PHP zakrpa](https://phpsos.de/hr/leistungen/php-patch-service/) iznova izrađujemo imagee, izvodimo rollout i dokumentiramo stanje po workloadu.
- Osiguravamo zapisnike prije zamjene i provjeravamo tragove napada.
- Uz [sigurnosni nadzor](https://phpsos.de/hr/leistungen/security-monitoring/) i automatizirane ponovne izrade brinemo da sljedeća zakrpa brže stigne u klaster.


## Česta pitanja

**Je li dovoljno ažurirati osnovni image u registryju?**  
Ne. Podovi koji rade i dalje koriste image s kojim su pokrenuti. Tek novi rollout s iznova izrađenim imageom zamjenjuje podove. Zatim provjerite PHP verziju u svakom podu koji radi.

**Zašto imagee referencirati putem digesta?**  
Tag može pokazivati na različita stanja imagea, ovisno o tome kada je preuzet. Digest označava točno jedno stanje. Tako sigurno znate koji kod radi u kojem podu, a rolloutovi postaju sljedivi.

**Što je s CronJobovima i init kontejnerima?**  
I oni mogu sadržavati PHP i spadaju u popis postojećeg stanja. CronJobovi pri svakom izvođenju pokreću nove podove iz svog predloška; zato ažurirajte image u predlošku. Init kontejneri rade pri pokretanju svakog poda.

**Štiti li NetworkPolicy od PHP2Shella?**  
Ne zatvara ranjivost, ali može ograničiti štetu. Tko ograniči odlazne veze PHP podova, otežava naknadno učitavanje zlonamjernog koda i bočna kretanja u klasteru.

## Izvori

- [php.net: sigurnosne objave](https://www.php.net/)
- [PHP 8 ChangeLog](https://www.php.net/ChangeLog-8.php)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
- [BSI](https://www.bsi.bund.de/)
