# PHP:n korjaus Kubernetesissa

> Kubernetes PHP-image PHP2Shellin jälkeen: löydä haavoittuvat podit, rakenna imaget uudelleen, vie kaikki workloadit käyttöön ja todista tila podeittain.

Lähde: https://phpsos.de/fi/server/kubernetes/  
Tilanne: 25.10.2026  
Palveluntarjoaja: PHP SOS, PHP-hätäapu ja palvelimen tietoturva. Pikaapu WhatsAppilla: https://wa.me/491736494914?text=Hei%20PHP%20SOS%2C%20tarvitsemme%20apua%20PHP-palvelimemme%20kanssa.%20Yritys%3A%20%E2%80%A6%20Verkkosivusto%3A%20%E2%80%A6

**Lyhyesti:** Kubernetesissa PHP on konttikuvassa, ei klusterissa. PHP2Shellin jälkeen sinun on rakennettava jokainen Kubernetes PHP -image uudelleen korjatulla PHP-versiolla, vietävä kaikki koskeneet workloadit uudelleen käyttöön ja tarkistettava tila sen jälkeen jokaisessa käynnissä olevassa podissa. Päivitetty peruskuva rekisterissä ei yksin muuta käynnissä olevia podeja.

## Miksi klusteri ei itse korjaa

Kubernetes hallinnoi kontteja, mutta ei huolehdi niiden sisällä olevasta ohjelmistosta. Jokainen pod toimii imagella, josta se käynnistettiin, kunnes se korvataan. Joka ajaa PHP-sovelluksia klusterissa, vastaa siksi imageista, vaikka klusteri toimisi hallinnoituna palveluna pilvipalveluntarjoajalla. Palveluntarjoaja ylläpitää tyypillisesti ohjaustasoa ja solmuja, ei asiakkaiden imageja.

PHP2Shell koostuu haavoittuvuuksista CVE-2026-109618 ja CVE-2026-109619, kumpikin CVSS v4.0 9.2. Ne koskevat muun muassa PHP-FPM:ää, Apachea mod_php:n kanssa ja FrankenPHP:tä, eli PHP-imagejen tavallisia toimintatapoja. Korjatut versiot ovat PHP 8.5.12, 8.4.27, 8.3.36 ja 8.2.35.

## Kartoitus: mikä Kubernetes PHP -image pyörii missä?

Aloita luettelolla kaikista klusterin imageista. Seuraavat komennot vain lukevat. Nimiavaruuksien, deploymentien ja konttien nimet ovat esimerkkejä.

```bash
# Kaikkien podien kaikki imaget ryhmiteltyinä
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}'

# Todella käynnissä oleva image-digest konttia kohden
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{range .status.containerStatuses[*]}{.imageID}{" "}{end}{"\n"}{end}'

# PHP-versio käynnissä olevassa podissa
kubectl exec -n shop deploy/web -c php -- php -v
```

Ajattele deploymentien lisäksi myös StatefulSetejä, DaemonSetejä, CronJobeja ja init-kontteja. Suuremmissa klustereissa auttavat image-skannerit, jotka käyvät imaget läpi tunnettujen CVE-haavoittuvuuksien varalta. Imagen sisäisten jakelupakettien kohdalla pätee kuten kaikkialla: backport voi jättää versionumeron ennalleen, jolloin ratkaisee paketin muutosloki.

## Rakenna imaget uudelleen

Päivitä ensin peruskuva. Jos käytät virallisia PHP-imageja, valitse muunnos, jossa on korjattu PHP-versio. Rakenna sitten oma imagesi uudelleen ottamatta vanhaa peruskerrosta välimuistista.

```bash
# Esimerkki: rakenna image uudelleen, hae peruskuva aktiivisesti uudelleen
docker build --pull --no-cache -t registry.example.com/shop/web:2026-10-25 .

# Tarkista PHP-versio uudessa imagessa ennen rolloutia
docker run --rm registry.example.com/shop/web:2026-10-25 php -v
```

Älä luota tageihin kuten `latest` tai pelkkään pääversioon. Viittaa manifestissa mahdollisuuksien mukaan uuden imagen digestiin, jotta on yksiselitteistä, mikä tila viedään käyttöön. Jos käyttöönotto kulkee GitOpsin tai Helmin kautta, muuta image siellä, jotta tila ei palaudu seuraavassa täsmäytyksessä.

## Rollout ja tarkistus

Uusi rollout korvaa workloadin kaikki podit vaiheittain. Sen jälkeen tarkistat tilan käynnissä olevissa podeissa. Vasta silloin korjaus on voimassa, sillä uudet tiedostot auttavat vain, jos vanhat PHP-prosessit eivät enää pyöri.

```bash
# Rollout uudella imagella (nimet esimerkkinä)
kubectl -n shop set image deploy/web php=registry.example.com/shop/web@sha256:<digest>
kubectl -n shop rollout status deploy/web

# Tarkistus: kaikki podit käynnistetty uudelleen, uusi digest aktiivinen?
kubectl -n shop get pods -o wide
kubectl -n shop exec deploy/web -c php -- php -v
```

Jos image on työnnetty uudelleen samalla tagilla, `kubectl rollout restart` käynnistää uudelleenkäynnistyksen; podit hakevat imagen uudelleen kuitenkin vain, jos `imagePullPolicy` niin määrää. Varmempaa on siirtyä uuteen digestiin.

> **Tärkeää:**
> Turvaa lokit, ennen kuin korvaat podeja. Vanhan podin mukana katoavat myös sen paikalliset lokit. Säilytä verkkopalvelimen ja sovelluksen lokit 20.10.2026 alkaen, mieluiten keskitetyssä lokialustassa.

