Aktuālā situācija: PHP2Shell. Divas kritiskas PHP ievainojamības (CVSS 9.2) ļauj izpildīt ļaunprātīgu kodu bez pieteikšanās. Ielāpi kopš 21.10.2026.Kas jādara tagad →

Nginx droša konfigurēšana PHP

Lielākā daļa ievainojamību Nginx uzstādījumos PHP slēpjas nevis Nginx, bet dažās PHP location rindiņās. Kā konfigurēt nodošanu PHP-FPM tā, lai tiktu izpildīti tikai vēlamie skripti.

Aktuāls uz 5 min lasīšanas laiksNostiprināšana un konfigurācija

Īsi sakot: Lai Nginx droši konfigurētu PHP, uz PHP-FPM nododiet tikai skriptus, kas patiešām pastāv, front controller lietojumprogrammām pat tikai index.php. Tam pievienojas nobloķēti punktfaili, piemēram, .git un .env, noklusējuma serveris nezināmiem hostvārdiem, piemērotas izmēra robežas un security.limit_extensions = .php pūlā. Tas neaizsargā pret ievainojamībām pašā PHP, bet ierobežo, ko pēc kļūdas var izpildīt.

Bīstamākās rindiņas atrodas PHP location

Kopš PHP2Shell daudzas komandas pārbauda savas PHP-FPM versijas un pūlus, kā to apraksta lapa Nginx ar PHP-FPM nostiprināšana, un pēc atjauninājuma pārstartē visus worker procesus. Otrs skatiens attiecas uz pašu Nginx konfigurāciju. Tur izšķiras, kuri faili vispār tiek izpildīti kā PHP.

Daudzās konfigurācijās ir bloks, kas katru pieprasījumu uz .php nodod PHP-FPM, neatkarīgi no tā, kur fails atrodas. Ja ielikts PHP fails nonāk augšupielāžu mapē, serveris to izpilda. No faila kļūdas tā rodas slēpta piekļuve.

Šis raksts koncentrējas uz Nginx pusi: kuras direktīvas ir svarīgas, kā darbojas location bloku secība un kā pārbaudīt rezultātu.

Kā Nginx izlemj, kurš bloks iedarbojas

Kas grib Nginx droši konfigurēt PHP, tam jāzina location bloku izvēle. Saskaņā ar Nginx dokumentāciju tā norit šādi:

  1. Precīzs trāpījums ar location = meklēšanu beidz nekavējoties.
  2. No prefiksa location tiek iegaumēts garākais atbilstošais. Ja tam ir ^~, regulārās izteiksmes vairs netiek pārbaudītas.
  3. Citādi regulārās izteiksmes (~, ~*) tiek pārbaudītas konfigurācijas faila secībā; uzvar pirmais trāpījums.
  4. Ja neviena regulārā izteiksme neatbilst, spēkā ir iegaumētais prefiksa location.

No tā izriet divi praktiski noteikumi. Bloķēšana PHP augšupielāžu mapēs jāveido vai nu kā ^~ prefikss, vai kā regulāra izteiksme pirms vispārējā PHP bloka. Un parasts prefiksa location, piemēram, location /uploads/, neaizsargā, jo regulārā izteiksme .php to pārspēj.

Droša pamata konfigurācija

Turpmākais piemērs rāda server bloku lietojumprogrammai ar front controller, kāda ir Laravel, Symfony, Shopware 6 vai daudzās pašu izstrādēs. Ceļus, socket un sertifikātus pielāgojiet.

server {
    listen 443 ssl;
    server_name www.example.de;
    root /var/www/seite1/public;
    index index.php;

    ssl_certificate     /etc/ssl/seite1/fullchain.pem;
    ssl_certificate_key /etc/ssl/seite1/privkey.pem;

    server_tokens off;
    client_max_body_size 32m;

    # Atļaut Let's Encrypt un citus zināmos ceļus
    location ^~ /.well-known/ {
        try_files $uri =404;
    }

    # Bloķēt slēptos failus un mapes (.git, .env, .htaccess)
    location ~ /\. {
        deny all;
    }

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    # Tikai front controller tiek nodots PHP-FPM
    location = /index.php {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_hide_header X-Powered-By;
        fastcgi_pass unix:/run/php/seite1.sock;
    }

    # Neviens cits PHP fails netiek izpildīts
    location ~ \.php$ {
        return 404;
    }
}

