Aktuel situation: PHP2Shell. To kritiske PHP-sårbarheder (CVSS 9,2) tillader skadelig kode uden login. Rettelser siden 21.10.2026.Hvad der skal gøres nu →

open_basedir og isolation pr. website

Sådan forhindrer I med open_basedir, egne systembrugere og adskilte PHP-FPM-pools, at et indbrud i ét website rammer alle andre på serveren.

Status 5 min. læsetidVejledninger

Kort sagt: open_basedir begrænser de mapper, som PHP må tilgå. Alene er det blot en ekstra spærring. Virksom isolation pr. website opstår først i samspil: egen systembruger, egen PHP-FPM-pool, egen temp-mappe og egne databaseadgange. Så forbliver et indbrud i ét website begrænset til dette website.

Hvorfor isolation efter PHP2Shell afgør skadens omfang

På mange servere kører flere websites side om side: firmasitet, en shop, en gammel kampagneside, hos bureauer ofte dusinvis af kundeprojekter. Ofte deler de en systembruger og en PHP-proces. Bliver ét af dem kompromitteret, ligger alle de andre åbne.

PHP2Shell gør denne risiko håndgribelig. Sårbarhederne CVE-2026-109618 og CVE-2026-109619 muliggør kørsel af skadelig kode uden login, uafhængigt af CMS'et. Ifølge medierapporter var der allerede den 17.10.2026 et første angrebsforsøg, rettelserne fulgte den 21.10. Løsningen er opdateringen. Om et angreb i tiden før rammer ét eller ti websites, afgør dog isolationen.

Netop ved den anden sårbarhed kommer en yderligere tanke til: Ifølge PHP-projektet kan en forespørgsels interne tilstand blive bestående i en worker og blive brugt af en senere forespørgsel i samme worker. Adskilte pools pr. website sørger for, at websites under alle omstændigheder ikke deler workere.

Hvad open_basedir kan

Med open_basedir fastlægger I en liste af mapper. PHP's filfunktioner som fopen, include eller file_get_contents nægter så adgang til alt uden for denne liste. Et indsmuglet script kan på den måde ikke uden videre læse nabowebsitets konfigurationsfiler.

Grænserne er vigtige: Kontrollen foregår inde i PHP. Programmer, der startes uden for PHP, er ikke underlagt den, og fejl i fortolkeren kan omgå den. Derfor hører open_basedir altid sammen med spærrede systemfunktioner, som beskrevet i vejledningen Brug disable_functions korrekt, og især med adskillelse på operativsystemniveau.

Isolation pr. website i fire lag

En pålidelig adskillelse bygger på flere lag. Hvert lag fanger det, som det foregående ikke klarer.

Lag Foranstaltning Virkning
Operativsystem egen systembruger pr. website andre websites' filer kan ikke læses
PHP-processer egen PHP-FPM-pool med egen socket ingen fælles worker, egne indstillinger
PHP-konfiguration open_basedir, egen tmp- og sessionmappe ekstra spærring, ingen fælles temp-filer
Data egen databasebruger med rettigheder kun til egen database ingen adgang til fremmede kundedata

Ved højt beskyttelsesbehov, f.eks. ved shops med betalingsafvikling eller portaler med sundhedsdata, kommer containere eller adskilte servere til.

Konfigurér open_basedir i PHP-FPM-poolen

Det følgende eksempel viser en pool til et website med egen bruger seite1. Stier og versionsnummer tilpasser I til jeres system.

; /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

Den sidste linje sætter samtidig PHP2Shell-overgangsforanstaltningen fra php.net. Den virker kun fra pool, php.ini eller serverkonfiguration, ikke via ini_set() eller .user.ini. Mapperne opretter I med passende rettigheder:

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

Hvordan rettighederne i selve webmappen bør se ud, beskriver vejledningen Filrettigheder på webserveren.

Tilslut webserveren og kontrollér resultatet

I Nginx peger hvert website på sin egen socket. Så havner ingen forespørgsel i et andet websites pool.

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;
    }
}

