Τρέχουσα κατάσταση: PHP2Shell. Δύο κρίσιμες ευπάθειες της PHP (CVSS 9.2) επιτρέπουν κακόβουλο κώδικα χωρίς σύνδεση. Patches από τις 21/10/2026.Τι πρέπει να γίνει τώρα →

Ασφαλής διαμόρφωση του Nginx για PHP

Οι περισσότερες αδυναμίες στις εγκαταστάσεις Nginx για PHP δεν βρίσκονται στο Nginx, αλλά σε λίγες γραμμές του location της PHP. Δείτε πώς ρυθμίζετε την παράδοση στο PHP-FPM ώστε να εκτελούνται μόνο τα επιθυμητά σενάρια.

Ημερομηνία 6 λεπτά ανάγνωσηςΣκλήρυνση και διαμόρφωση

Εν ολίγοις: Για να διαμορφώσετε το Nginx με ασφάλεια για PHP, παραδίδετε στο PHP-FPM μόνο σενάρια που υπάρχουν πραγματικά, στις εφαρμογές με front controller μάλιστα μόνο το index.php. Προστίθενται αποκλεισμένα dotfiles όπως .git και .env, ένας προεπιλεγμένος server για άγνωστα ονόματα hosts, κατάλληλα όρια μεγέθους και security.limit_extensions = .php στο pool. Αυτό δεν προστατεύει από ευπάθειες στην ίδια την PHP, περιορίζει όμως τι μπορεί να εκτελεστεί μετά από ένα σφάλμα.

Οι πιο επικίνδυνες γραμμές βρίσκονται στο location της PHP

Από το PHP2Shell πολλές ομάδες ελέγχουν τις εκδόσεις και τα pools του PHP-FPM, όπως περιγράφει η σελίδα Ασφάλιση του Nginx με PHP-FPM, και επανεκκινούν μετά την ενημέρωση όλους τους workers. Μια δεύτερη ματιά αφορά την ίδια τη διαμόρφωση του Nginx. Εκεί αποφασίζεται ποια αρχεία εκτελούνται καθόλου ως PHP.

Σε πολλές διαμορφώσεις υπάρχει ένα μπλοκ που προωθεί κάθε αίτημα προς .php στο PHP-FPM, ανεξάρτητα από το πού βρίσκεται το αρχείο. Αν ένα αρχείο PHP που έχει εισαχθεί καταλήξει σε φάκελο upload, ο διακομιστής το εκτελεί. Από ένα σφάλμα αρχείου γίνεται έτσι κερκόπορτα.

Αυτό το άρθρο επικεντρώνεται στην πλευρά του Nginx: ποιες οδηγίες μετράνε, πώς επιδρά η σειρά των μπλοκ location και πώς δοκιμάζετε το αποτέλεσμα.

Πώς αποφασίζει το Nginx ποιο μπλοκ ισχύει

Όποιος θέλει να διαμορφώσει το Nginx με ασφάλεια για PHP πρέπει να γνωρίζει την επιλογή των μπλοκ location. Σύμφωνα με την τεκμηρίωση του Nginx εξελίσσεται ως εξής:

  1. Μια ακριβής αντιστοίχιση με location = τερματίζει αμέσως την αναζήτηση.
  2. Ανάμεσα στα location με πρόθεμα, κρατιέται το μακρύτερο που ταιριάζει. Αν φέρει ^~, δεν ελέγχονται πλέον κανονικές εκφράσεις.
  3. Διαφορετικά ελέγχονται κανονικές εκφράσεις (~, ~*) με τη σειρά του αρχείου διαμόρφωσης· κερδίζει η πρώτη αντιστοίχιση.
  4. Αν δεν ταιριάζει καμία κανονική έκφραση, ισχύει το location με πρόθεμα που κρατήθηκε.

Από αυτό προκύπτουν δύο πρακτικοί κανόνες. Ένας αποκλεισμός της PHP σε φακέλους upload πρέπει είτε να δημιουργηθεί ως πρόθεμα ^~ είτε να βρίσκεται ως κανονική έκφραση πριν από το γενικό μπλοκ PHP. Και ένα κανονικό location με πρόθεμα όπως το location /uploads/ δεν προστατεύει, επειδή η κανονική έκφραση για .php το παρακάμπτει.

Μια ασφαλής βασική διαμόρφωση

Το παρακάτω παράδειγμα δείχνει ένα μπλοκ server για εφαρμογή με front controller, όπως είναι συνηθισμένο στο Laravel, στο Symfony, στο Shopware 6 ή σε πολλές ιδιόκτητες αναπτύξεις. Προσαρμόστε διαδρομές, socket και πιστοποιητικά.

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;

    # Επιτρέπονται το Let's Encrypt και άλλες γνωστές διαδρομές
    location ^~ /.well-known/ {
        try_files $uri =404;
    }

    # Αποκλεισμός κρυφών αρχείων και φακέλων (.git, .env, .htaccess)
    location ~ /\. {
        deny all;
    }

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

    # Στο PHP-FPM παραδίδεται μόνο ο front controller
    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;
    }

    # Κάθε άλλο αρχείο PHP δεν εκτελείται
    location ~ \.php$ {
        return 404;
    }
}

