Dabartinė padėtis: PHP2Shell. Du kritiniai PHP pažeidžiamumai (CVSS 9,2) leidžia vykdyti kenkėjišką kodą be prisijungimo. Pataisos nuo 2026-10-21.Ką dabar daryti →

Least Privilege: žiniatinklio serverio naudotojo teisės

Įterptas kodas veikia su žiniatinklio serverio naudotojo teisėmis. Ką ši paskyra gali daryti, lemia, kaip toli nueis užpuolikas. Štai kaip apriboti shell, sudo, cron, duomenų bazę ir failų sistemą iki būtino minimumo.

Būsena 5 min. skaitymoSutvirtinimas ir konfigūracija

Trumpai: žiniatinklio serverio naudotojas, kuriuo veikia PHP, pagal mažiausių teisių principą (Least Privilege) turėtų skaityti tik tai, ko reikia svetainei, ir rašyti tik ten, kur ji saugo duomenis. Jis neturi prisijungimo shell, sudo teisių, savų cron užduočių ir SSH raktų, o jo duomenų bazės paskyra gali tik skaityti ir keisti duomenis. systemd parinktys, tokios kaip ProtectSystem ir PrivateTmp, papildomai apriboja PHP-FPM.

Klausimas po įsilaužimo: ką šis procesas gali daryti?

PHP2Shell atveju kalbama apie kenkėjiško kodo vykdymą nuotoliu be prisijungimo. Jei tai pavyksta, kodas veikia ne tuštumoje, o kaip konkretus naudotojas: PHP proceso naudotojas. Viską, ką šis naudotojas gali, nuo to momento gali ir užpuolikas.

Daugelyje serverių to stebėtinai daug. Naudotojas valdo visą programos kodą, turi shell, gali kurti savus cron užduotis, o programos duomenų bazės paskyra turi visas teises į visas duomenų bazes. Užpuolikui tai idealus pagrindas įsitvirtinti ilgam.

Kaip teisingai paskirstyti failus ir aplankus, aprašo vadovas Failų teisės žiniatinklio serveryje. Šis straipsnis nagrinėja pačią paskyrą: prisijungimą, ypatingas teises, suplanuotas užduotis, duomenų bazę ir ribas, kurias nubrėžia systemd.

Inventorizacija: kas yra žiniatinklio serverio naudotojas?

Pirmiausia išsiaiškinkite, kurie naudotojai apskritai dalyvauja. Su PHP-FPM kiekvienas baseinas per user ir group nustato, kokiu naudotoju veikia jo darbiniai procesai. Su mod_php PHP veikia kaip Apache naudotojas. Kaip PHP-FPM pagrindinis procesas ir darbiniai procesai veikia kartu, aiškina PHP-FPM paaiškinimas: procesų valdytojas, baseinai ir darbiniai procesai. Šios komandos tik skaito:

# Kokiais naudotojais veikia žiniatinklio serveris ir PHP?
ps -eo user,group,cmd | grep -E "[p]hp-fpm|[n]ginx|[a]pache2|[h]ttpd" | sort | uniq -c
# Paskyros duomenys: namų katalogas ir shell (pritaikyti naudotoją)
getent passwd www-data
# Ar naudotojas turi sudo teisių?
sudo -l -U www-data
# Ar turi savų cron užduočių?
sudo crontab -l -u www-data
# SSH raktai namų kataloge (Debian/Ubuntu sistemose tai /var/www)
sudo ls -la /var/www/.ssh 2>/dev/null

Užsirašykite rezultatus kiekvienam baseino naudotojui. Jei visos svetainės veikia tuo pačiu naudotoju, tai pirmas punktas sąraše; kaip tai atskirti, aprašo PHP-FPM baseinų izoliavimas kiekvienai svetainei.

Žiniatinklio serverio naudotojo teisės: ko paskyrai nereikia

Toliau pateikta apžvalga rodo, ko žiniatinklio serverio naudotojui paprastai nereikia ir kaip tai atimti.