## Väliaikaiset toimenpiteet klusterissa

Jos PHP-versiollesi ei ole vielä korjattua imagea, php.net suosittelee väliaikaisia toimenpiteitä ilman täydellistä suojaa. Klusterissa asetat muistirajat konttien resurssirajoilla, jotka perustuvat cgroupeihin. Se vastaa suositusta rajoittaa muistia konteilla tai cgroupeilla eikä `RLIMIT_AS`- tai `RLIMIT_DATA`-asetuksilla.

```ini
; php.ini tai FPM-pooli imagessa, esim. ConfigMapilla liitettynä
session.upload_progress.enabled = 0
post_max_size = 8M
upload_max_filesize = 6M
```

Latausominaisuuden kanssa php.net mainitsee arvon `post_max_size = 32M`. PHP 8.5:ssä lisätään `fatal_error_backtraces=0`. Konfiguraation muutoksen jälkeen tarvitaan uusi rollout. Lisäksi NetworkPolicyt rajoittavat PHP-podien lähteviä yhteyksiä, ja suojasäännöillä varustettu Ingress voi vaikeuttaa hyökkäysyrityksiä. Pelkkiin pyyntötietoihin perustuvat säännöt eivät kuitenkaan Cloudflaren mukaan riitä.

## Vahvempi pohja pitkällä aikavälillä

Suunnittele säännölliset automaattiset uudelleenrakennukset kaikille PHP-imageille, image-tarkistus build-ketjuun ja käytännöt, jotka sallivat vain allekirjoitetut tai tarkistetut imaget. Jos PHP-kontit toimivat ilman root-oikeuksia olevalla käyttäjällä ja kirjoitussuojatulla tiedostojärjestelmällä, onnistuneen hyökkäyksen vahinko pienenee. Vihjeitä yksittäisille konteille on sivulla [PHP:n korjaus Docker-konteissa](https://phpsos.de/fi/php2shell/docker-container-patchen/), FrankenPHP:lle sivulla [FrankenPHP turvalliseksi](https://phpsos.de/fi/server/frankenphp/).

Monissa klustereissa PHP-sovellukset eivät pyöri yksin. Usein on sidecar-kontteja lokitukselle tai mittareille, apuimageja tietokantamigraatioille ja jobeja, jotka käynnistyvät vain öisin. Myös kolmansien osapuolten imaget, esimerkiksi wikille, valvontakäyttöliittymälle tai tikettijärjestelmälle, voivat sisältää PHP:tä, vaikka se ei näy nimestä. Tarkista siksi paitsi omat sovelluksesi myös jokainen klusterin image. Vieraiden imagejen kohdalla: odota valmistajan päivitettyä versiota, tarkista sen ilmoitus sisältyvästä PHP-versiosta ja rajoita tavoitettavuutta, kunnes se on saatavilla. Jos tällainen järjestelmä toimii vain sisäisesti, se pienentää riskiä, mutta ei korvaa päivitystä.

## Miten PHP SOS auttaa konkreettisesti?

- Kartoitamme kaikki PHP:tä sisältävät workloadit, niiden imaget ja digestit ja tarkistamme PHP-version käynnissä olevissa podeissa.
- [PHP-korjauspalvelun](https://phpsos.de/fi/leistungen/php-patch-service/) kautta rakennamme imaget uudelleen, vien ne käyttöön ja dokumentoimme tilan workloadeittain.
- Turvaamme lokit ennen vaihtoa ja tarkistamme hyökkäyksen jäljet.
- [Tietoturvavalvonnalla](https://phpsos.de/fi/leistungen/security-monitoring/) ja automatisoiduilla uudelleenrakennuksilla huolehdimme siitä, että seuraava korjaus tavoittaa klusterin nopeammin.


## Usein kysytyt kysymykset

**Riittääkö, että päivitän peruskuvan rekisterissä?**  
Ei. Käynnissä olevat podit käyttävät yhä imagea, jolla ne käynnistettiin. Vasta uusi rollout uudelleen rakennetulla imagella korvaa podit. Tarkista sen jälkeen PHP-versio jokaisessa käynnissä olevassa podissa.

**Miksi imaget kannattaa viitata digestillä?**  
Tagi voi osoittaa eri image-tiloihin sen mukaan, milloin se on haettu. Digest nimeää täsmälleen yhden tilan. Näin tiedät varmasti, mikä koodi pyörii missäkin podissa, ja rolloutit ovat jäljitettäviä.

**Entä CronJobit ja init-kontit?**  
Nekin voivat sisältää PHP:tä ja kuuluvat kartoitukseen. CronJobit käynnistävät jokaisella ajolla uudet podit mallinsa pohjalta; päivitä siksi image mallissa. Init-kontit ajetaan jokaisen podin käynnistyessä.

**Suojaako NetworkPolicy PHP2Shelliltä?**  
Se ei sulje haavoittuvuutta, mutta voi rajoittaa vahinkoa. Kun rajoitat PHP-podien lähteviä yhteyksiä, haittakoodin jälkilataus ja sivuttaisliike klusterissa vaikeutuvat.

## Lähteet

- [php.net: tietoturvatiedotteet](https://www.php.net/)
- [PHP 8 ChangeLog (muutosloki)](https://www.php.net/ChangeLog-8.php)
- [OWASP Cheat Sheets (ohjekortit)](https://cheatsheetseries.owasp.org/)
- [BSI (Saksan liittovaltion tietoturvavirasto)](https://www.bsi.bund.de/)
