# open_basedir en isolatie per website

> open_basedir goed instellen en websites netjes scheiden: eigen gebruiker, eigen PHP-FPM-pool, eigen tmp-mappen. Met voorbeeldconfiguratie voor Nginx.

Bron: https://phpsos.de/nl/ratgeber/open-basedir/  
Stand: 25-10-2026  
Aanbieder: PHP SOS, PHP-noodhulp en serverbeveiliging. Directe hulp via WhatsApp: https://wa.me/491736494914?text=Hallo%20PHP%20SOS%2C%20wij%20hebben%20hulp%20nodig%20met%20onze%20PHP-server.%20Bedrijf%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kort gezegd:** `open_basedir` beperkt de mappen waartoe PHP toegang heeft. Alleen is dat slechts een extra barrière. Werkzame isolatie per website ontstaat pas in samenspel: eigen systeemgebruiker, eigen PHP-FPM-pool, eigen tmp-map en eigen databasetoegangen. Dan blijft een inbraak op één website beperkt tot die website.

## Waarom isolatie na PHP2Shell de schade bepaalt

Op veel servers draaien meerdere websites naast elkaar: de bedrijfssite, een webshop, een oude campagnesite, bij bureaus vaak tientallen klantprojecten. Vaak delen ze één systeemgebruiker en één PHP-proces. Wordt er één gecompromitteerd, dan liggen alle andere open.

PHP2Shell maakt dit risico tastbaar. De kwetsbaarheden CVE-2026-109618 en CVE-2026-109619 maken het mogelijk zonder aanmelding schadelijke code uit te voeren, onafhankelijk van het CMS. Volgens mediaberichten was er al op 17-10-2026 een eerste aanvalspoging, de patches volgden op 21-10. De oplossing is de update. Of een aanval in de tijd daarvoor één of tien websites treft, bepaalt echter de isolatie.

Bij de tweede kwetsbaarheid komt nog een gedachte bij: volgens het PHP-project kan de interne toestand van een verzoek in een worker blijven bestaan en door een later verzoek in dezelfde worker worden gebruikt. Gescheiden pools per website zorgen ervoor dat websites hoe dan ook geen workers delen.

## Wat open_basedir doet

Met `open_basedir` legt u een lijst van mappen vast. Bestandsfuncties van PHP zoals `fopen`, `include` of `file_get_contents` weigeren dan toegang tot alles buiten die lijst. Een binnengebracht script kan zo niet zomaar de configuratiebestanden van de buurwebsite lezen.

De grenzen zijn belangrijk: de controle vindt plaats binnen PHP. Programma's die buiten PHP worden gestart vallen er niet onder en fouten in de interpreter kunnen haar omzeilen. Daarom hoort `open_basedir` altijd samen met geblokkeerde systeemfuncties, zoals beschreven in de gids [disable_functions correct inzetten](https://phpsos.de/nl/ratgeber/disable-functions/), en vooral met scheiding op het niveau van het besturingssysteem.

## Isolatie per website in vier lagen

Een stevige scheiding bouwt op meerdere lagen. Elke laag vangt op wat de vorige niet kan.

| Laag | Maatregel | Werking |
|---|---|---|
| Besturingssysteem | eigen systeemgebruiker per website | Bestanden van andere websites zijn niet leesbaar |
| PHP-processen | eigen PHP-FPM-pool met eigen socket | geen gedeelde worker, eigen instellingen |
| PHP-configuratie | `open_basedir`, eigen tmp- en sessiemap | extra barrière, geen gedeelde tijdelijke bestanden |
| Gegevens | eigen databasegebruiker met rechten alleen op de eigen database | geen toegang tot vreemde klantgegevens |

Bij hoge beschermingsbehoefte, bijvoorbeeld bij webshops met betalingsafhandeling of portalen met gezondheidsgegevens, komen containers of gescheiden servers erbij.

## open_basedir in de PHP-FPM-pool configureren

Het volgende voorbeeld toont een pool voor een website met eigen gebruiker `seite1`. Paden en versienummer past u aan uw systeem aan.

```ini
; /etc/php/8.3/fpm/pool.d/seite1.conf
[seite1]
user = seite1
group = seite1
listen = /run/php/seite1.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = ondemand
pm.max_children = 10

php_admin_value[open_basedir] = /var/www/seite1/:/var/www/seite1-tmp/
php_admin_value[upload_tmp_dir] = /var/www/seite1-tmp/
php_admin_value[sys_temp_dir] = /var/www/seite1-tmp/
php_admin_value[session.save_path] = /var/www/seite1-tmp/sessions
php_admin_value[error_log] = /var/log/php/seite1.error.log
php_admin_flag[session.upload_progress.enabled] = off
```

De laatste regel zet meteen de PHP2Shell-tussenmaatregel van php.net. Ze werkt alleen vanuit pool, php.ini of serverconfiguratie, niet via `ini_set()` of `.user.ini`. De mappen maakt u aan met passende rechten:

