Текуща ситуация: PHP2Shell. Две критични уязвимости в PHP (CVSS 9,2) позволяват злонамерен код без вход. Корекции от 21.10.2026 г.Какво да направите сега →

open_basedir и изолация за всеки уебсайт

Как с open_basedir, отделни системни потребители и разделени PHP-FPM пулове да попречите проникването в един уебсайт да засегне всички останали на сървъра.

Актуалност 5 мин. четенеНаръчници

Накратко: open_basedir ограничава директориите, до които PHP има достъп. Сама по себе си това е само допълнителна бариера. Ефективна изолация за всеки уебсайт се получава едва от взаимодействието: отделен системен потребител, отделен PHP-FPM пул, отделна temp папка и отделни достъпи до базата данни. Тогава проникването в един уебсайт остава ограничено до него.

Защо изолацията след PHP2Shell решава какви са щетите

На много сървъри работят няколко уебсайта един до друг: фирменият сайт, магазин, стара кампанийна страница, а при агенциите често десетки клиентски проекта. Често те споделят един системен потребител и един PHP процес. Ако един от тях бъде компрометиран, всички останали са изложени.

PHP2Shell прави този риск осезаем. Уязвимостите CVE-2026-109618 и CVE-2026-109619 позволяват изпълнение на злонамерен код без вход в системата, независимо от CMS. Според медийни съобщения още на 17.10.2026 е имало първи опит за атака, а пачовете последваха на 21.10. Решението е актуализацията. Дали една атака в предходния период засяга един или десет уебсайта обаче решава изолацията.

Особено при втората уязвимост се добавя още една мисъл: според проекта PHP вътрешното състояние на една заявка може да остане в worker процеса и да бъде използвано от по-късна заявка в същия worker. Отделните пулове за всеки уебсайт гарантират, че уебсайтовете така или иначе не споделят worker процеси.

Какво постига open_basedir

С open_basedir определяте списък от директории. Файловите функции на PHP като fopen, include или file_get_contents тогава отказват достъп до всичко извън този списък. Внедрен скрипт така не може лесно да чете конфигурационните файлове на съседния уебсайт.

Границите са важни: проверката се извършва в рамките на PHP. Програми, стартирани извън PHP, не са обект на нея, а грешки в интерпретатора могат да я заобиколят. Затова open_basedir винаги принадлежи заедно със заключени системни функции, както е описано в наръчника Правилно използване на disable_functions, и преди всичко с разделяне на ниво операционна система.

Изолация за всеки уебсайт в четири слоя

Устойчивото разделяне се гради на няколко слоя. Всеки улавя това, което предходният не постига.

Слой Мярка Ефект
Операционна система отделен системен потребител за всеки уебсайт Файловете на други уебсайтове не могат да се четат
PHP процеси отделен PHP-FPM пул със собствен сокет няма общ worker, собствени настройки
PHP конфигурация open_basedir, отделна tmp и session папка допълнителна бариера, няма общи временни файлове
Данни отделен потребител на базата данни с права само за собствената база няма достъп до чужди данни на клиенти

При висока нужда от защита, например при магазини с обработка на плащания или портали със здравни данни, се добавят контейнери или разделени сървъри.

Конфигуриране на open_basedir в PHP-FPM пула

Следният пример показва пул за уебсайт със собствен потребител seite1. Пътищата и номера на версията адаптирайте към Вашата система.

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

Последният ред веднага въвежда и преходната мярка на php.net за PHP2Shell. Тя действа само от пула, php.ini или конфигурацията на сървъра, не чрез ini_set() или .user.ini. Папките създавате с подходящи права:

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

Как трябва да изглеждат правата в самата уеб директория, описва наръчникът Права за файлове на уеб сървъра.

Свързване на уеб сървъра и проверка на резултата

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

Допълнителни указания за тази комбинация ще намерите на страницата Защита на Nginx с PHP-FPM. След рестарта проверете дали пуловете действително работят разделено:

sudo systemctl restart php8.3-fpm
# Всеки пул трябва да работи под собствения си потребител
ps -eo user,pid,cmd | grep "[p]hp-fpm: pool"

След това тествайте всички функции на уебсайта: качвания, обработка на изображения, кешове, планирани задачи. Съобщенията за грешки с указание open_basedir restriction в лога на грешките показват кой път още липсва. Добавяйте само пътища, които приложението действително изисква, и никога цялата файлова система.

Съвет

Агенциите с много клиентски сайтове трябва да поддържат конфигурацията на пула като шаблон. Така всеки нов уебсайт получава разделянето автоматично, вместо да се налага по-късно да го добавяте. Основна информация за този случай има на страницата Партньор по сигурността за агенции.

Типични спънки при преминаването

Преминаването към разделени пулове е планируемо, но има няколко повтарящи се капана. Най-честият засяга споделените библиотеки: ако например фреймуърк или папка с шрифтове е извън директорията на уебсайта, този път трябва да се добави само за четене в open_basedir. По-добре е такива зависимости да се пренесат в самия проект.

Вторият капан са сесиите. Ако мястото за съхранение се смени, всички посетители веднъж се отписват, а текущите кошници се губят. Затова планирайте преминаването в спокоен времеви прозорец и го обявете вътрешно.

Трето, планираните задачи често се изпълняват през командния ред и така под друг потребител от уебсайта. Проверете cron задачите и опашките и ги пуснете под новия потребител на уебсайта, иначе се получават файлове с грешен собственик, които PHP по-късно не може да променя.

Накрая, всеки пул трябва да има собствени граници за процеси и памет. Уебсайт, който попада под натоварване или бива атакуван, така не може да повали и останалите.

Как конкретно помага PHP SOS?

  • Установяваме кои уебсайтове днес споделят потребители, процеси и бази данни.
  • Създаваме за всеки уебсайт отделни потребители, пулове, temp папки и достъпи до базата данни, без да променяме приложенията.
  • Тестваме всеки уебсайт след преминаването и отстраняваме целенасочено липсващите пътища.
  • Документираме разделянето като шаблон за бъдещи проекти.

Как това се вписва в цялостна концепция, описва услугата Заздравяване на сървъри за PHP уеб сървъри.

Често задавани въпроси

Достатъчно ли е open_basedir, за да се разделят уебсайтовете един от друг?

Не. open_basedir е допълнителна бариера в рамките на PHP, а не твърдо разделяне. Изолацията става надеждна едва с отделни системни потребители и пулове за всеки уебсайт, а при по-висока нужда от защита с контейнери или разделени сървъри.

Защо след задаването на open_basedir качванията вече не работят?

Обикновено в списъка липсва папката за временни файлове. Създайте за всеки уебсайт собствена tmp папка, впишете я в open_basedir и задайте upload_tmp_dir и sys_temp_dir на тази папка.

Може ли приложението само да отмени open_basedir?

Приложението може да ограничи настройката по време на изпълнение само допълнително, но не и да я облекчи. Все пак задайте open_basedir чрез php_admin_value в пула, за да е стойността еднозначно фиксирана.

Възможна ли е изолация и при споделен хостинг?

Това зависи от хостинг доставчика. Много оферти разделят клиентите чрез отделни потребители и PHP процеси. Попитайте как е реализирано разделянето, особено ако няколко Ваши уебсайта са в един пакет.

Източници

Незабавен контакт

Всеки час има значение. Пишете ни сега.

Опишете накратко системата, версията на PHP и какво сте забелязали. Ние се свързваме с Вас, уточняваме ситуацията и работим отдалечено, докато инцидентът бъде приключен и документиран.

Незабавна помощ