Teisė Kodėl pavojinga Rekomendacija
Prisijungimo shell galimas prisijungimas ir interaktyvus naudojimas shell /usr/sbin/nologin
sudo įrašai kelias į root teises jokių įrašų, net atskiroms komandoms
Sava crontab nuolatinės užpakalinės durys, išgyvenančios kiekvieną paleidimą iš naujo jokios, apriboti per /etc/cron.allow
SSH raktai prisijungimas iš išorės jokių authorized_keys
Programos kodo savininkas kodą galima pakeisti savininkas yra diegimo (deploy) naudotojas
Rašymo teisės už duomenų aplankų ribų kenkėjiško kodo padėjimas tik įkėlimai, talpykla, temp
Visos duomenų bazės teisės kitų programų duomenų bazės, prieiga prie failų per duomenų bazę tik sava duomenų bazė, tik duomenų teisės

Shell nustatote komanda usermod -s /usr/sbin/nologin www-data. Cron taisyklė tokia: jei yra /etc/cron.allow, savų cron užduočių kurti gali tik ten išvardyti naudotojai. Naujai sukurtos cron užduotys ar nežinomi SSH raktai tipiškai rodo, kad kažkas įsitvirtino. Ypač aiškų perspėjimo ženklą aprašo straipsnis Perspėjimo ženklas: žiniatinklio serveris paleidžia shell.

Duomenų bazė: teises riboti iki būtinų

Svetainės duomenų bazės paskyra faktiškai yra antras žiniatinklio serverio naudotojas. Jos prisijungimo duomenys yra programos konfigūracijos faile ir įterptam kodui prieinami skaityti. Todėl ji turėtų galėti tik tai, ko programai reikia veikiant.

-- Pavyzdys MySQL/MariaDB: sava paskyra kiekvienai svetainei, tik duomenų teisės
CREATE USER 'seite1'@'localhost' IDENTIFIED BY 'hier-ein-langes-Zufallspasswort';
GRANT SELECT, INSERT, UPDATE, DELETE ON seite1.* TO 'seite1'@'localhost';
-- Patikrinti teises
SHOW GRANTS FOR 'seite1'@'localhost';

Teisių FILE, SUPER ar GRANT OPTION ir prieigos prie *.* programos paskyrai nereikia. Daugeliui CMS atnaujinimams papildomai reikia CREATE, ALTER, INDEX ir DROP. Tvarkingiau turėti atskirą paskyrą atnaujinimams ir migracijoms, naudojamą tik techninės priežiūros metu. Reikalavimus patikrinkite gamintojo dokumentacijoje.

PHP-FPM papildomai apriboti su systemd

systemd gali apriboti tarnybos požiūrį į sistemą. PHP-FPM ypač tinka kelios parinktys iš systemd dokumentacijos. Jos veikia ir pagrindinį procesą, kuris paleidžiamas kaip root.

# sudo systemctl edit php8.3-fpm
[Service]
# /usr, /boot ir /etc tik skaitymui
ProtectSystem=full
# /home, /root ir /run/user nematomi
ProtectHome=true
# savas /tmp ir /var/tmp tik šiai tarnybai
PrivateTmp=true
# jokio teisių išplėtimo per setuid ar failų capabilities
NoNewPrivileges=true

Išbandykite šias parinktis prieš naudodami gamyboje. Jei svetainės yra aplanke /home, ProtectHome=true užblokuos prieigą. NoNewPrivileges=true gali trikdyti programas, kurias iškviečia PHP ir kurios paleidžiamos keičia savo grupės teises, pavyzdžiui, kai kurias vietines pašto programas PHP funkcijai mail(). Todėl eikite žingsniais:

  1. Pridėkite vieną parinktį, paleiskite tarnybą iš naujo, patikrinkite systemctl status php8.3-fpm.
  2. Išbandykite pagrindines svetainės funkcijas: prisijungimą, formas, laiškų siuntimą, įkėlimus, programos cron užduotis.
  3. Peržiūrėkite PHP-FPM ir programos klaidų žurnalą.
  4. Tik tada pridėkite kitą parinktį.