```bash
sudo useradd --system --home /var/www/seite1 --shell /usr/sbin/nologin seite1
sudo mkdir -p /var/www/seite1-tmp/sessions
sudo chown -R seite1:seite1 /var/www/seite1-tmp
sudo chmod 700 /var/www/seite1-tmp
```

Hoe de rechten in de eigenlijke webmap eruit moeten zien, beschrijft de gids [Bestandsrechten op de webserver](https://phpsos.de/nl/ratgeber/dateirechte-webserver/).

## Webserver koppelen en resultaat controleren

In Nginx verwijst elke website naar haar eigen socket. Zo komt geen verzoek terecht in de pool van een andere website.

```nginx
server {
    server_name seite1.example;
    root /var/www/seite1/public;

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/seite1.sock;
    }
}
```

Meer aanwijzingen over deze combinatie vindt u onder [Nginx met PHP-FPM beveiligen](https://phpsos.de/nl/server/nginx-php-fpm/). Na de herstart controleert u of de pools echt gescheiden draaien:

```bash
sudo systemctl restart php8.3-fpm
# Elke pool hoort onder zijn eigen gebruiker te draaien
ps -eo user,pid,cmd | grep "[p]hp-fpm: pool"
```

Test vervolgens alle functies van de website: uploads, beeldverwerking, caches, geplande taken. Foutmeldingen met de vermelding `open_basedir restriction` in het foutlog laten zien welk pad nog ontbreekt. Vul alleen paden aan die de toepassing echt nodig heeft, en nooit het hele bestandssysteem.

> **Tip:**
> Bureaus met veel klantsites moeten de poolconfiguratie als sjabloon onderhouden. Zo krijgt elke nieuwe website de scheiding automatisch, in plaats van dat ze later moet worden nagerust. Achtergronden voor dit geval staan onder [Beveiligingspartner voor bureaus](https://phpsos.de/nl/branchen/agenturen-white-label/).

## Typische valkuilen bij de omschakeling

De omschakeling naar gescheiden pools is plannen, maar kent enkele terugkerende valkuilen. De meest voorkomende betreft gedeelde bibliotheken: ligt bijvoorbeeld een framework of een map met lettertypen buiten de websitemap, dan moet dat pad leesbaar in `open_basedir` worden opgenomen. Beter is het zulke afhankelijkheden in het project zelf binnen te halen.

De tweede valkuil zijn sessies. Verandert de opslaglocatie, dan zijn alle bezoekers één keer afgemeld en gaan lopende winkelmandjes verloren. Plan de omschakeling daarom in een rustig tijdvenster en kondig haar intern aan.

Ten derde lopen geplande taken vaak via de opdrachtregel en dus onder een andere gebruiker dan de website. Controleer cronjobs en wachtrijen en laat ze onder de nieuwe websitegebruiker draaien, anders ontstaan bestanden met de verkeerde eigenaar die PHP later niet meer mag wijzigen.

Tot slot moet elke pool eigen grenzen voor processen en geheugen hebben. Een website die onder belasting komt of wordt aangevallen, kan zo de andere niet mee op de knieën dwingen.

## Hoe helpt PHP SOS concreet?

- We inventariseren welke websites nu gebruikers, processen en databases delen.
- We richten per website eigen gebruikers, pools, tmp-mappen en databasetoegangen in, zonder de toepassingen te wijzigen.
- We testen elke website na de omschakeling en verhelpen ontbrekende paden gericht.
- We documenteren de scheiding als sjabloon voor toekomstige projecten.

Hoe dat in een totaalconcept past, beschrijft de dienst [Serververharding voor PHP-webservers](https://phpsos.de/nl/leistungen/server-haertung/).


## Veelgestelde vragen

**Volstaat open_basedir om websites van elkaar te scheiden?**  
Nee. open_basedir is een extra barrière binnen PHP, geen harde scheiding. Betrouwbaar wordt de isolatie pas met eigen systeemgebruikers en pools per website, bij hogere beschermingsbehoefte met containers of gescheiden servers.

**Waarom werken uploads niet meer nadat ik open_basedir heb ingesteld?**  
Meestal ontbreekt de map voor tijdelijke bestanden in de lijst. Maak voor elke website een eigen tmp-map aan, neem die op in open_basedir en zet upload_tmp_dir en sys_temp_dir op deze map.

**Kan een toepassing open_basedir zelf opheffen?**  
Een toepassing kan de instelling tijdens de uitvoering alleen verder beperken, niet versoepelen. Stel open_basedir toch in via php_admin_value in de pool, zodat de waarde eenduidig vastligt.

**Is isolatie ook mogelijk bij shared hosting?**  
Dat ligt bij de hoster. Veel aanbieders scheiden klanten via eigen gebruikers en PHP-processen. Vraag na hoe de scheiding is uitgevoerd, vooral als meerdere van uw websites in één pakket zitten.

## Bronnen

- [php.net: beveiligingsmeldingen](https://www.php.net/)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
- [BSI IT-Grundschutz (basisbeveiliging van de Duitse federale dienst voor informatiebeveiliging)](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
