Lühidalt: Veebiserveri kasutaja, kelle all PHP töötab, peaks vähima õiguse põhimõtte (Least Privilege) kohaselt lugema ainult seda, mida veebisait vajab, ja kirjutama ainult sinna, kuhu see andmeid salvestab. Tal ei ole sisselogimisshelli, sudo-õigusi, oma croni-töid ega SSH-võtmeid ning tema andmebaasikonto tohib andmeid ainult lugeda ja muuta. systemd valikud, nagu ProtectSystem ja PrivateTmp, piiravad PHP-FPM-i lisaks.
Küsimus pärast sissemurdmist: mida see protsess tohib?
PHP2Shelli puhul on tegemist pahatahtliku koodi kaugkäivitamisega ilma sisselogimiseta. Kui see õnnestub, ei tööta kood tühjuses, vaid kindla kasutajana: PHP protsessi kasutajana. Kõike, mida see kasutaja tohib, tohib sellest hetkest alates ka ründaja.
Paljudes serverites on seda üllatavalt palju. Kasutajale kuulub kogu programmikood, tal on shell, ta saab luua oma croni-töid ja rakenduse andmebaasikontol on kõik õigused kõigile andmebaasidele. Ründajale on see ideaalne lähtepositsioon, et end püsivalt sisse seada.
Kuidas faile ja kaustu õigesti omistada, kirjeldab juhend Failiõigused veebiserveris. See artikkel vaatab kontot ennast: sisselogimist, eriõigusi, ajastatud ülesandeid, andmebaasi ja piire, mille systemd seab.
Inventuur: kes on veebiserveri kasutaja?
Esmalt selgitate välja, millised kasutajad üldse osalevad. PHP-FPM-i puhul määrab iga pool valikutega user ja group, kelle all selle töölised töötavad. mod_php puhul töötab PHP Apache'i kasutajana. Kuidas peaprotsess ja töölised PHP-FPM-is koos töötavad, selgitab PHP-FPM selgitatud: protsessihaldur, poolid ja töölised. Järgmised käsud ainult loevad:
# Millise kasutaja all töötavad veebiserver ja PHP?
ps -eo user,group,cmd | grep -E "[p]hp-fpm|[n]ginx|[a]pache2|[h]ttpd" | sort | uniq -c
# Konto andmed: kodukataloog ja shell (kohandage kasutajat)
getent passwd www-data
# Kas kasutajal on sudo-õigusi?
sudo -l -U www-data
# Kas on oma croni-töid?
sudo crontab -l -u www-data
# SSH-võtmed kodukataloogis (Debianis/Ubuntus on see /var/www)
sudo ls -la /var/www/.ssh 2>/dev/null
Märkige tulemused üles iga poolikasutaja kohta. Kui kõik veebisaidid töötavad sama kasutaja all, on see nimekirja esimene punkt; kuidas seda eraldada, kirjeldab PHP-FPM-poolide eraldamine veebisaidi kaupa.
Veebiserveri kasutaja õigused: mida konto ei vaja
Järgnev ülevaade näitab, mida veebiserveri kasutaja tavaliselt ei vaja ja kuidas selle ära võtate.
| Õigus | Miks ohtlik | Soovitus |
|---|---|---|
| Sisselogimisshell | Sisselogimine ja interaktiivne kasutus võimalik | Shell /usr/sbin/nologin |
| sudo-kirjed | Tee root-õigusteni | ühtegi kirjet, ka mitte üksikkäskude jaoks |
| oma crontab | püsiv tagauks, mis elab üle iga taaskäivituse | mitte ühtegi, piirake failiga /etc/cron.allow |
| SSH-võtmed | Sisselogimine väljastpoolt | ühtegi authorized_keys faili |
| Programmikoodi omanik | Koodi saab muuta | Omanik on deploy-kasutaja |
| Kirjutusõigused väljaspool andmekaustu | Pahakoodi paigutamine | ainult üleslaadimised, vahemälu, ajutised failid |
| täielikud andmebaasiõigused | Teiste rakenduste andmebaasid, failidele ligipääs andmebaasi kaudu | ainult oma andmebaas, ainult andmeõigused |
Shelli seate käsuga usermod -s /usr/sbin/nologin www-data. Cron'i puhul kehtib: kui /etc/cron.allow on olemas, tohivad oma croni-töid luua ainult seal nimetatud kasutajad. Äsja loodud croni-tööd või tundmatud SSH-võtmed on tüüpiline märk sellest, et keegi on end sisse seadnud. Eriti selge hoiatusmärgi kirjeldab artikkel Hoiatusmärk: veebiserver käivitab shelli.
Andmebaas: õigused vajalikule piirata
Veebisaidi andmebaasikonto on tegelikult teine veebiserveri kasutaja. Selle ligipääsuandmed on rakenduse konfiguratsioonifailis ja sissetoodud koodile loetavad. Seetõttu peaks see tohtima ainult seda, mida rakendus töös vajab.
-- Näide MySQL/MariaDB: oma konto iga veebisaidi jaoks, ainult andmeõigused
CREATE USER 'seite1'@'localhost' IDENTIFIED BY 'hier-ein-langes-Zufallspasswort';
GRANT SELECT, INSERT, UPDATE, DELETE ON seite1.* TO 'seite1'@'localhost';
-- Õiguste kontroll
SHOW GRANTS FOR 'seite1'@'localhost';
Õigusi nagu FILE, SUPER või GRANT OPTION ja ligipääsu *.* ei pea rakenduse kontol olema. Paljud sisuhaldussüsteemid vajavad uuenduste jaoks lisaks CREATE, ALTER, INDEX ja DROP. Puhtam on eraldi konto uuenduste ja migratsioonide jaoks, mida kasutatakse ainult hoolduse ajal. Kontrollige nõudeid tootja dokumentatsioonist.
PHP-FPM-i systemd abil lisaks piirata
systemd saab piirata teenuse vaadet süsteemile. PHP-FPM-i jaoks sobivad eriti mõned systemd dokumentatsiooni valikud. Need mõjuvad ka peaprotsessile, mis käivitub root'ina.
# sudo systemctl edit php8.3-fpm
[Service]
# /usr, /boot ja /etc kirjutuskaitstud
ProtectSystem=full
# /home, /root ja /run/user nähtamatud
ProtectHome=true
# oma /tmp ja /var/tmp ainult sellele teenusele
PrivateTmp=true
# ei mingit õiguste laiendamist setuid-i või faili-capabilities'i kaudu
NoNewPrivileges=true
Testige neid valikuid enne tootmiskasutust. Kui veebisaidid asuvad kaustas /home, takistab ProtectHome=true ligipääsu. NoNewPrivileges=true võib segada programme, mida PHP kutsub ja mis käivitumisel vahetavad grupiõigusi, näiteks mõned kohalikud meiliprogrammid PHP funktsiooni mail() jaoks. Tegutsege seetõttu etapiviisi:
- Lisage üks valik, taaskäivitage teenus, kontrollige
systemctl status php8.3-fpm. - Testige veebisaidi põhifunktsioone: sisselogimine, vormid, meili saatmine, üleslaadimised, rakenduse croni-tööd.
- Hinnake PHP-FPM-i ja rakenduse vealogi.
- Alles siis lisage järgmine valik.
Lõpuks soklist: PHP käsiraamatu kohaselt saab see vaikimisi õigused 0660 poolikasutajale ja -grupile. Seadke listen.owner ja listen.group nii, et ühenduda saab ainult veebiserver, mitte iga kohalik kasutaja.
Minimaalsed õigused on hoiak, mitte ühekordne projekt. Kontrollige selle artikli inventuuri uuesti pärast iga ümberehitust ja iga uut veebisaiti, sest uued teenused toovad sageli kaasa heldeid vaikeõigusi.
Kokkuvõte: ründaja pärib selle, mida te lubate
Vähima õiguse põhimõte kõlab teoreetiliselt, kuid on väga praktiline küsimus: mida saab teha see, kes käivitab koodi veebiserveri kasutajana? Serveris, kus on shell, sudo-kirje, oma crontab ja kõigi õigustega andmebaasikonto, on vastus: peaaegu kõike. Piiratud serveris jääb see pigem ühe veebisaidi intsidendiks, mille saab tuvastada ja puhastada.
Ümberseadmine ei vaja uut tarkvara, ainult hoolikat inventuuri ja järkjärgulisi teste. Alustage punktidest, mis peaaegu midagi ei riku, see tähendab shellist, sudost ja SSH-võtmetest, ning liikuge siis edasi andmebaasiõiguste ja systemd valikute juurde.
Kuidas PHP SOS konkreetselt aitab?
- Kontode kontroll: Me kaardistame iga pooli ja veebiserveri jaoks kasutaja, shelli, sudo-kirjed, croni-tööd, SSH-võtmed ja andmebaasiõigused.
- Õiguste vähendamine: Me võtame ära selle, mida ei vajata, ning eraldame deploy-, tööaja- ja hoolduskontod.
- Teenuste piiramine: Me seame systemd kaitsevalikud etapiviisi ja testime veebisaiti pärast iga sammu.
- Püsiv hoidmine: Serveri kõvendamise raames dokumenteerime õiguste kontseptsiooni tulevaste muudatuste jaoks.
Korduma kippuvad küsimused
Millise kasutajana töötab PHP minu serveris?
See sõltub töörežiimist. mod_php puhul töötab PHP Apache'i kasutajana, näiteks www-data või apache. PHP-FPM-i puhul määrab iga pool oma kasutaja valikutega user ja group; peaprotsess töötab tavaliselt root'ina, töölised poolikasutajana. Käsk ps näitab seda kiiresti.
Kas veebiserveri kasutaja vajab sisselogimisshelli?
Ei. Ei Nginx, Apache ega PHP-FPM vaja selle kasutaja interaktiivset sisselogimist. Shell, näiteks /usr/sbin/nologin, takistab selle kontoga sisselogimist. Juurutused (deployment) käivad eraldi kasutaja kaudu.
Miks ei tohi www-data'l olla sudo-õigusi, isegi mitte ühe käsu jaoks?
Sest sissetoodud kood pärib just need õigused. Isegi näiliselt kahjutu käsk võib vigaselt lubatuna viia root-õigusteni. Ülesanded, mis vajavad kõrgemaid õigusi, kuuluvad eraldi teenustesse või veebiserveri väliste protsesside juurde.
Kas see aitab PHP2Shelli vastu?
See ei sulge auku, selleks on vaja PHP uuendust ja kõigi töölisprotsesside taaskäivitamist. Minimaalsed õigused piiravad aga seda, mida ründaja pärast edukat ärakasutamist teha saab: faile muuta, end püsivalt sisse seada, jõuda teiste veebisaitideni.