Το $realpath_root επιλύει συμβολικούς συνδέσμους. Αυτό είναι σημαντικό σε deployments με εναλλασσόμενο symlink προς την τρέχουσα έκδοση, ώστε το PHP-FPM και η OPcache να βλέπουν τη σωστή διαδρομή. Προσέξτε επιπλέον: σύμφωνα με την τεκμηρίωση του Nginx οι οδηγίες fastcgi_param κληρονομούνται από ανώτερα επίπεδα μόνο όταν στο τρέχον επίπεδο δεν υπάρχουν δικές τους. Γι' αυτό το include fastcgi_params; ανήκει στο ίδιο μπλοκ.

Τα κλασικά CMS όπως το WordPress, το TYPO3 ή το Contao έχουν πολλά σημεία εισόδου. Εκεί αντικαθιστάτε το μπλοκ του front controller με ένα γενικό location PHP που παραδίδει μόνο υπάρχοντα αρχεία (try_files $uri =404;) και αποκλείετε την εκτέλεση σε όλους τους εγγράψιμους φακέλους. Πώς επιτυγχάνεται, αναφέρεται στο Απαγόρευση εκτέλεσης PHP σε φακέλους upload.

Η δεύτερη προστασία στο PHP-FPM

Το Nginx αποφασίζει τι προωθείται, το PHP-FPM αποφασίζει τι εκτελεί. Σύμφωνα με το εγχειρίδιο της PHP, το PHP-FPM εκτελεί από προεπιλογή αρχεία με .php και .phar και συνιστά το ίδιο να περιοριστεί σε .php. Αυτό πιάνει σφάλματα διαμόρφωσης στον διακομιστή ιστού.

; στο pool, π.χ. /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 πρέπει να είναι προσβάσιμο μόνο για το Nginx. Οι θύρες FPM στο δίκτυο, για παράδειγμα η 9000, δεν πρέπει να ανοίγονται προς τα έξω. Πώς ο διακομιστής εμφανίζει συνολικά μόνο τις απαραίτητες θύρες, περιγράφει το Firewall για διακομιστές ιστού: άνοιγμα μόνο των απαραίτητων θυρών.

Άγνωστα ονόματα hosts και άλλες ρυθμίσεις

Χωρίς δικό του προεπιλεγμένο server, το Nginx απαντά σε αιτήματα για άγνωστα ονόματα hosts με το πρώτο κατάλληλο μπλοκ server. Οι αυτοματοποιημένες σαρώσεις που απευθύνονται μόνο στη διεύθυνση IP καταλήγουν τότε απευθείας στην εφαρμογή σας. Ένας δικός σας προεπιλεγμένος server τερματίζει τέτοια αιτήματα χωρίς απάντηση.

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

Περαιτέρω σημεία που έχουν αποδειχθεί:

Ρύθμιση Σύσταση Σκοπός
server_tokens off κανένας αριθμός έκδοσης σε κεφαλίδες και σελίδες σφαλμάτων
client_max_body_size ανάλογα με το post_max_size έγκαιρη απόρριψη μεγάλων αιτημάτων
autoindex απενεργοποιημένο (προεπιλογή) κανένας κατάλογος φακέλων
fastcgi_hide_header X-Powered-By καμία έκδοση PHP προς τα έξω
Σελίδες κατάστασης pm.status_path μόνο εσωτερικά κανένα δημόσιο στοιχείο λειτουργίας
Αρχεία backup αποκλεισμός ή αφαίρεση .sql, .zip, .bak στο webroot καμία λήψη βάσεων δεδομένων

Περισσότερα για τις ενδείξεις έκδοσης υπάρχουν στο άρθρο expose_php και κεφαλίδες Server.

Μια ακόμη ρύθμιση αφορά τις επιτρεπόμενες μεθόδους HTTP. Οι περισσότεροι ιστότοποι χρειάζονται μόνο GET, HEAD και POST. Με το limit_except μπορούν να απορριφθούν άλλες μέθοδοι σε ένα location· σύμφωνα με την τεκμηρίωση του Nginx, η ελευθέρωση του GET επιτρέπει αυτόματα και το HEAD. Ελέγξτε πρώτα αν διεπαφές της εφαρμογής σας χρησιμοποιούν π.χ. PUT ή DELETE, επειδή τα REST API το κάνουν συχνά.

Δοκιμή πριν από την επαναφόρτωση

Κάθε αλλαγή ελέγχεται πρώτα με nginx -t και μόνο μετά επαναφορτώνεται το Nginx. Στη συνέχεια δοκιμάζετε τη συμπεριφορά απ' έξω με κανονικά αιτήματα στο δικό σας domain:

