# php_admin_value: Lås indstillinger mod overskrivning

> php_admin_value og php_admin_flag forklaret: Sådan låser I PHP-værdier i FPM-pool og Apache mod ini_set(), .htaccess og .user.ini og kontrollerer det.

Kilde: https://phpsos.de/da/blog/php-admin-value-sperren/  
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_admin_value` og `php_admin_flag` sætter PHP-indstillinger i PHP-FPM-poolen eller i Apache-konfigurationen, så applikationer hverken kan ændre dem med `ini_set()` eller med `.htaccess`. php.net kræver netop det til PHP2Shell-overgangsforanstaltningerne, f.eks. for `memory_limit=-1`. Efter indstillingen skal tjenesten genstartes, og værdien bør kontrolleres i webkonteksten.

## Hvorfor "sat" ikke betyder "låst"

I dagene efter den 21. oktober 2026 har mange administratorer skrevet php.nets overgangsforanstaltninger ind i deres php.ini. En detalje i anbefalingen gik ofte tabt: `memory_limit=-1` skal være sat, så applikationer ikke kan overskrive den. php.net nævner udtrykkeligt `php_admin_value` i FPM-poolen eller i Apache-konfigurationen hertil.

Årsagen er enkel. Mange CMS, shops og frameworks sætter deres egne værdier, f.eks. en højere hukommelsesgrænse til importer. Står værdien kun i php.ini, overskriver applikationen den ved næste kald. Beskyttelsesforanstaltningen findes så på papiret, men ikke i den kørende proces.

Det berører ikke kun PHP2Shell. Hver hærdning, fra slukkede fejludskrifter til upload-grænser, er kun så stærk som sit svageste niveau.

## Hvem der overhovedet må ændre PHP-indstillinger

PHP kender fire ændringstilstande. Hver indstilling har én af dem, og den bestemmer, på hvilke steder den kan sættes. Betydningerne stammer fra PHP-manualen.

| Tilstand | Hvor værdien kan sættes | Eksempler |
|---|---|---|
| `INI_USER` | i scriptet med `ini_set()` og i `.user.ini` | få køretidsværdier |
| `INI_PERDIR` | php.ini, `.htaccess`, `httpd.conf`, `.user.ini` | `post_max_size`, `session.upload_progress.enabled` |
| `INI_SYSTEM` | kun php.ini eller `httpd.conf` | `file_uploads`, `disable_functions` |
| `INI_ALL` | overalt, også med `ini_set()` | `memory_limit`, `display_errors`, `open_basedir` |

Farlige er først og fremmest `INI_ALL`-værdier: De kan ændres fra ethvert script. `INI_PERDIR`-værdier kan ganske vist ikke ændres med `ini_set()`, men nok via en `.htaccess` ved mod_php eller en `.user.ini` ved PHP-FPM. Den, der har skriverettigheder i webroden, altså også indsmuglet kode, kan oprette sådanne filer.

## php_admin_value i FPM-poolen og i Apache

Ved PHP-FPM står værdierne i pool-filen. PHP-manualen fastslår: Værdier sat med `php_admin_value` og `php_admin_flag` kan ikke overskrives med `ini_set()`. Til til/fra-værdier bruger I `php_admin_flag`, til alle andre `php_admin_value`.

```ini
; /etc/php/8.3/fpm/pool.d/seite1.conf (uddrag)
[seite1]
user = seite1
group = seite1
listen = /run/php/seite1.sock

php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_flag[session.upload_progress.enabled] = off
php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php/seite1-fehler.log
php_admin_value[open_basedir] = /var/www/seite1/:/tmp/seite1/
```

`memory_limit=-1` hører ifølge php.net kun sammen med en hukommelsesgrænse via container eller cgroup hjemme i konfigurationen. Hvordan det lykkes med systemd, står i indlægget [Sæt hukommelsesgrænser med systemd og cgroups](https://phpsos.de/da/blog/speichergrenzen-systemd-cgroups/).

Ved Apache med mod_php hører direktiverne hjemme i serverkonfigurationen eller VirtualHost. Ifølge PHP-manualen er de ikke tilladt i `.htaccess`, og når de først er sat, kan hverken `.htaccess` eller `ini_set()` ændre dem.

```apache
<VirtualHost *:443>
    ServerName www.example.de
    DocumentRoot /var/www/seite1/public
    <IfModule php_module>
        php_admin_value memory_limit -1
        php_admin_value post_max_size 32M
        php_admin_value upload_max_filesize 24M
        php_admin_flag session.upload_progress.enabled off
        php_admin_flag display_errors off
    </IfModule>