Yderligere henvisninger til denne kombination finder I under Sikr Nginx med PHP-FPM. Efter genstarten kontrollerer I, om poolene faktisk kører adskilt:

sudo systemctl restart php8.3-fpm
# Hver pool bør køre under sin egen bruger
ps -eo user,pid,cmd | grep "[p]hp-fpm: pool"

Test derefter alle funktioner på websitet: uploads, billedbehandling, caches, planlagte opgaver. Fejlmeddelelser med henvisning til open_basedir restriction i fejlloggen viser, hvilken sti der stadig mangler. Tilføj kun stier, som applikationen virkelig har brug for, og aldrig hele filsystemet.

Tip

Bureauer med mange kundesider bør vedligeholde pool-konfigurationen som skabelon. Så får hvert nyt website adskillelsen automatisk i stedet for at skulle eftermonteres senere. Baggrund for dette tilfælde står under Sikkerhedspartner for bureauer.

Typiske faldgruber ved omstillingen

Omstillingen til adskilte pools kan planlægges, men har nogle tilbagevendende fælder. Den hyppigste berører fælles anvendte biblioteker: Ligger f.eks. et framework eller en mappe med skrifttyper uden for websitets mappe, skal denne sti optages læsende i open_basedir. Bedre er det at hente sådanne afhængigheder ind i selve projektet.

Den anden fælde er sessioner. Skifter lagringsstedet, bliver alle besøgende logget af én gang, og igangværende indkøbskurve går tabt. Planlæg derfor omstillingen i et roligt tidsvindue, og varsl den internt.

For det tredje kører planlagte opgaver ofte via kommandolinjen og dermed under en anden bruger end websitet. Kontrollér cronjobs og køer, og lad dem køre under den nye website-bruger, ellers opstår der filer med forkert ejer, som PHP senere ikke må ændre.

Endelig bør hver pool have egne grænser for processer og hukommelse. Et website, der kommer under belastning eller angribes, kan så ikke tvinge de andre i knæ.

Hvordan hjælper PHP SOS konkret?

  • Vi kortlægger, hvilke websites der i dag deler bruger, processer og databaser.
  • Vi opretter egne brugere, pools, temp-mapper og databaseadgange pr. website uden at ændre applikationerne.
  • Vi tester hvert website efter omstillingen og udbedrer manglende stier målrettet.
  • Vi dokumenterer adskillelsen som skabelon til fremtidige projekter.

Hvordan det passer ind i et samlet koncept, beskriver ydelsen Serverhærdning til PHP-webservere.

Ofte stillede spørgsmål

Er open_basedir nok til at adskille websites fra hinanden?

Nej. open_basedir er en ekstra spærring inde i PHP, ikke en hård adskillelse. Isolationen bliver først pålidelig med egne systembrugere og pools pr. website, ved højere beskyttelsesbehov med containere eller adskilte servere.

Hvorfor virker uploads ikke længere, efter at jeg har sat open_basedir?

Oftest mangler mappen til midlertidige filer på listen. Opret en egen tmp-mappe til hvert website, før den ind i open_basedir, og sæt upload_tmp_dir og sys_temp_dir til denne mappe.

Kan en applikation selv ophæve open_basedir?

En applikation kan under kørslen kun skærpe indstillingen yderligere, ikke lempe den. Sæt alligevel open_basedir via php_admin_value i poolen, så værdien ligger entydigt fast.

Er isolation også mulig ved shared hosting?

Det afhænger af hosteren. Mange tilbud adskiller kunder via egne brugere og PHP-processer. Spørg, hvordan adskillelsen er gennemført, især hvis flere af jeres websites ligger i én pakke.

Kilder

Akut kontakt

Hver time tæller. Skriv til os nu.

Beskriv kort system, PHP-version og observation. Vi vender tilbage, afklarer situationen og arbejder på afstand, indtil hændelsen er afsluttet og dokumenteret.

Akut hjælp