# Least Privilege: права на потребителя на уеб сървъра

> Потребител на уеб сървъра с минимални права: без shell, sudo и cron, с ограничени права в базата и защита чрез systemd за PHP-FPM. С команди за проверка.

Източник: https://phpsos.de/bg/blog/rechte-des-webserver-benutzers/  
Актуалност: 25.10.2026  
Доставчик: PHP SOS, Спешна помощ за PHP и сигурност на сървъри. Незабавна помощ по WhatsApp: https://wa.me/491736494914?text=%D0%97%D0%B4%D1%80%D0%B0%D0%B2%D0%B5%D0%B9%D1%82%D0%B5%2C%20PHP%20SOS%2C%20%D0%B8%D0%BC%D0%B0%D0%BC%D0%B5%20%D0%BD%D1%83%D0%B6%D0%B4%D0%B0%20%D0%BE%D1%82%20%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%20%D1%81%20%D0%BD%D0%B0%D1%88%D0%B8%D1%8F%20PHP%20%D1%81%D1%8A%D1%80%D0%B2%D1%8A%D1%80.%20%D0%A4%D0%B8%D1%80%D0%BC%D0%B0%3A%20%E2%80%A6%20%D0%A3%D0%B5%D0%B1%D1%81%D0%B0%D0%B9%D1%82%3A%20%E2%80%A6

**Накратко:** Потребителят на уеб сървъра, под който работи PHP, трябва по принципа на минималните права (Least Privilege) да чете само онова, което е нужно на уебсайта, и да записва само там, където сайтът съхранява данни. Той няма shell за вход, няма sudo права, няма собствени cron задачи и няма SSH ключове, а акаунтът му в базата данни може само да чете и променя данни. Опции на systemd като `ProtectSystem` и `PrivateTmp` ограничават допълнително PHP-FPM.

## Въпросът след пробива: какво може този процес?

При PHP2Shell става дума за отдалечено изпълнение на злонамерен код без вход в системата. Ако успее, кодът не работи във вакуум, а като съвсем определен потребител: потребителят на PHP процеса. Всичко, което този потребител може, от този момент може и атакуващият.

На много сървъри това е учудващо много. Потребителят притежава целия програмен код, има shell, може да създава собствени cron задачи, а акаунтът на приложението в базата данни има всички права върху всички бази. За атакуващия това е идеалната отправна точка, за да се закрепи за постоянно.

