Aktuellt läge: PHP2Shell. Två kritiska PHP-sårbarheter (CVSS 9,2) tillåter skadlig kod utan inloggning. Patchar sedan den 21 oktober 2026.Vad som bör göras nu →

Säkra Nginx med PHP-FPM

Med Nginx och PHP-FPM ligger säkerheten i pooler, rättigheter och en ren omstart. Så patchar ni efter PHP2Shell och härdar Nginx och PHP-FPM långsiktigt.

Aktualitet 5 min läsningServer och webbhotell

Kort sagt: Med Nginx och PHP-FPM sitter sårbarheten i PHP2Shell i PHP-FPM, inte i Nginx. Patcha alla PHP-FPM-versioner, starta om varje FPM-tjänst helt och styrk det med processernas starttider. För långsiktig säkerhet med Nginx och PHP-FPM räknas separata pooler, värden som inte kan skrivas över och en Nginx-konfiguration som inte kör uppladdade filer.

Hur Nginx och PHP-FPM samverkar

Nginx levererar statiska filer själv och lämnar förfrågningar till PHP-skript vidare via FastCGI till PHP-FPM. PHP-FPM består av en master-process och flera worker-processer, grupperade i pooler. En worker hanterar många förfrågningar i följd.

Just det är relevant för PHP2Shell. Vid CVE-2026-109619 kan en förfrågans interna tillstånd finnas kvar efter att minnet frigjorts och användas av en senare förfrågan i samma worker. Vid CVE-2026-109618 kan ett out-of-memory-tillstånd avbryta PHP mitt i initieringen av en förfrågan. Båda sårbarheterna är bedömda med CVSS v4.0 9,2 och åtgärdade i PHP 8.5.12, 8.4.27, 8.3.36 och 8.2.35.

Kontrollera beståndet: versioner, pooler, processer

Många servrar har flera PHP-FPM-versioner parallellt. Följande kommandon läser bara; paket- och tjänstenamn är exempel för Debian/Ubuntu och RHEL-familjen.

# Vilka FPM-tjänster körs?
systemctl list-units --type=service | grep -i fpm

# Vilken version ligger bakom? (exempel Debian/Ubuntu)
php-fpm8.3 -v
# RHEL-familjen
php-fpm -v

# Till vilka sockets eller portar skickar Nginx vidare?
nginx -T 2>/dev/null | grep -E 'fastcgi_pass'

