# PHP-FPM forklaret: procesmanager, pools og workere

> PHP-FPM forklaret: sådan arbejder master, pools og workere, hvad pm static, dynamic og ondemand betyder, og hvilke pool-indstillinger der giver sikkerhed.

Kilde: https://phpsos.de/da/php/php-fpm-erklaert/  
Status: 25.10.2026  
Udbyder: PHP SOS, PHP-nødhjælp og serversikkerhed. Akut hjælp på WhatsApp: https://wa.me/491736494914?text=Hej%20PHP%20SOS%2C%20vi%20har%20brug%20for%20hj%C3%A6lp%20med%20vores%20PHP-server.%20Firma%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort sagt:** PHP-FPM (FastCGI Process Manager) driver PHP som egen tjeneste ved siden af webserveren. En master-proces administrerer pools, og hver pool starter workere, der behandler forespørgsler via FastCGI. Pools kan køres pr. website med egen bruger, egne grænser og låste PHP-indstillinger. Fordi workere behandler mange forespørgsler efter hinanden, skal de alle genstartes efter en PHP-opdatering.

## Hvad er PHP-FPM?

PHP-manualen beskriver FPM som PHP's primære FastCGI-implementering med funktioner, der især er nyttige for stærkt belastede websites. FPM blev optaget med PHP 5.3.3 som egen SAPI, altså som egen driftsform. Dens SAPI-navn er `fpm-fcgi`.