Galiausiai lizdas (socket): pagal PHP vadovą jam pagal numatytuosius nustatymus suteikiamos teisės 0660 baseino naudotojui ir grupei. Nustatykite listen.owner ir listen.group taip, kad prisijungti galėtų tik žiniatinklio serveris, o ne kiekvienas vietinis naudotojas.

Patarimas

Minimalios teisės yra požiūris, o ne vienkartinis projektas. Šio straipsnio inventorizaciją kartokite po kiekvieno pertvarkymo ir kiekvienos naujos svetainės, nes naujos tarnybos dažnai ateina su dosniomis numatytosiomis teisėmis.

Išvada: užpuolikas paveldi tai, ką leidžiate

Least Privilege skamba kaip teorija, bet tai labai praktiškas klausimas: ką gali daryti tas, kas vykdo kodą kaip žiniatinklio serverio naudotojas? Serveryje su shell, sudo įrašu, sava crontab ir duomenų bazės paskyra su visomis teisėmis atsakymas toks: beveik viską. Apribotame serveryje dažniau lieka incidentas vienoje svetainėje, kurį galima aptikti ir sutvarkyti.

Perėjimui nereikia naujos programinės įrangos, tik kruopščios inventorizacijos ir nuoseklių bandymų. Pradėkite nuo punktų, kurie vargu ar ką nors sulaužys, t. y. shell, sudo ir SSH raktų, o tada pereikite prie duomenų bazės teisių ir systemd parinkčių.

Kaip PHP SOS padeda konkrečiai?

  • Patikrinti paskyras: kiekvienam baseinui ir žiniatinklio serveriui surenkame naudotoją, shell, sudo įrašus, cron užduotis, SSH raktus ir duomenų bazės teises.
  • Sumažinti teises: atimame tai, ko nereikia, ir atskiriame diegimo, vykdymo ir techninės priežiūros paskyras.
  • Apriboti tarnybas: systemd apsaugos parinktis nustatome žingsniais ir po kiekvieno žingsnio išbandome svetainę.
  • Išlaikyti ilgam: serverio sutvirtinimo rėmuose dokumentuojame teisių koncepciją būsimiems pakeitimams.

Dažni klausimai

Kuriuo naudotoju veikia PHP mano serveryje?

Tai priklauso nuo veikimo režimo. Su mod_php PHP veikia kaip Apache naudotojas, pavyzdžiui, www-data arba apache. Su PHP-FPM kiekvienas baseinas (pool) naudotoją nustato per user ir group; pagrindinis procesas dažniausiai veikia kaip root, darbiniai procesai (worker) kaip baseino naudotojas. Komanda ps tai parodo greitai.

Ar žiniatinklio serverio naudotojui reikia prisijungimo shell?

Ne. Nei Nginx, nei Apache, nei PHP-FPM šiam naudotojui interaktyvaus prisijungimo nereikalauja. Shell, pavyzdžiui, /usr/sbin/nologin, neleidžia niekam prisijungti su šia paskyra. Diegimas (deployment) vyksta per atskirą naudotoją.

Kodėl www-data neturėtų turėti sudo teisių, net vienai komandai?

Nes įterptas kodas paveldi būtent šias teises. Net iš pažiūros nekenksminga komanda, jei ji netinkamai leidžiama, gali baigtis root teisėmis. Užduotys, kurioms reikia didesnių teisių, turi būti atskirose tarnybose ar procesuose už žiniatinklio serverio ribų.

Ar tai padeda nuo PHP2Shell?

Pažeidžiamumo tai neuždaro, tam reikia PHP atnaujinimo ir visų darbinių procesų paleidimo iš naujo. Tačiau minimalios teisės apriboja, ką užpuolikas gali daryti po sėkmingo išnaudojimo: keisti failus, įsitvirtinti, pasiekti kitas svetaines.

Šaltiniai

Skubus kontaktas

Kiekviena valanda svarbi. Parašykite mums dabar.

Trumpai aprašykite sistemą, PHP versiją ir pastebėjimus. Mes atsakysime, išsiaiškinsime padėtį ir dirbsime nuotoliu, kol incidentas bus užbaigtas ir dokumentuotas.

Skubi pagalba