sudo nginx -t && sudo systemctl reload nginx
# Αναμένεται: 403 ή 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
# Αναμένεται: 404, επειδή εκτελείται μόνο ο front controller
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/info.php
# Ποια μπλοκ παραδίδουν στο PHP-FPM;
sudo nginx -T 2>/dev/null | grep -nE "location|fastcgi_pass"

Διασφαλίστε πριν από κάθε μεγαλύτερη αλλαγή την πλήρη έξοδο του nginx -T με ημερομηνία. Περιέχει ολόκληρη την αποτελεσματική διαμόρφωση, συμπεριλαμβανομένων όλων των ενσωματωμένων αρχείων. Αν κάτι πάει στραβά μετά από μια αλλαγή, η σύγκριση δείχνει αμέσως τι διαφέρει. Στην επόμενη κρίσιμη ευπάθεια έχετε έτσι επιπλέον μια αξιόπιστη βάση για την καταγραφή, χωρίς να χρειαστεί να συγκεντρώνετε πρώτα αρχεία.

Συμβουλή

Αλλάξτε τη διαμόρφωση πρώτα σε περιβάλλον δοκιμών ή σε αντίγραφο του μπλοκ server. Ένα ξεχασμένο σημείο εισόδου, για παράδειγμα ένα callback πληρωμής, γίνεται αλλιώς αντιληπτό μόνο όταν σταματήσουν οι παραγγελίες.

Πώς βοηθά συγκεκριμένα η PHP SOS;

  • Ανάγνωση της διαμόρφωσης: Αξιολογούμε ολόκληρη τη διαμόρφωση του Nginx με nginx -T και αντιστοιχίζουμε κάθε παράδοση στην PHP στον ιστότοπο και στο pool της.
  • Καθορισμός σημείων εισόδου: Μαζί με τους προγραμματιστές σας καθορίζουμε ποια σενάρια πρέπει να εκτελούνται και αποκλείουμε τα υπόλοιπα.
  • Υλοποίηση και δοκιμή: Προσαρμόζουμε μπλοκ server και pools, ελέγχουμε με nginx -t και δοκιμάζουμε φόρμες, διαδρομές πληρωμής και ανεβάσματα.
  • Μόνιμη προστασία: Η διαμόρφωση γίνεται μέρος της σκλήρυνσης διακομιστή και της τεκμηρίωσης του διακομιστή σας.

Συχνές ερωτήσεις

Πρέπει να γίνει επανεκκίνηση του Nginx μετά από ενημέρωση της PHP;

Για το patch της PHP όχι, επειδή το Nginx δεν περιέχει PHP. Επανεκκίνηση πρέπει να γίνει σε όλες τις υπηρεσίες PHP-FPM. Αν αλλάζετε παράλληλα και τη διαμόρφωση του Nginx, ελέγξτε την πρώτα με nginx -t και επαναφορτώστε μετά το Nginx.

Γιατί να παραδίδεται στην PHP μόνο το index.php;

Πολλές σύγχρονες εφαρμογές έχουν ένα μόνο σημείο εισόδου, τον front controller. Αν παραδίδεται στο PHP-FPM μόνο αυτό το αρχείο, ένα αρχείο PHP που έχει εισαχθεί αλλού δεν μπορεί να εκτελεστεί μέσω του περιηγητή. Σε συστήματα με πολλά σημεία εισόδου αυτό το μοτίβο δεν είναι δυνατό.

Τι προσφέρει το security.limit_extensions στο PHP-FPM;

Η ρύθμιση ορίζει ποιες καταλήξεις αρχείων εκτελεί το PHP-FPM ως σενάριο. Σύμφωνα με το εγχειρίδιο της PHP η προεπιλογή είναι .php .phar· συνιστάται ο περιορισμός σε .php. Αυτό πιάνει σφάλματα στη διαμόρφωση του διακομιστή ιστού, αλλά δεν την αντικαθιστά.

Αποτελούν οι κανόνες του Nginx προστασία από το PHP2Shell;

Όχι. Το PHP2Shell βρίσκεται στον διερμηνέα PHP και κλείνει μόνο με ενημέρωση σε διορθωμένη έκδοση και επανεκκίνηση όλων των workers. Μια ασφαλής διαμόρφωση Nginx μικραίνει την επιφάνεια επίθεσης και περιορίζει τη ζημιά μετά από μια εισβολή.

Πηγές

Άμεση επικοινωνία

Κάθε ώρα μετράει. Γράψτε μας τώρα.

Περιγράψτε σύντομα το σύστημα, την έκδοση PHP και ό,τι παρατηρείτε. Θα επικοινωνήσουμε μαζί σας, θα διευκρινίσουμε την κατάσταση και θα εργαστούμε εξ αποστάσεως μέχρι το περιστατικό να κλείσει και να τεκμηριωθεί.

Άμεση βοήθεια