$realpath_root atrisina simboliskās saites. Tas ir svarīgi izvietošanām ar mainīgu simbolisko saiti uz aktuālo izlaidumu, lai PHP-FPM un OPcache redzētu pareizo ceļu. Ņemiet vērā arī: saskaņā ar Nginx dokumentāciju fastcgi_param direktīvas no augstākiem līmeņiem tiek mantotas tikai tad, ja pašreizējā līmenī nav savu. Tāpēc include fastcgi_params; pieder tajā pašā blokā.

Klasiskajiem CMS, piemēram, WordPress, TYPO3 vai Contao, ir vairāki ieejas punkti. Tur front controller bloku aizstājiet ar vispārēju PHP location, kas nodod tikai esošus failus (try_files $uri =404;), un bloķējiet izpildi visās rakstāmajās mapēs. Kā tas izdodas, rakstīts sadaļā PHP izpildes aizliegšana augšupielāžu mapēs.

Otra aizsardzība PHP-FPM

Nginx izlemj, ko nodot tālāk, PHP-FPM izlemj, ko izpildīt. Saskaņā ar PHP rokasgrāmatu PHP-FPM pēc noklusējuma izpilda failus ar .php un .phar un pats iesaka to ierobežot uz .php. Tas pārtver konfigurācijas kļūdas tīmekļa serverī.

; pūlā, piem., /etc/php/8.3/fpm/pool.d/seite1.conf
security.limit_extensions = .php
listen = /run/php/seite1.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

Socket jābūt sasniedzamam tikai Nginx. FPM porti tīklā, piemēram, 9000, nedrīkst būt atvērti uz āru. Kā serveris kopumā rāda tikai nepieciešamos portus, apraksta Ugunsmūris tīmekļa serveriem: atvērt tikai nepieciešamos portus.

Nezināmi hostvārdi un citas regulēšanas skrūves

Bez sava noklusējuma servera Nginx pieprasījumus uz nezināmiem hostvārdiem atbild ar pirmo piemērotu server bloku. Automatizētas skenēšanas, kas uzrunā tikai IP adresi, tad nonāk tieši jūsu lietojumprogrammā. Savs noklusējuma serveris šādus pieprasījumus beidz bez atbildes.

server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    ssl_reject_handshake on;
    return 444;
}

Citi punkti, kas sevi apliecinājuši:

Regulēšanas skrūve Ieteikums Mērķis
server_tokens off nekāda versijas numura galvenē un kļūdu lapās
client_max_body_size atbilstoši post_max_size lielus pieprasījumus noraidīt agrīni
autoindex izslēgts (noklusējums) nekādu direktoriju sarakstu
fastcgi_hide_header X-Powered-By nekāda PHP versija uz āru
Statusa lapas pm.status_path tikai iekšēji nekādu ekspluatācijas datu publiski
Rezerves kopiju faili .sql, .zip, .bak tīmekļa saknē bloķēt vai noņemt nekādas datubāzu lejupielādes

Vairāk par versiju norādēm rakstā expose_php un Server galvenes.

Vēl viena regulēšanas skrūve attiecas uz atļautajām HTTP metodēm. Lielākajai daļai vietņu vajag tikai GET, HEAD un POST. Ar limit_except citas metodes location var noraidīt; saskaņā ar Nginx dokumentāciju GET atļaušana automātiski atļauj arī HEAD. Iepriekš pārbaudiet, vai jūsu lietojumprogrammas saskarnes neizmanto, piemēram, PUT vai DELETE, jo REST API to bieži dara.