</VirtualHost>
```

To finesser fra manualen: For at slette en tidligere sat værdi bruger I `none` som værdi. Og PHP-konstanter som `E_ALL` har ingen betydning i Apache-konfigurationen; for `error_reporting` skal I dér angive talværdien.

## Hvilke værdier I bør låse

Ikke hver indstilling behøver at være låst. Fornuftigt er det for alt, hvad der angår sikkerhed eller tjener som overgangsforanstaltning:

1. php.nets PHP2Shell-overgangsværdier: `memory_limit`, `post_max_size`, `upload_max_filesize`, `session.upload_progress.enabled` og på PHP 8.5 `fatal_error_backtraces`.
2. Fejlvisning og protokollering: `display_errors`, `display_startup_errors`, `log_errors`, `error_log`.
3. Filadgang og isolation: `open_basedir`, `upload_tmp_dir`, `session.save_path`.
4. Netværksadgange fra PHP: `allow_url_include` og, hvis applikationen ikke har brug for det, `allow_url_fopen`.
5. Spærrede funktioner via `disable_functions`, som i poolen ifølge manualen supplerer php.ini-listen og ikke erstatter den. Detaljer i vejledningen [Brug disable_functions rigtigt](https://phpsos.de/da/ratgeber/disable-functions/).

Ved `session.upload_progress.enabled` er låsningen særligt vigtig, fordi værdien ellers kunne slås til igen via en `.user.ini`. Mere herom under [Slå session.upload_progress fra: rigtigt og varigt](https://phpsos.de/da/blog/session-upload-progress-abschalten/).

## Kontrollér, at låsen virker

Efter hver ændring genstarter I tjenesten og kontrollerer værdien i webkonteksten. En kort, straks slettet kontrolfil viser, om poolen holder værdien, også når applikationen vil ændre den:

```php
<?php
// Kontrolfil: læg den kortvarigt ud, kald den én gang via domænet, slet den straks
header('Content-Type: text/plain');
$vorher = ini_get('memory_limit');
$versuch = @ini_set('memory_limit', '256M');
echo "memory_limit: $vorher\n";
echo 'Änderung per ini_set() ', ($versuch === false ? 'blockiert' : 'MÖGLICH'), "\n";
```

Forventet er `-1` og "blockiert". Lyder outputtet "MÖGLICH", er værdien ikke sat via `php_admin_value`, eller tjenesten er endnu ikke genstartet. Gentag kontrollen for hver pool og hver PHP-version.

> **Tip:**
> Hold de låste værdier samlet et centralt sted, f.eks. i en pool-skabelon eller i jeres konfigurationsstyring. Hostingpaneler overskriver til dels håndændrede pool-filer ved næste lagring; dér hører værdierne hjemme i de felter, som panelet har afsat til formålet.

Hvordan PHP samlet ordner sine konfigurationsniveauer, forklarer [php.ini forklaret: Opbygning, niveauer og forrang](https://phpsos.de/da/php/php-ini-erklaert/). De fuldstændige overgangsforanstaltninger står under [Akutforanstaltninger, hvis I endnu ikke kan patche](https://phpsos.de/da/php2shell/sofortmassnahmen-ohne-patch/).

## Konklusion: Først låst er virkelig sat

php.nets overgangsforanstaltninger til PHP2Shell har bragt en skelnen ind i bevidstheden, som tidligere ofte blev overset: En værdi i php.ini er for mange indstillinger kun et forslag, en værdi i `php_admin_value` en forskrift. For komfortværdier som tidszonen er forskellen uvæsentlig. For sikkerhedsindstillinger og overgangsforanstaltninger afgør den, om foranstaltningen overhovedet virker i den løbende drift.

Indsatsen er overskuelig: en håndfuld linjer pr. pool eller VirtualHost, en genstart, en kort kontrol. Hold listen over låste værdier lille og begrundet, så udviklere kan forstå, hvorfor deres applikation ikke må ændre en værdi. Og vedligehold listen i jeres skabeloner, så nye websites arver den automatisk.

## Hvordan hjælper PHP SOS konkret?

- **Udlæs niveauerne:** Vi finder for hvert website ud af, hvilke værdier fra php.ini, pool, Apache, `.htaccess` eller `.user.ini` der faktisk gælder.
- **Sæt låse:** Sikkerhedsrelevante værdier og PHP2Shell-overgangsforanstaltningerne indfører vi som `php_admin_value` henholdsvis `php_admin_flag` og genstarter tjenesterne.
- **Test applikationen:** Vi kontrollerer, om applikationen kører fejlfrit med de låste værdier, og analyserer fejllogget.
- **Vedligehold skabeloner:** Inden for rammerne af [serverhærdningen](https://phpsos.de/da/leistungen/server-haertung/) overfører vi værdierne til pool-skabeloner og dokumentation.


## Ofte stillede spørgsmål

**Hvad er forskellen på php_value og php_admin_value?**  
Begge sætter en PHP-indstilling. Værdier fra php_value kan applikationen senere ændre igen, f.eks. med ini_set() eller .htaccess. Værdier fra php_admin_value og php_admin_flag er ifølge PHP-manualen låst for ini_set(), ved Apache også for .htaccess.

**Kan jeg skrive php_admin_value i en .htaccess-fil?**  
Nej. Ifølge PHP-manualen er php_admin_value ikke tilladt i .htaccess-filer. Den hører hjemme i Apache-serverkonfigurationen eller VirtualHost, ved PHP-FPM i pool-filen.

**Hvad sker der, hvis en applikation vil ændre en låst værdi?**  
Kaldet til ini_set() mislykkes og returnerer false, den låste værdi består. Godt programmerede applikationer klarer det. Kontrollér alligevel fejllogget og de vigtigste funktioner efter omstillingen.

**Skal jeg genstarte efter en ændring i poolen?**  
Ja. PHP-FPM læser pool-filerne ved start eller ved genindlæsning af tjenesten. Ved Apache med mod_php gælder det samme for serverkonfigurationen. Uden genstart kører den gamle værdi videre.

**Kan disable_functions udvides i poolen?**  
Ja, med en særegenhed: Ifølge PHP-manualen overskriver disable_functions i FPM-poolen ikke værdierne fra php.ini, men supplerer dem. Poolen kan altså spærre yderligere funktioner, men ikke frigive nogen.

## Kilder

- [PHP-manual: FPM-konfiguration](https://www.php.net/manual/en/install.fpm.configuration.php)
- [PHP-manual: Ændring af konfiguration](https://www.php.net/manual/en/configuration.changes.php)
- [PHP-manual: Indstillingernes ændringstilstande](https://www.php.net/manual/en/configuration.changes.modes.php)
- [php.net: Sikkerhedsmeddelelser](https://www.php.net/)
