Aktuel situation: PHP2Shell. To kritiske PHP-sårbarheder (CVSS 9,2) tillader skadelig kode uden login. Rettelser siden 21.10.2026.Hvad der skal gøres nu →

Konfigurér Nginx sikkert til PHP

De fleste svagheder i Nginx-opsætninger til PHP sidder ikke i Nginx, men i få linjer i PHP-location'en. Sådan konfigurerer I overdragelsen til PHP-FPM, så kun de ønskede scripts udføres.

Status 6 min. læsetidHærdning og konfiguration

Kort sagt: For at konfigurere Nginx sikkert til PHP giver I kun scripts videre til PHP-FPM, som virkelig findes, ved front-controller-applikationer endda kun index.php. Hertil kommer spærrede dotfiles som .git og .env, en standardserver til ukendte værtsnavne, passende størrelsesgrænser og security.limit_extensions = .php i poolen. Det beskytter ikke mod sårbarheder i selve PHP, men begrænser, hvad der kan udføres efter en fejl.

De farligste linjer står i PHP-location'en

Siden PHP2Shell kontrollerer mange teams deres PHP-FPM-versioner og pools, som siden Afsikr Nginx med PHP-FPM beskriver, og genstarter efter opdateringen alle workers. Et andet blik gælder selve Nginx-konfigurationen. Dér afgøres det, hvilke filer der overhovedet udføres som PHP.

I mange konfigurationer står der en blok, der sender hver forespørgsel til .php videre til PHP-FPM, uanset hvor filen ligger. Havner en indsmuglet PHP-fil i en upload-mappe, udfører serveren den. Af en filfejl bliver der således en bagdør.

Dette indlæg koncentrerer sig om Nginx-siden: hvilke direktiver der tæller, hvordan rækkefølgen af location-blokke virker, og hvordan I tester resultatet.

Sådan afgør Nginx, hvilken blok der gælder

Den, der vil konfigurere Nginx sikkert til PHP, må kende udvælgelsen af location-blokke. Ifølge Nginx-dokumentationen forløber den således:

  1. Et nøjagtigt match med location = afslutter søgningen med det samme.
  2. Blandt præfiks-locations huskes den længste passende. Bærer den ^~, kontrolleres ingen regulære udtryk mere.
  3. Ellers kontrolleres regulære udtryk (~, ~*) i konfigurationsfilens rækkefølge; det første match vinder.
  4. Passer intet regulært udtryk, gælder den huskede præfiks-location.

Heraf følger to praktiske regler. En spærring for PHP i upload-mapper skal enten oprettes som ^~-præfiks eller stå som regulært udtryk før den generelle PHP-blok. Og en normal præfiks-location som location /uploads/ beskytter ikke, fordi det regulære udtryk for .php overtrumfer den.

En sikker grundkonfiguration

Eksemplet nedenfor viser en server-blok til en applikation med front-controller, som den er almindelig ved Laravel, Symfony, Shopware 6 eller mange egenudviklinger. Stier, socket og certifikater tilpasser I.

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;

    # Tillad Let's Encrypt og andre kendte stier
    location ^~ /.well-known/ {
        try_files $uri =404;
    }

    # Spær skjulte filer og mapper (.git, .env, .htaccess)
    location ~ /\. {
        deny all;
    }

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

    # Kun front-controlleren overdrages til 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;
    }

    # Enhver anden PHP-fil udføres ikke
    location ~ \.php$ {
        return 404;
    }
}

$realpath_root opløser symbolske links. Det er vigtigt ved deployments med skiftende symlink til den aktuelle release, så PHP-FPM og OPcache ser den rigtige sti. Bemærk desuden: Ifølge Nginx-dokumentationen nedarves fastcgi_param-direktiver kun fra højere niveauer, hvis der ikke står egne på det aktuelle niveau. Derfor hører include fastcgi_params; hjemme i den samme blok.

Klassiske CMS som WordPress, TYPO3 eller Contao har flere indgangspunkter. Dér erstatter I front-controller-blokken med en generel PHP-location, der kun overdrager eksisterende filer (try_files $uri =404;), og spærrer udførelsen i alle skrivbare mapper. Hvordan det lykkes, står under Forbyd PHP-udførelse i upload-mapper.

Den anden sikring i PHP-FPM

Nginx afgør, hvad der gives videre, PHP-FPM afgør, hvad det udfører. Ifølge PHP-manualen udfører PHP-FPM som standard filer med .php og .phar og anbefaler selv at begrænse det til .php. Det opfanger konfigurationsfejl i webserveren.

; i poolen, f.eks. /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

Socketten bør kun kunne nås af Nginx. FPM-porte i netværket, f.eks. 9000, hører ikke hjemme åbnet udadtil. Hvordan serveren samlet kun viser de nødvendige porte, beskriver Firewall til webservere: Åbn kun nødvendige porte.

