Aktuálna situácia: PHP2Shell. Dve kritické zraniteľnosti PHP (CVSS 9.2) umožňujú spustenie škodlivého kódu bez prihlásenia. Záplaty od 21. 10. 2026.Čo treba urobiť teraz →

open_basedir a izolácia každého webu

Ako pomocou open_basedir, samostatných systémových používateľov a oddelených poolov PHP-FPM zabrániť tomu, aby vniknutie na jeden web zasiahlo všetky ostatné na serveri.

Stav 5 min čítaniaPríručky

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.

Tip

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.

Zdroje

Okamžitý kontakt

Každá hodina sa počíta. Napíšte nám hneď.

Stručne opíšte systém, verziu PHP a svoje pozorovanie. Ozveme sa, vyjasníme situáciu a budeme pracovať na diaľku, kým nebude incident uzavretý a zdokumentovaný.

Okamžitá pomoc