Testēšana pirms pārlādes

Katru izmaiņu vispirms pārbaudiet ar nginx -t un tikai tad pārlādējiet Nginx. Pēc tam testējiet uzvedību no ārpuses ar parastiem pieprasījumiem uz savu domēnu:

sudo nginx -t && sudo systemctl reload nginx
# Sagaidāms: 403 vai 404
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/HEAD
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.env
# Sagaidāms: 404, jo tiek izpildīts tikai front controller
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/info.php
# Kuri bloki nodod PHP-FPM?
sudo nginx -T 2>/dev/null | grep -nE "location|fastcgi_pass"

Pirms katras lielākas izmaiņas saglabājiet pilnu nginx -T izvadi ar datumu. Tā satur visu spēkā esošo konfigurāciju, ieskaitot visus iekļautos failus. Ja pēc izmaiņas kaut kas noiet greizi, salīdzinājums uzreiz parāda, kas atšķiras. Nākamās kritiskās ievainojamības gadījumā jums turklāt ir uzticams pamats inventarizācijai, nevajadzot vispirms savākt failus.

Padoms

Konfigurāciju vispirms mainiet testa vidē vai server bloka kopijā. Aizmirsts ieejas punkts, piemēram, maksājuma callback, citādi tiek pamanīts tikai tad, kad pasūtījumi neienāk.

Kā PHP SOS palīdz konkrēti?

  • Nolasīt konfigurāciju: mēs izvērtējam visu Nginx konfigurāciju ar nginx -T un katru PHP nodošanu piešķiram tās vietnei un pūlam.
  • Noteikt ieejas punktus: kopā ar jūsu izstrādātājiem mēs nosakām, kuri skripti jāizpilda, un pārējos bloķējam.
  • Īstenot un testēt: mēs pielāgojam server blokus un pūlus, pārbaudām ar nginx -t un testējam veidlapas, maksājumu ceļus un augšupielādes.
  • Nodrošināt pastāvīgi: konfigurācija kļūst par daļu no mūsu serveru nostiprināšanas un jūsu servera dokumentācijas.

Biežāk uzdotie jautājumi

Vai Nginx pēc PHP atjauninājuma jāpārstartē?

PHP ielāpam ne, jo Nginx nesatur PHP. Jāpārstartē visi PHP-FPM pakalpojumi. Ja pie tā maināt arī Nginx konfigurāciju, pārbaudiet to iepriekš ar nginx -t un tad pārlādējiet Nginx.

Kāpēc PHP nodot tikai index.php?

Daudzām mūsdienu lietojumprogrammām ir viens ieejas punkts, front controller. Ja PHP-FPM tiek nodots tikai šis fails, citur ielikts PHP fails nevar tikt izpildīts caur pārlūku. Sistēmām ar daudziem ieejas punktiem šis paraugs nav iespējams.

Ko dod security.limit_extensions PHP-FPM?

Iestatījums nosaka, kurus failu paplašinājumus PHP-FPM izpilda kā skriptu. Saskaņā ar PHP rokasgrāmatu noklusējums ir .php .phar; ieteicams ierobežot uz .php. Tas pārtver kļūdas tīmekļa servera konfigurācijā, bet to neaizstāj.

Vai Nginx noteikumi aizsargā pret PHP2Shell?

Nē. PHP2Shell atrodas PHP interpretatorā un tiek aizvērta tikai ar atjauninājumu uz labotu versiju un visu worker procesu pārstartēšanu. Droša Nginx konfigurācija samazina uzbrukuma virsmu un ierobežo zaudējumus pēc ielaušanās.

Avoti

Tūlītējs kontakts

Katra stunda ir svarīga. Rakstiet mums tūlīt.

Īsi aprakstiet sistēmu, PHP versiju un novēroto. Mēs sazināsimies, noskaidrosim situāciju un strādāsim attālināti, līdz incidents ir slēgts un dokumentēts.

Tūlītēja palīdzība