Ukendte værtsnavne og flere justeringsskruer

Uden egen standardserver besvarer Nginx forespørgsler til ukendte værtsnavne med den første passende server-blok. Automatiserede scanninger, der kun henvender sig til IP-adressen, havner så direkte i jeres applikation. En egen standardserver afslutter sådanne forespørgsler uden svar.

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

Yderligere punkter, der har vist sig at fungere:

Justeringsskrue Anbefaling Formål
server_tokens off intet versionsnummer i header og fejlsider
client_max_body_size passende til post_max_size afvis store forespørgsler tidligt
autoindex fra (standard) ingen mappelister
fastcgi_hide_header X-Powered-By ingen PHP-version udadtil
Statussider pm.status_path kun internt ingen driftsdata offentligt
Backupfiler spær eller fjern .sql, .zip, .bak i webroden ingen download af databaser

Mere om versionsangivelser står i indlægget expose_php og Server-headeren.

En yderligere justeringsskrue angår de tilladte HTTP-metoder. De fleste websites har kun brug for GET, HEAD og POST. Med limit_except kan andre metoder afvises i en location; ifølge Nginx-dokumentationen tillader frigivelsen af GET automatisk også HEAD. Kontrollér på forhånd, om grænseflader i jeres applikation bruger f.eks. PUT eller DELETE, for REST-API'er gør det ofte.

Test, før I genindlæser

Hver ændring kontrollerer I først med nginx -t og genindlæser først derefter Nginx. Bagefter tester I adfærden udefra med normale forespørgsler til jeres eget domæne:

sudo nginx -t && sudo systemctl reload nginx
# Forventet: 403 eller 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
# Forventet: 404, fordi kun front-controlleren udføres
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/info.php
# Hvilke blokke overdrager til PHP-FPM?
sudo nginx -T 2>/dev/null | grep -nE "location|fastcgi_pass"

Sikr før hver større ændring det fuldstændige output fra nginx -T med dato. Det indeholder hele den virksomme konfiguration inklusive alle indbundne filer. Går noget galt efter en ændring, viser sammenligningen straks, hvad der er forskelligt. Ved næste kritiske sårbarhed har I desuden et pålideligt grundlag for beholdningsopgørelsen uden først at skulle samle filer sammen.

Tip

Ændr først konfigurationen i et testmiljø eller på en kopi af server-blokken. Et glemt indgangspunkt, f.eks. et betalings-callback, opdages ellers først, når ordrer udebliver.

Hvordan hjælper PHP SOS konkret?

  • Læs konfigurationen: Vi analyserer hele Nginx-konfigurationen med nginx -T og henfører hver PHP-overdragelse til sit website og sin pool.
  • Fastlæg indgangspunkter: Sammen med jeres udviklere bestemmer vi, hvilke scripts der skal udføres, og spærrer resten.
  • Gennemfør og test: Vi tilpasser server-blokke og pools, kontrollerer med nginx -t og tester formularer, betalingsveje og uploads.
  • Afsikr varigt: Konfigurationen bliver en del af vores serverhærdning og dokumentationen af jeres server.

Ofte stillede spørgsmål

Skal Nginx genstartes efter en PHP-opdatering?

Ikke for PHP-patchen, for Nginx indeholder ikke PHP. Genstartes skal alle PHP-FPM-tjenester. Ændrer I samtidig Nginx-konfigurationen, kontrollerer I den først med nginx -t og genindlæser derefter Nginx.

Hvorfor kun give index.php videre til PHP?

Mange moderne applikationer har ét enkelt indgangspunkt, front-controlleren. Overdrages kun denne fil til PHP-FPM, kan en indsmuglet PHP-fil et andet sted ikke udføres via browseren. Ved systemer med mange indgangspunkter er dette mønster ikke muligt.

Hvad giver security.limit_extensions i PHP-FPM?

Indstillingen fastlægger, hvilke filendelser PHP-FPM udfører som script. Ifølge PHP-manualen er standarden .php .phar; anbefalet er at begrænse til .php. Det opfanger fejl i webserverkonfigurationen, men erstatter den ikke.

Er Nginx-regler en beskyttelse mod PHP2Shell?

Nej. PHP2Shell sidder i PHP-fortolkeren og lukkes kun af opdateringen til en rettet version og genstart af alle workers. En sikker Nginx-konfiguration formindsker angrebsfladen og begrænser skaden efter et indbrud.

Kilder

Akut kontakt

Hver time tæller. Skriv til os nu.

Beskriv kort system, PHP-version og observation. Vi vender tilbage, afklarer situationen og arbejder på afstand, indtil hændelsen er afsluttet og dokumenteret.

Akut hjælp