# php_admin_value: asetusten lukitseminen ylikirjoitukselta

> php_admin_value ja php_admin_flag selitettynä: näin lukitsette PHP-arvot FPM-poolissa ja Apachessa ini_set()-kutsua ja .htaccess-tiedostoa vastaan.

Lähde: https://phpsos.de/fi/blog/php-admin-value-sperren/  
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:** `php_admin_value` ja `php_admin_flag` asettavat PHP-asetukset PHP-FPM-poolissa tai Apachen asetuksissa niin, etteivät sovellukset voi muuttaa niitä funktiolla `ini_set()` eivätkä `.htaccess`-tiedostolla. php.net vaatii juuri tätä PHP2Shellin siirtymäajan toimenpiteissä, esimerkiksi arvolle `memory_limit=-1`. Asetuksen jälkeen palvelu on käynnistettävä uudelleen, ja arvo on syytä tarkistaa verkkokontekstissa.

## Miksi ”asetettu” ei tarkoita ”lukittu”

21. lokakuuta 2026 jälkeisinä päivinä moni ylläpitäjä kirjoitti php.net:n siirtymäajan toimenpiteet php.ini-tiedostoonsa. Yksi suosituksen yksityiskohta jäi usein huomaamatta: `memory_limit=-1` on asetettava niin, etteivät sovellukset voi ylikirjoittaa sitä. php.net nimeää tähän nimenomaisesti komennon `php_admin_value` FPM-poolissa tai Apachen asetuksissa.

Syy on yksinkertainen. Monet CMS:t, verkkokaupat ja kehykset asettavat omia arvojaan, esimerkiksi korkeamman muistirajan tuonteja varten. Jos arvo on vain tiedostossa php.ini, sovellus ylikirjoittaa sen seuraavassa kutsussa. Suojatoimenpide on silloin olemassa paperilla mutta ei käynnissä olevassa prosessissa.

Tämä ei koske vain PHP2Shelliä. Jokainen koventaminen, pois kytketyistä virhetulosteista upload-rajoihin, on vain niin vahva kuin sen heikoin taso.

## Kuka saa ylipäätään muuttaa PHP-asetuksia

PHP tuntee neljä muutostilaa. Jokaisella asetuksella on yksi niistä, ja se määrää, missä kohdissa asetus voidaan asettaa. Merkitykset ovat peräisin PHP-käsikirjasta.

| Tila | Missä arvo voidaan asettaa | Esimerkkejä |
|---|---|---|
| `INI_USER` | skriptissä funktiolla `ini_set()` ja tiedostossa `.user.ini` | muutamia suoritusaikaisia arvoja |
| `INI_PERDIR` | php.ini, `.htaccess`, `httpd.conf`, `.user.ini` | `post_max_size`, `session.upload_progress.enabled` |
| `INI_SYSTEM` | vain php.ini tai `httpd.conf` | `file_uploads`, `disable_functions` |
| `INI_ALL` | kaikkialla, myös funktiolla `ini_set()` | `memory_limit`, `display_errors`, `open_basedir` |

Vaarallisia ovat erityisesti `INI_ALL`-arvot: ne voi muuttaa mistä tahansa skriptistä. `INI_PERDIR`-arvoja ei voi muuttaa funktiolla `ini_set()`, mutta kyllä mod_php:n kanssa `.htaccess`-tiedostolla tai PHP-FPM:n kanssa `.user.ini`-tiedostolla. Joka saa kirjoittaa verkkojuureen, siis myös sisäänajettu koodi, voi luoda tällaisia tiedostoja.

## php_admin_value FPM-poolissa ja Apachessa

PHP-FPM:ssä arvot ovat pool-tiedostossa. PHP-käsikirja toteaa: komennoilla `php_admin_value` ja `php_admin_flag` asetettuja arvoja ei voi ylikirjoittaa funktiolla `ini_set()`. Päälle/pois-arvoille käyttäkää `php_admin_flag`, kaikille muille `php_admin_value`.

