Stručne: open_basedir obmedzuje adresáre, ku ktorým môže PHP pristupovať. Samo o sebe je to len dodatočná bariéra. Účinná izolácia každého webu vzniká až v súhre: samostatný systémový používateľ, samostatný pool PHP-FPM, samostatný priečinok tmp a samostatné prístupy k databáze. Vtedy vniknutie na jeden web zostane obmedzené na tento web.
Prečo po PHP2Shell izolácia rozhoduje o rozsahu škody
Na mnohých serveroch bežia vedľa seba viaceré weby: firemná stránka, e-shop, stará kampaňová stránka, pri agentúrach často desiatky zákazníckych projektov. Často zdieľajú jedného systémového používateľa a jeden proces PHP. Ak sa jeden z nich kompromituje, všetky ostatné sú otvorené.
PHP2Shell toto riziko spresňuje. Zraniteľnosti CVE-2026-109618 a CVE-2026-109619 umožňujú vykonanie škodlivého kódu bez prihlásenia, nezávisle od CMS. Podľa správ médií bol prvý pokus o útok už 17. 10. 2026, záplaty nasledovali 21. 10. Riešením je aktualizácia. Či však útok v čase pred ňou zasiahne jeden web alebo desať, rozhoduje izolácia.
Pri druhej zraniteľnosti pribúda ďalšia úvaha: podľa projektu PHP môže vnútorný stav požiadavky pretrvať vo workerovi a môže ho využiť neskoršia požiadavka v tom istom workerovi. Oddelené pooly pre každý web zaisťujú, že si weby workerov aj tak nedelia.
Čo open_basedir dokáže
Pomocou open_basedir určíte zoznam adresárov. Súborové funkcie PHP ako fopen, include alebo file_get_contents potom odmietnu prístup ku všetkému mimo tohto zoznamu. Zavlečený skript tak nemôže bez ďalšieho čítať konfiguračné súbory susedného webu.
Hranice sú dôležité: kontrola prebieha vo vnútri PHP. Programy spustené mimo PHP jej nepodliehajú a chyby v interpreteri ju môžu obísť. Preto patrí open_basedir vždy spolu so zablokovanými systémovými funkciami, ako je opísané v príručke Správne používať disable_functions, a predovšetkým s oddelením na úrovni operačného systému.
Izolácia každého webu v štyroch vrstvách
Spoľahlivé oddelenie sa buduje na viacerých vrstvách. Každá zachytí to, čo predchádzajúca nezvládne.
| Vrstva | Opatrenie | Účinok |
|---|---|---|
| Operačný systém | samostatný systémový používateľ pre každý web | Súbory iných webov nie sú čitateľné |
| Procesy PHP | samostatný pool PHP-FPM s vlastným socketom | žiadny spoločný worker, vlastné nastavenia |
| Konfigurácia PHP | open_basedir, samostatný priečinok tmp a session |
dodatočná bariéra, žiadne spoločné dočasné súbory |
| Údaje | samostatný používateľ databázy s právami iba na vlastnú databázu | žiadny prístup k cudzím údajom zákazníkov |
Pri vysokej potrebe ochrany, napríklad pri e-shopoch so spracovaním platieb alebo portáloch so zdravotnými údajmi, pribúdajú kontajnery alebo oddelené servery.
Nastaviť open_basedir v poole PHP-FPM
Nasledujúca ukážka zobrazuje pool pre web so samostatným používateľom seite1. Cesty a číslo verzie prispôsobte svojmu systému.
; /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
Posledný riadok hneď nastavuje prechodné opatrenie php.net k PHP2Shell. Pôsobí iba z poolu, php.ini alebo konfigurácie servera, nie cez ini_set() alebo .user.ini. Priečinky založíte s vhodnými právami:
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
Ako by mali vyzerať práva v samotnom webovom adresári, popisuje príručka Práva k súborom na webovom serveri.
Pripojiť webový server a skontrolovať výsledok
V Nginx odkazuje každý web na svoj vlastný socket. Žiadna požiadavka tak nepristane v poole iného webu.
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;
}
}
Ďalšie pokyny k tejto kombinácii nájdete na stránke Zabezpečiť Nginx s PHP-FPM. Po reštarte skontrolujte, či pooly skutočne bežia oddelene:
sudo systemctl restart php8.3-fpm
# Každý pool by mal bežať pod vlastným používateľom
ps -eo user,pid,cmd | grep "[p]hp-fpm: pool"
Potom otestujte všetky funkcie webu: uploady, spracovanie obrázkov, cache, plánované úlohy. Chybové hlásenia s odkazom na open_basedir restriction v chybovom logu ukazujú, ktorá cesta ešte chýba. Dopĺňajte iba cesty, ktoré aplikácia skutočne potrebuje, a nikdy celý súborový systém.
Agentúry s mnohými zákazníckymi webmi by mali konfiguráciu poolu udržiavať ako vzor. Každý nový web tak dostane oddelenie automaticky, namiesto aby sa muselo dodatočne dopĺňať. Súvislosti pre tento prípad sú na stránke Bezpečnostný partner pre agentúry.
Typické úskalia pri prechode
Prechod na oddelené pooly sa dá naplánovať, má však niekoľko opakujúcich sa pascí. Najčastejšia sa týka zdieľaných knižníc: ak napríklad framework alebo priečinok s písmami leží mimo adresára webu, musí sa táto cesta pre čítanie pridať do open_basedir. Lepšie je takéto závislosti preniesť priamo do projektu.
Druhou pascou sú session. Ak sa zmení miesto ukladania, všetci návštevníci sa raz odhlásia a rozpracované košíky sa stratia. Prechod preto naplánujte do pokojného časového okna a interne ho oznámte.
Po tretie, plánované úlohy často bežia cez príkazový riadok, a teda pod iným používateľom než web. Skontrolujte cronjoby a fronty a nechajte ich bežať pod novým používateľom webu, inak vzniknú súbory s nesprávnym vlastníkom, ktoré PHP už nesmie meniť.
Napokon by mal mať každý pool vlastné limity pre procesy a pamäť. Web, ktorý sa dostane pod záťaž alebo je napadnutý, tak nemôže položiť ostatné.
Ako konkrétne pomáha PHP SOS?
- Zistíme, ktoré weby si dnes delia používateľov, procesy a databázy.
- Pre každý web zriadime samostatných používateľov, pooly, priečinky tmp a prístupy k databáze bez zmeny aplikácií.
- Po prechode otestujeme každý web a chýbajúce cesty cielene doplníme.
- Oddelenie zdokumentujeme ako vzor pre budúce projekty.
Ako to zapadá do celkovej koncepcie, popisuje služba Spevnenie servera pre webové servery PHP.
Časté otázky
Stačí open_basedir na oddelenie webov od seba?
Nie. open_basedir je dodatočná bariéra vo vnútri PHP, nie tvrdé oddelenie. Spoľahlivá je izolácia až so samostatnými systémovými používateľmi a poolmi pre každý web, pri vyššej potrebe ochrany s kontajnermi alebo oddelenými servermi.
Prečo po nastavení open_basedir prestali fungovať uploady?
Najčastejšie v zozname chýba priečinok pre dočasné súbory. Založte pre každý web samostatný priečinok tmp, zapíšte ho do open_basedir a nastavte upload_tmp_dir a sys_temp_dir na tento priečinok.
Môže aplikácia open_basedir sama zrušiť?
Aplikácia môže nastavenie za behu iba ďalej obmedziť, nie uvoľniť. Napriek tomu nastavte open_basedir cez php_admin_value v poole, aby bola hodnota jednoznačne daná.
Je izolácia možná aj pri zdieľanom hostingu?
To závisí od poskytovateľa. Mnohé ponuky oddeľujú zákazníkov samostatnými používateľmi a procesmi PHP. Opýtajte sa, ako je oddelenie realizované, najmä ak je viac vašich webov v jednom balíku.