# Pooler och deras användare
grep -RhE '^\[|^user|^listen' /etc/php/*/fpm/pool.d/ 2>/dev/null

Stäm av varje fastcgi_pass-post mot en pool som körs. Då ser ni vilken PHP-version som betjänar vilken webbplats. För distributionspaket styrker ändringsloggen med CVE-numren patchen, inte versionsnumret ensamt.

Ett vanligt fynd vid sådana inventeringar är servrar där flera PHP-versioner har installerats genom åren och bara en används på riktigt. De övriga FPM-tjänsterna körs ändå vidare, ofta med standardpooler som lyssnar på en lokal socket eller port. De är oftast inte direkt nåbara utifrån men är ändå en onödig risk och förlänger varje akut uppdatering. Inaktivera och ta bort versioner som ingen webbplats använder, sedan ni har kontrollerat kopplingen via fastcgi_pass-posterna.

Det lönar sig också att titta på poolernas användare. Körs alla pooler som www-data eller nginx finns åtskillnaden mellan webbplatserna bara på papperet. Den som tar över en webbplats kan då läsa alla andras filer, till exempel konfigurationsfiler med databaslösenord. Egna systemanvändare per pool och lämpliga filrättigheter skapar här en verklig gräns. Det är ingen åtgärd mot PHP2Shell men begränsar den möjliga skadan av ett lyckat angrepp avsevärt.

Installera patchen och förnya alla worker-processer

Efter paketuppdateringen startar ni om varje PHP-FPM-tjänst. En reload ersätter visserligen workers, men en fullständig omstart förnyar även master-processen och är efter säkerhetsuppdateringar det säkra sättet.

# Exempel Debian/Ubuntu, per installerad version
systemctl restart php8.3-fpm
# RHEL-familjen
systemctl restart php-fpm

# Kontroll: starttid för master och workers
ps -eo pid,lstart,cmd | grep -E 'php-fpm' | grep -v grep

Varje process måste ha startats efter uppdateringen. Det beskrivs utförligt under Starta om PHP-FPM och alla worker-processer.

Viktigt

En patch tar inte bort skadlig programvara som fördes in tidigare. Spara Nginx åtkomst- och felloggar från och med den 20 oktober 2026 och kontrollera webbplatserna med avseende på spår.

Sätt tillfälliga värden i poolen

Så länge en version inte är patchad rekommenderar php.net tillfälliga åtgärder. De ger inget fullständigt skydd. I PHP-FPM sätter ni värdena med php_admin_value respektive php_admin_flag i poolen, då kan applikationer inte skriva över dem med ini_set().

; Exempel: /etc/php/8.3/fpm/pool.d/website.conf
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M

Utan uppladdningsfunktion anger php.net post_max_size = 8M. På PHP 8.5 tillkommer fatal_error_backtraces=0. För anvisningen om memory_limit=-1 behöver ni en minnesgräns på cgroup-nivå, till exempel via MemoryMax i ett systemd-tillägg för FPM-tjänsten. Anpassa client_max_body_size i Nginx till det nya post_max_size så att användarna får begripliga felmeddelanden. Starta därefter om FPM.

Förbättra säkerheten med Nginx och PHP-FPM långsiktigt

Utöver det akuta fallet hjälper några grundregler som begränsar skadan vid framtida sårbarheter:

  • En pool per webbplats med egen systemanvändare, egen socket och egen open_basedir-gräns. Mer under open_basedir och isolering per webbplats.
  • Socketrättigheter så att bara Nginx kommer åt, öppna inga FPM-portar utåt.
  • Kör bara befintliga skript: sätt try_files $uri =404; i PHP-location, så att Nginx inte skickar vidare sökvägar som inte finns till PHP.
  • Kör inte uppladdningar: förbjud PHP-körning i uppladdningskataloger. Anvisningar finns under Implementera filuppladdningar säkert.
  • Skydda statussidor: gör pm.status_path och ping.path nåbara bara internt.
# Exempel: ingen PHP-körning i uppladdningskatalogen
location ~* ^/uploads/.*\.php$ {
    deny all;
}

Kontrollera varje ändring med nginx -t innan ni läser om Nginx. Anteckna dessutom vilka pooler, versioner och specialregler som finns på servern. Den korta dokumentationen sparar värdefull tid vid nästa kritiska sårbarhet, eftersom ingen först behöver leta efter vilken webbplats som hör till vilken pool.

Hur hjälper PHP SOS konkret?

  • Vi kopplar varje webbplats till sin pool och PHP-version och kontrollerar den faktiska paketstatusen.
  • Vi patchar, startar om alla FPM-tjänster och dokumenterar processernas starttider som underlag.
  • Fram till patchen sätter vi de tillfälliga värdena per pool och begränsar minnet via cgroup.
  • Inom ramen för serverhärdningen separerar vi pooler, rättigheter och uppladdningskataloger ordentligt.
  • Vid misstanke om ett intrång tar vi över Incident Response.

Vanliga frågor

Räcker systemctl reload för PHP-FPM efter en uppdatering?

En reload förnyar worker-processerna, men master-processen kan behålla den gamla koden. Efter en säkerhetsuppdatering är en fullständig omstart av tjänsten det säkra sättet. Kontrollera därefter starttiden för master och workers.

Måste Nginx startas om efter en PHP-uppdatering?

Nginx innehåller självt ingen PHP och behöver inte startas om för PHP-patchen. Alla PHP-FPM-tjänster måste startas om. Ändrar ni Nginx-konfigurationen samtidigt kontrollerar ni den med nginx -t innan ni läser om den.

Varför egna pooler för varje webbplats?

Varje pool körs med egen användare och egna gränser. Om en webbplats komprometteras kommer angriparen inte utan vidare åt de andras filer. Dessutom kan tillfälliga värden sättas riktat per pool.

Är pm.max_requests ett skydd mot PHP2Shell?

Nej, det ersätter ingen patch. Värdet begränsar hur många förfrågningar en worker hanterar innan den ersätts. Det kan förkorta livslängden för tillstånd i processen men är ingen åtgärd som php.net nämner.

Källor

Direktkontakt

Varje timme räknas. Skriv till oss nu.

Beskriv kort system, PHP-version och observation. Vi hör av oss, klarlägger läget och arbetar på distans tills incidenten är avslutad och dokumenterad.

Direkthjälp