Как да зададете правилно правата на файлове и папки, описва наръчникът [Права на файловете на уеб сървъра](https://phpsos.de/bg/ratgeber/dateirechte-webserver/). Тази статия разглежда самия акаунт: вход, специални права, планирани задачи, база данни и границите, които налага systemd.

## Опис: кой е потребителят на уеб сървъра?

Първо изяснете кои потребители изобщо участват. При PHP-FPM всеки пул определя с `user` и `group` под кого работят неговите работни процеси. При mod_php PHP работи като потребителя на Apache. Как главният процес и работните процеси взаимодействат при PHP-FPM, обяснява [PHP-FPM обяснено: мениджър на процеси, пулове и работни процеси](https://phpsos.de/bg/php/php-fpm-erklaert/). Следващите команди само четат:

```bash
# Под кои потребители работят уеб сървърът и PHP?
ps -eo user,group,cmd | grep -E "[p]hp-fpm|[n]ginx|[a]pache2|[h]ttpd" | sort | uniq -c
# Данни за акаунта: домашна директория и shell (съобразете потребителя)
getent passwd www-data
# Има ли потребителят sudo права?
sudo -l -U www-data
# Собствени cron задачи?
sudo crontab -l -u www-data
# SSH ключове в домашната директория (при Debian/Ubuntu това е /var/www)
sudo ls -la /var/www/.ssh 2>/dev/null
```

Запишете резултатите за всеки потребител на пул. Ако всички уебсайтове работят под един и същ потребител, това е първата точка в списъка; как да ги разделите, описва [Изолирайте PHP-FPM пуловете за всеки уебсайт](https://phpsos.de/bg/blog/php-fpm-pools-isolieren/).

## Права на потребителя на уеб сървъра: от какво акаунтът няма нужда

Следващият преглед показва от какво един потребител на уеб сървъра обикновено няма нужда и как да му го отнемете.

| Право | Защо е опасно | Препоръка |
|---|---|---|
| Shell за вход | Възможни са вход и интерактивна работа | Shell `/usr/sbin/nologin` |
| Записи за sudo | Път към права на root | Без записи, дори за отделни команди |
| Собствена crontab | Постоянна задна врата, която оцелява при всеки рестарт | Без такава, ограничете с `/etc/cron.allow` |
| SSH ключове | Вход отвън | Без `authorized_keys` |
| Собственост върху програмния код | Кодът може да бъде променян | Собственик е потребител за внедряване (Deploy) |
| Права за запис извън папките с данни | Поставяне на злонамерен код | Само качени файлове, кеш, Temp |
| Пълни права в базата данни | Бази на други приложения, достъп до файлове през базата | Само собствената база, само права върху данните |

Shell се задава с `usermod -s /usr/sbin/nologin www-data`. За cron важи: ако съществува `/etc/cron.allow`, само изброените там потребители могат да създават собствени cron задачи. Новосъздадени cron задачи или непознати SSH ключове са типичен признак, че някой се е закрепил. Особено ясен предупредителен сигнал описва статията [Предупредителен сигнал: уеб сървърът стартира shell](https://phpsos.de/bg/blog/webserver-startet-shell/).

## Базата данни: ограничете правата до необходимото

Акаунтът на един уебсайт в базата данни е фактически втори потребител на уеб сървъра. Данните му за достъп се намират в конфигурационния файл на приложението и са четими за внедрен код. Затова той трябва да може само онова, което приложението изисква в нормална работа.

```sql
-- Пример MySQL/MariaDB: отделен акаунт за всеки уебсайт, само права върху данните
CREATE USER 'seite1'@'localhost' IDENTIFIED BY 'hier-ein-langes-Zufallspasswort';
GRANT SELECT, INSERT, UPDATE, DELETE ON seite1.* TO 'seite1'@'localhost';
-- Проверка на правата
SHOW GRANTS FOR 'seite1'@'localhost';
```

Права като `FILE`, `SUPER` или `GRANT OPTION` и достъп до `*.*` не са нужни на акаунта на приложението. Много CMS за актуализации изискват допълнително `CREATE`, `ALTER`, `INDEX` и `DROP`. По-чисто решение е отделен акаунт за актуализации и миграции, който се използва само по време на поддръжка. Проверете изискванията в документацията на производителя.

## Допълнително ограничаване на PHP-FPM със systemd

systemd може да ограничи изгледа на една услуга към системата. За PHP-FPM особено подходящи са няколко опции от документацията на systemd. Те действат и върху главния процес, който стартира като root.

```ini
# sudo systemctl edit php8.3-fpm
[Service]
# /usr, /boot и /etc само за четене
ProtectSystem=full
# /home, /root и /run/user невидими
ProtectHome=true
# собствени /tmp и /var/tmp само за тази услуга
PrivateTmp=true
# без разширяване на правата чрез setuid или capabilities на файлове
NoNewPrivileges=true
```

Тествайте тези опции, преди да ги въведете в продукция. Ако уебсайтовете се намират в `/home`, `ProtectHome=true` пречи на достъпа. `NoNewPrivileges=true` може да попречи на програми, които PHP извиква и които при стартиране сменят груповите си права, например някои локални пощенски програми за функцията `mail()` на PHP. Затова действайте на стъпки:

1. Добавете една опция, рестартирайте услугата, проверете `systemctl status php8.3-fpm`.
2. Тествайте основните функции на уебсайта: вход, формуляри, изпращане на поща, качване на файлове, cron задачите на приложението.
3. Прегледайте журнала с грешки на PHP-FPM и на приложението.
4. Едва тогава добавете следващата опция.

Накрая сокетът: според наръчника на PHP по подразбиране той получава права `0660` за потребителя и групата на пула. Задайте `listen.owner` и `listen.group` така, че да може да се свързва само уеб сървърът, а не всеки локален потребител.

> **Съвет:**
> Минималните права са основна нагласа, а не еднократен проект. Повторете описа от тази статия след всяка реорганизация и при всеки нов уебсайт, защото новите услуги често идват с щедри права по подразбиране.

## Заключение: атакуващият наследява онова, което позволите

Least Privilege звучи като теория, но е съвсем практичен въпрос: какво може да направи някой, който изпълнява код като потребител на уеб сървъра? На сървър с shell, запис за sudo, собствена crontab и акаунт в базата данни с всички права отговорът е: почти всичко. На ограничен сървър нещата по-скоро остават в рамките на инцидент в един-единствен уебсайт, който може да бъде разпознат и почистен.

Преминаването не изисква нов софтуер, а само внимателен опис и постепенни тестове. Започнете с точките, които едва ли могат да счупят нещо, тоест shell, sudo и SSH ключове, и после продължете към правата в базата данни и опциите на systemd.

## Как помага PHP SOS конкретно?

- **Проверка на акаунтите:** За всеки пул и уеб сървър отчитаме потребител, shell, записи за sudo, cron задачи, SSH ключове и права в базата данни.
- **Намаляване на правата:** Отнемаме онова, което не е нужно, и разделяме акаунтите за внедряване, за изпълнение и за поддръжка.
- **Ограничаване на услугите:** Въвеждаме защитните опции на systemd стъпка по стъпка и тестваме уебсайта след всяка стъпка.
- **Поддържане във времето:** В рамките на [заздравяването на сървъра](https://phpsos.de/bg/leistungen/server-haertung/) документираме концепцията за правата за бъдещи промени.


## Често задавани въпроси

**Под кой потребител работи PHP на моя сървър?**  
Това зависи от режима на работа. При mod_php PHP работи като потребителя на Apache, например www-data или apache. При PHP-FPM всеки пул определя своя потребител чрез user и group; главният процес обикновено работи като root, а работните процеси (worker) като потребителя на пула. Командата ps го показва бързо.

**Нужен ли е на потребителя на уеб сървъра shell за вход?**  
Не. Нито Nginx, нито Apache, нито PHP-FPM изискват интерактивен вход за този потребител. Shell като /usr/sbin/nologin пречи на всеки да влезе с този акаунт. Внедряванията (deployment) се извършват с отделен потребител.

**Защо www-data да няма sudo права, дори за една-единствена команда?**  
Защото внедреният код наследява точно тези права. Дори на пръв поглед безобидна команда, ако е разрешена неправилно, може да доведе до права на root. Задачите, които изискват повишени права, трябва да се поемат от отделни услуги или процеси извън уеб сървъра.

**Помага ли това срещу PHP2Shell?**  
То не затваря уязвимостта; за това са необходими актуализацията на PHP и рестартът на всички работни процеси. Минималните права обаче ограничават какво може да направи атакуващият след успешна експлоатация: да променя файлове, да се закрепи в системата, да достигне други уебсайтове.

## Източници

- [Наръчник на PHP: конфигурация на FPM (user, listen.mode)](https://www.php.net/manual/en/install.fpm.configuration.php)
- [systemd.exec (ProtectSystem, PrivateTmp, NoNewPrivileges)](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html)
- [BSI IT-Grundschutz](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