```ini
; /etc/php/8.3/fpm/pool.d/seite1.conf (ote)
[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` kuuluu php.net:n mukaan asetuksiin vain yhdessä kontin tai cgroupin kautta asetetun muistirajan kanssa. Miten se onnistuu systemd:llä, kerrotaan kirjoituksessa [Muistirajojen asettaminen systemd:llä ja cgroupeilla](https://phpsos.de/fi/blog/speichergrenzen-systemd-cgroups/).

Apachella mod_php:n kanssa direktiivien paikka on palvelinasetuksissa tai VirtualHostissa. PHP-käsikirjan mukaan ne eivät ole sallittuja `.htaccess`-tiedostossa, ja kerran asetettuna ne eivät muutu `.htaccess`-tiedostolla eikä `ini_set()`-funktiolla.

```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>
```

Kaksi hienovaraisuutta käsikirjasta: aiemmin asetetun arvon tyhjentämiseksi käytätte arvona `none`. Ja PHP-vakioilla kuten `E_ALL` ei ole Apachen asetuksissa merkitystä; `error_reporting`-asetukselle on siellä annettava lukuarvo.

## Mitkä arvot kannattaa lukita

Kaikkia asetuksia ei tarvitse lukita. Se on järkevää kaikelle, mikä koskee turvallisuutta tai toimii siirtymäajan toimenpiteenä:

1. php.net:n PHP2Shellin siirtymäarvot: `memory_limit`, `post_max_size`, `upload_max_filesize`, `session.upload_progress.enabled` ja PHP 8.5:llä `fatal_error_backtraces`.
2. Virhetuloste ja lokitus: `display_errors`, `display_startup_errors`, `log_errors`, `error_log`.
3. Tiedostoihin pääsy ja eristys: `open_basedir`, `upload_tmp_dir`, `session.save_path`.
4. Verkkopääsyt PHP:stä: `allow_url_include` ja, jos sovellus ei tarvitse sitä, `allow_url_fopen`.
5. Estetyt funktiot asetuksella `disable_functions`, jotka poolissa täydentävät käsikirjan mukaan php.ini-listaa eivätkä korvaa sitä. Yksityiskohdat oppaassa [disable_functions oikein käyttöön](https://phpsos.de/fi/ratgeber/disable-functions/).

Asetuksen `session.upload_progress.enabled` kohdalla lukitseminen on erityisen tärkeää, koska arvon voisi muuten kytkeä takaisin päälle `.user.ini`-tiedostolla. Lisää kohdassa [session.upload_progress pois käytöstä: oikein ja pysyvästi](https://phpsos.de/fi/blog/session-upload-progress-abschalten/).

## Lukituksen toiminnan tarkistus

Käynnistäkää palvelu uudelleen jokaisen muutoksen jälkeen ja tarkistakaa arvo verkkokontekstissa. Lyhyt, heti poistettava tarkistustiedosto näyttää, pitääkö pooli arvon, vaikka sovellus yrittäisi muuttaa sitä:

```php
<?php
// Tarkistustiedosto: aseta hetkeksi, kutsu kerran verkkotunnuksen kautta, poista heti
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";
```

Odotettu tulos on `-1` ja ”blockiert”. Jos tuloste on ”MÖGLICH”, arvoa ei ole asetettu komennolla `php_admin_value` tai palvelua ei ole vielä käynnistetty uudelleen. Toistakaa tarkistus jokaiselle poolille ja jokaiselle PHP-versiolle.

> **Vinkki:**
> Pitäkää lukitut arvot keskitetysti kirjattuina, esimerkiksi pool-mallipohjassa tai asetustenhallinnassanne. Hosting-paneelit ylikirjoittavat käsin muutettuja pool-tiedostoja osin seuraavassa tallennuksessa; siellä arvojen paikka on paneelin tarjoamissa kentissä.

Miten PHP järjestää asetustasonsa kokonaisuudessaan, selittää [php.ini selitettynä: rakenne, tasot ja etusija](https://phpsos.de/fi/php/php-ini-erklaert/). Täydelliset siirtymäajan toimenpiteet ovat kohdassa [Pikatoimet, jos ette voi vielä päivittää](https://phpsos.de/fi/php2shell/sofortmassnahmen-ohne-patch/).

## Yhteenveto: vasta lukittu on todella asetettu

php.net:n PHP2Shell-siirtymätoimenpiteet ovat tuoneet tietoisuuteen eron, joka aiemmin usein ohitettiin: php.ini-tiedoston arvo on monelle asetukselle vain ehdotus, `php_admin_value`-arvo on määräys. Mukavuusarvoille, kuten aikavyöhykkeelle, ero on merkityksetön. Tietoturva-asetuksille ja siirtymäajan toimenpiteille se ratkaisee, tehoaako toimenpide käynnissä olevassa toiminnassa lainkaan.

Vaiva on hallittava: kourallinen rivejä poolia tai VirtualHostia kohden, uudelleenkäynnistys, lyhyt tarkistus. Pitäkää lukittujen arvojen lista pienenä ja perusteltuna, jotta kehittäjät voivat ymmärtää, miksi heidän sovelluksensa ei saa muuttaa arvoa. Ja ylläpitäkää listaa mallipohjissanne, jotta uudet verkkosivustot perivät sen automaattisesti.

## Miten PHP SOS auttaa konkreettisesti?

- **Tasojen lukeminen:** Selvitämme jokaiselle verkkosivustolle, mitkä arvot tiedostoista php.ini, pooli, Apache, `.htaccess` tai `.user.ini` ovat todella voimassa.
- **Lukitusten asettaminen:** Kirjaamme turvallisuuden kannalta olennaiset arvot ja PHP2Shellin siirtymäajan toimenpiteet komennoilla `php_admin_value` ja `php_admin_flag` ja käynnistämme palvelut uudelleen.
- **Sovelluksen testaus:** Tarkistamme, toimiiko sovellus virheittä lukittujen arvojen kanssa, ja arvioimme virhelokin.
- **Mallipohjien ylläpito:** [Palvelimen koventamisen](https://phpsos.de/fi/leistungen/server-haertung/) yhteydessä siirrämme arvot pool-mallipohjiin ja dokumentaatioon.


## Usein kysytyt kysymykset

**Mitä eroa on php_valuella ja php_admin_valuella?**  
Molemmat asettavat PHP-asetuksen. Komennolla php_value asetetun arvon sovellus voi myöhemmin muuttaa takaisin, esimerkiksi funktiolla ini_set() tai .htaccess-tiedostolla. Komennoilla php_admin_value ja php_admin_flag asetetut arvot on PHP-käsikirjan mukaan lukittu funktiota ini_set() vastaan, Apachessa myös .htaccess-tiedostoa vastaan.

**Voinko kirjoittaa php_admin_valuen .htaccess-tiedostoon?**  
Et. PHP-käsikirjan mukaan php_admin_value ei ole sallittu .htaccess-tiedostoissa. Sen paikka on Apachen palvelinasetuksissa tai VirtualHostissa, PHP-FPM:n kanssa pool-tiedostossa.

**Mitä tapahtuu, jos sovellus yrittää muuttaa lukittua arvoa?**  
Funktiokutsu ini_set() epäonnistuu ja palauttaa false, lukittu arvo säilyy. Hyvin ohjelmoidut sovellukset selviävät siitä. Tarkistakaa muutoksen jälkeen silti virheloki ja tärkeimmät toiminnot.

**Täytyykö poolin muutoksen jälkeen käynnistää uudelleen?**  
Kyllä. PHP-FPM lukee pool-tiedostot käynnistyksessä tai palvelun uudelleenlatauksessa. Apachella mod_php:n kanssa sama pätee palvelinasetuksiin. Ilman uudelleenkäynnistystä vanha arvo pysyy voimassa.

**Voiko disable_functions-asetusta laajentaa poolissa?**  
Kyllä, yhdellä erityispiirteellä: PHP-käsikirjan mukaan disable_functions FPM-poolissa ei ylikirjoita php.ini-tiedoston arvoja vaan täydentää niitä. Pooli voi siis estää lisää funktioita mutta ei vapauttaa yhtään.

## Lähteet

- [PHP-käsikirja: FPM-asetukset](https://www.php.net/manual/en/install.fpm.configuration.php)
- [PHP-käsikirja: asetusten muuttaminen](https://www.php.net/manual/en/configuration.changes.php)
- [PHP-käsikirja: asetusten muutostilat](https://www.php.net/manual/en/configuration.changes.modes.php)
- [php.net: tietoturvailmoitukset](https://www.php.net/)