Forskellen til mod_php: PHP kører ikke i webserveren, men som egen tjeneste. Nginx, Apache eller en anden webserver giver PHP-forespørgsler videre via FastCGI-protokollen og får det færdige svar tilbage. Webserver og PHP kan dermed genstartes, konfigureres og sikres uafhængigt af hinanden. Hvordan FastCGI grundlæggende fungerer, står under [CGI og FastCGI](https://phpsos.de/da/php/cgi-und-fastcgi/).

## Master, pools og workere: procesmodellen

PHP-FPM består af tre niveauer:

1. **Master-proces:** læser konfigurationen, åbner socketsene og starter eller afslutter workere. Den udfører selv ingen applikationskode.
2. **Pools:** Hver pool har et navn, en egen socket eller port, en egen Unix-bruger og egne PHP-indstillinger. Manualen nævner udtrykkeligt forskellige uid, gid, chroot, miljø og php.ini pr. pool.
3. **Workere:** processer i en pool, som modtager og udfører forespørgsler. En worker behandler mange forespørgsler efter hinanden, før den erstattes.

Hvor mange workere der kører, afgør procesmanageren med direktivet `pm`:

| Tilstand | Adfærd | Vigtige direktiver |
|---|---|---|
| `static` | fast antal workere | `pm.max_children` |
| `dynamic` | workere mellem nedre og øvre grænse | `pm.start_servers`, `pm.min_spare_servers`, `pm.max_spare_servers` |
| `ondemand` | workere først ved behov, nedlukning efter tomgang | `pm.process_idle_timeout` (standard 10s) |

`pm.max_children` begrænser i alle tilstande antallet af samtidige forespørgsler. `pm.max_requests` erstatter en worker efter et fast antal forespørgsler; standarden 0 betyder ubegrænset.

Hvilken tilstand der passer, afhænger af belastningen. `static` holder altid lige mange workere klar og egner sig til jævnt stærkt brugte applikationer med nok arbejdshukommelse. `dynamic` er et kompromis for de fleste websites. `ondemand` sparer hukommelse på servere med mange små websites, fordi pools uden besøgende ikke optager workere; til gengæld varer den første forespørgsel efter en pause lidt længere. Et for højt sat `pm.max_children` kan drive serveren ud i hukommelsesmangel ved belastningsspidser, et for lavt fører til ventetider og fejlmeddelelser fra webserveren.

## En pool med sikre grundindstillinger

Et eksempel på en egen pool pr. website, med direktiver fra PHP-manualen. Stier og værdier er eksempler:

```ini
; /etc/php/8.3/fpm/pool.d/kunde-a.conf
[kunde-a]
user = kunde-a
group = kunde-a

listen = /run/php/kunde-a.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s

request_terminate_timeout = 60s
security.limit_extensions = .php
clear_env = yes

php_admin_value[open_basedir] = /var/www/kunde-a:/tmp
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[error_log] = /var/log/php/kunde-a.error.log
```

Ifølge manualen kan værdier via `php_value` og `php_flag` ændres under kørsel med `ini_set()`, værdier via `php_admin_value` og `php_admin_flag` derimod ikke. `security.limit_extensions` står som standard på `.php .phar` og fastlægger, hvilke filendelser FPM udfører som hovedscript. `clear_env = yes` er standarden og tømmer workernes miljø.

Til overvågning findes en statusside via `pm.status_path` og en ping-side via `ping.path`. Begge bør kun kunne nås internt. Langsomme forespørgsler logger FPM med backtrace, hvis `request_slowlog_timeout` og `slowlog` er sat.

> **Vigtigt:**
> PHP-manualen advarer: Den, der kan åbne en FastCGI-forbindelse til PHP-FPM, kontrollerer forespørgslens konfiguration og kan dermed udføre vilkårlig kode. PHP-FPM må aldrig kunne nås fra et ikke-betroet netværk. Brug en Unix-socket eller `listen.allowed_clients`.

## Hvilken rolle spiller PHP-FPM ved PHP2Shell?

PHP-FPM hører til de berørte driftsformer. Procesmodellen bliver særligt tydelig ved CVE-2026-109619: Intern tilstand, der hører til forespørgslen, kan blive bestående, efter at hukommelsen er frigivet, og en senere forespørgsel i den samme worker kan udnytte den, før den nulstilles. Det er kun muligt, fordi workere behandler mange forespørgsler efter hinanden.

Heraf følger tre pligter:

1. **Indspille opdateringen:** PHP 8.5.12, 8.4.27, 8.3.36 eller 8.2.35 hhv. en bekræftet backport fra distributionen.
2. **Genstarte alle workere:** Nye filer på disken ændrer intet, så længe gamle workere kører. Det gælder for hver installeret FPM-version og hver pool. Kommandoerne står under [Genstart PHP-FPM og alle workere](https://phpsos.de/da/php2shell/php-fpm-neustart/).
3. **Sætte overgangsværdier låst:** Foranstaltningerne fra php.net, f.eks. `session.upload_progress.enabled=0`, hører via `php_admin_value` eller `php_admin_flag` hjemme i poolen, ikke i `.user.ini`.

Adskillelsen i pools erstatter ikke en opdatering, men begrænser skaden: Kører hvert website under egen bruger, når en angriber efter et indbrud ikke automatisk de andres filer. Hvordan det konkret ser ud, beskriver [Isolér PHP-FPM-pools pr. website](https://phpsos.de/da/blog/php-fpm-pools-isolieren/); integrationen i Nginx står under [Sikring af Nginx med PHP-FPM](https://phpsos.de/da/server/nginx-php-fpm/).

## Hvordan hjælper PHP SOS konkret?

- **Kortlægge pools:** Vi opstiller alle FPM-versioner, pools, brugere og sockets på jeres server.
- **Patche og genstarte:** Vi opdaterer PHP og dokumenterer via starttidspunkter, at ingen gammel worker kører mere.
- **Adskille pools:** Som led i [serverhærdningen](https://phpsos.de/da/leistungen/server-haertung/) opretter vi pr. website en pool med egen bruger og låste indstillinger.
- **Kontrollere tilgængelighed:** Vi kontrollerer, at FastCGI-sockets og statussider ikke kan nås udefra.


## Ofte stillede spørgsmål

**Hvad står FPM for?**  
FPM står for FastCGI Process Manager. PHP-manualen beskriver den som PHP's primære FastCGI-implementering med funktioner, der især er nyttige for stærkt belastede websites. Den blev optaget med PHP 5.3.3.

**Hvad er forskellen på pool og worker?**  
En pool er en gruppe worker-processer med fælles konfiguration: bruger, socket, grænser og PHP-indstillinger. En worker er en enkelt proces, der behandler forespørgsler efter hinanden. En server kan have mange pools, f.eks. én pr. website.

**Skal PHP-FPM kunne nås via TCP eller via en Unix-socket?**  
Kører webserveren på den samme host, anbefaler PHP-manualen en Unix-socket. Ved TCP skal listen.allowed_clients sættes, fordi enhver adresse ellers må forbinde. En åbent tilgængelig FastCGI-port tillader ifølge manualen vilkårlig kodeudførelse.

**Beskytter pm.max_requests mod sårbarheder som PHP2Shell?**  
Nej. pm.max_requests erstatter en worker efter et fast antal forespørgsler og hjælper især mod hukommelseslækager i udvidelser. Mod en sårbarhed i fortolkeren hjælper kun opdateringen med efterfølgende genstart af alle workere.

## Kilder

- [PHP-manualen: FastCGI Process Manager](https://www.php.net/manual/en/install.fpm.php)
- [PHP-manualen: FPM-konfiguration](https://www.php.net/manual/en/install.fpm.configuration.php)
- [php.net: PHP 5.3.3-udgivelsen](https://www.php.net/releases/5_3_3.php)
- [php.net: Sikkerhedsmeddelelser](https://www.php.net/)
