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

Απομόνωση των pools PHP-FPM ανά ιστότοπο

Ένα ξεχωριστό pool ανά ιστότοπο είναι η αρχή και όχι το τέλος. Δείτε πώς ελέγχετε τα υπάρχοντα pools και σκληραίνετε sockets, καταλήξεις, σελίδες κατάστασης, πόρους και logs.

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

Εν ολίγοις: Κάθε ιστότοπος σε έναν διακομιστή πρέπει να έχει δικό του pool PHP-FPM με δικό του χρήστη συστήματος και δικό του socket. Ο διαχωρισμός γίνεται όμως αποτελεσματικός μόνο με τις λεπτομέρειες: δικαιώματα socket μόνο για τον διακομιστή ιστού, security.limit_extensions σε .php, καμία δημόσια προσβάσιμη σελίδα κατάστασης, δικά του όρια για διεργασίες και χρόνο εκτέλεσης και χωριστά logs. Από το ίδιο το PHP2Shell προστατεύει μόνο η ενημέρωση· τα pools περιορίζουν πόσο μακριά φτάνει μια επίθεση.

Ένας διακομιστής, πολλοί ιστότοποι, ένας κοινός κίνδυνος

Σε πολλούς διακομιστές έχει αναπτυχθεί με τα χρόνια κάτι που κανείς δεν σχεδίασε έτσι. Ο ιστότοπος της εταιρείας, το κατάστημα, μια σελίδα καμπάνιας του 2019 και ένα δοκιμαστικό σύστημα λειτουργούν δίπλα-δίπλα, συχνά με τον ίδιο χρήστη και στο ίδιο pool. Αν παραβιαστεί η ξεχασμένη σελίδα καμπάνιας, εκτίθενται και τα δεδομένα πελατών του καταστήματος.

Το PHP-FPM, ο διαχειριστής διεργασιών FastCGI της PHP, το λύνει με pools: ομάδες διεργασιών worker με δικές τους ρυθμίσεις. Πώς λειτουργεί η βασική αρχή, εξηγεί το PHP-FPM: διαχειριστής διεργασιών, pools και workers. Τη δημιουργία διαχωρισμένων pools με δικό τους χρήστη, δικό τους φάκελο temp και open_basedir περιγράφει ο οδηγός open_basedir και απομόνωση ανά ιστότοπο. Αυτό το άρθρο πάει ένα βήμα πιο πέρα: πώς ελέγχετε τα υπάρχοντα pools και ποιες ρυθμίσεις κάνουν τον διαχωρισμό ανθεκτικό;

Σημαντικό για την τοποθέτηση: στο PHP2Shell οι ευπάθειες CVE-2026-109618 και CVE-2026-109619 βρίσκονται στον διερμηνέα PHP, τον οποίο μοιράζονται όλα τα pools μιας έκδοσης PHP. Ένα ξεχωριστό pool δεν εμποδίζει την εκμετάλλευση. Αποφασίζει όμως αν ένας επιτιθέμενος θα φτάσει στη συνέχεια έναν ιστότοπο ή όλους.

Pools PHP-FPM με δικό τους χρήστη: έλεγχος της υπάρχουσας κατάστασης

Προτού αλλάξετε κάτι, αποκτήστε μια εικόνα. Οι παρακάτω εντολές μόνο διαβάζουν. Οι διαδρομές και οι αριθμοί εκδόσεων διαφέρουν ανά διανομή:

# Όλα τα pools με χρήστη και socket
grep -HE '^\s*(\[|user|group|listen)\s*' /etc/php/*/fpm/pool.d/*.conf

# Pools που εκτελούνται και οι χρήστες τους
ps -eo user,pid,cmd | grep '[p]hp-fpm: pool'

# Sockets και τα δικαιώματά τους
ls -l /run/php/

# Έλεγχος της διαμόρφωσης για σφάλματα (δεν αλλάζει τίποτα)
sudo php-fpm8.3 -t

Προσέξτε τρία μοτίβα: περισσότεροι ιστότοποι στο ίδιο pool, pools που εκτελούνται ως www-data ή ακόμη και ως root, και sockets στα οποία μπορούν να γράφουν όλοι οι χρήστες. Καθένα από αυτά υπονομεύει τον διαχωρισμό.

Αν στον διακομιστή εκτελούνται πολλές εκδόσεις PHP, καθεμία έχει τη δική της υπηρεσία FPM με δικούς της φακέλους pool. Ελέγξτε όλες, όχι μόνο την έκδοση που ρυθμίσατε τελευταία. Ειδικά οι παλιές εκδόσεις με ξεχασμένα pools αποτελούν κίνδυνο, επειδή συχνά ούτε συντηρούνται ούτε επανεκκινούνται μετά τις ενημερώσεις. Υποδείξεις υπάρχουν στο Πολλές εκδόσεις PHP σε έναν διακομιστή. Καταγράψτε το αποτέλεσμα σε έναν μικρό πίνακα: ιστότοπος, pool, χρήστης, socket, έκδοση PHP. Αυτή η επισκόπηση αποτελεί ταυτόχρονα τη βάση για κάθε μεταγενέστερη αλλαγή.

Οι σημαντικότερες ρυθμίσεις ανά pool

Η παρακάτω επισκόπηση στηρίζεται στη διαμόρφωση FPM του εγχειριδίου της PHP. Οι τιμές για διεργασίες και χρόνους εξαρτώνται από το φορτίο και την εφαρμογή σας:

Ρύθμιση Σκοπός Σύσταση
user, group χρήστης των workers ξεχωριστός χρήστης ανά ιστότοπο, ποτέ root
listen.owner, listen.group, listen.mode δικαιώματα στο socket μόνο η ομάδα του διακομιστή ιστού, λειτουργία 0660
listen.acl_users πρόσβαση μέσω ACL αντί για ιδιοκτήτη καταχωρίστε μόνο τον χρήστη του διακομιστή ιστού
security.limit_extensions εκτελέσιμες καταλήξεις περιορισμός σε .php (προεπιλογή .php .phar)
clear_env εκκαθάριση μεταβλητών περιβάλλοντος αφήστε την προεπιλογή yes
pm.max_children μέγιστος αριθμός workers περιορισμός ώστε ένας ιστότοπος να μην εξαντλεί τον διακομιστή
request_terminate_timeout διακοπή αιτημάτων που κρέμονται ορισμός ανάλογα με το μακρύτερο θεμιτό αίτημα
pm.status_path, ping.path σελίδα κατάστασης και ping ορίστε τα μόνο αν χρειάζονται και προστατέψτε τα εσωτερικά
slowlog, request_slowlog_timeout καταγραφή αργών αιτημάτων ξεχωριστό αρχείο ανά pool

Ένα απόσπασμα για ένα σκληρυμένο pool μοιάζει ως εξής:

; /etc/php/8.3/fpm/pool.d/shop.conf (απόσπασμα)
[shop]
user = shop
group = shop
listen = /run/php/shop.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
request_terminate_timeout = 60s

security.limit_extensions = .php
clear_env = yes

slowlog = /var/log/php/shop.slow.log
request_slowlog_timeout = 10s
php_admin_value[error_log] = /var/log/php/shop.error.log

Ρυθμίσεις όπως το memory_limit ή το session.upload_progress.enabled τις ορίζετε ανά pool με php_admin_value και php_admin_flag. Σύμφωνα με το εγχειρίδιο, αυτές οι τιμές δεν μπορούν να αντικατασταθούν με ini_set(). Περισσότερα στο php_admin_value: κλείδωμα ρυθμίσεων κατά της αντικατάστασης.

Σωστή τοποθέτηση των σελίδων κατάστασης και της εναλλαγής workers

Τα pm.status_path και ping.path είναι ενεργά μόνο όταν έχουν οριστεί. Η σελίδα κατάστασης δείχνει αιτήματα που εκτελούνται, διεργασίες και φόρτο. Για την παρακολούθηση είναι χρήσιμη, αν είναι όμως δημόσια προσβάσιμη αποτελεί περιττή πηγή πληροφοριών για επιτιθέμενους. Προωθήστε αυτές τις διαδρομές στον διακομιστή ιστού μόνο για εσωτερικές διευθύνσεις. Πώς συνεργάζονται με ασφάλεια το Nginx και το PHP-FPM, περιγράφει το Ασφάλιση του Nginx με PHP-FPM.

Το pm.max_requests ορίζει μετά από πόσα αιτήματα επανεκκινείται ένας worker· η προεπιλογή είναι 0, δηλαδή ποτέ. Μια τιμή μεγαλύτερη από μηδέν βοηθά κατά της αργά αυξανόμενης κατανάλωσης μνήμης. Ως προστασία κατά του PHP2Shell δεν προορίζεται: το php.net δεν την αναφέρει στα μεταβατικά μέτρα και τονίζει ότι μόνο η ενημέρωση προστατεύει πλήρως. Μετά την ενημέρωση ισχύει επιπλέον: όλοι οι workers όλων των pools πρέπει να επανεκκινηθούν, επειδή οι παλιές διεργασίες αλλιώς συνεχίζουν να εκτελούνται με τον ευάλωτο κώδικα.

Συμβουλή

Διατηρείτε ένα πρότυπο για νέα pools και δημιουργείτε με αυτό κάθε νέο ιστότοπο. Έτσι ο διαχωρισμός προκύπτει αυτόματα, αντί να προστίθεται εκ των υστέρων χρόνια αργότερα.

Τυπικά λάθη κατά τη μετάβαση

Το συχνότερο λάθος είναι ένα νέο pool που εκτελείται μεν με δικό του χρήστη, τα αρχεία του όμως ανήκουν ακόμη στον www-data. Τότε το pool δεν μπορεί να γράψει εκεί που πρέπει και κάποιος ορίζει υπερβολικά γενναιόδωρα δικαιώματα. Διευκρινίστε εκ των προτέρων ποιοι φάκελοι πρέπει να είναι εγγράψιμοι. Το δεύτερο λάθος είναι οι προγραμματισμένες εργασίες που εκτελούνται ακόμη με τον παλιό χρήστη και δημιουργούν αρχεία με λάθος ιδιοκτήτη. Το τρίτο είναι ένας κοινός φάκελος session για όλα τα pools, που καταργεί ξανά τον διαχωρισμό.

Δοκιμάστε μετά από κάθε μετάβαση τη σύνδεση, τα uploads, τις κρυφές μνήμες και τις προγραμματισμένες εργασίες του ιστοτόπου και παρακολουθήστε το log σφαλμάτων του pool.

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

  • Καταγράφουμε όλα τα pools, τους χρήστες, τα sockets και τις ρυθμίσεις και δείχνουμε πού μοιράζονται σήμερα οι ιστότοποι διεργασίες ή δικαιώματα.
  • Δημιουργούμε για κάθε ιστότοπο ένα σκληρυμένο pool, με δικαιώματα socket, όριο καταλήξεων, όρια πόρων και δικά του logs.
  • Προστατεύουμε τις σελίδες κατάστασης, επανεκκινούμε ελεγχόμενα όλους τους workers και δοκιμάζουμε κάθε ιστότοπο.
  • Στο πλαίσιο της σκλήρυνσης διακομιστή τεκμηριώνουμε τον διαχωρισμό ως πρότυπο για μελλοντικά έργα.

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

Γιατί να έχει κάθε ιστότοπος δικό του pool PHP-FPM;

Ένα ξεχωριστό pool με ξεχωριστό χρήστη συστήματος διαχωρίζει τους ιστοτόπους σε επίπεδο διεργασιών και δικαιωμάτων αρχείων. Αν παραβιαστεί ένας ιστότοπος, ο κώδικας δεν μπορεί χωρίς άλλο να διαβάσει τα αρχεία των υπολοίπων. Επιπλέον, όρια και ρυθμίσεις μπορούν να οριστούν χωριστά για κάθε ιστότοπο.

Προστατεύει ένα ξεχωριστό pool από το PHP2Shell;

Όχι. Οι ευπάθειες βρίσκονται στον ίδιο τον διερμηνέα PHP, τον οποίο μοιράζονται όλα τα pools. Προστασία προσφέρει μόνο η ενημέρωση σε διορθωμένη έκδοση με επανεκκίνηση όλων των workers. Τα διαχωρισμένα pools περιορίζουν όμως πόσο μακριά φτάνει μια επιτυχημένη επίθεση.

Τι κάνει το security.limit_extensions;

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

Είναι επικίνδυνη η σελίδα κατάστασης του PHP-FPM;

Αποκαλύπτει λεπτομέρειες για διεργασίες και αιτήματα που εκτελούνται. Αν είναι δημόσια προσβάσιμη χωρίς προστασία, διευκολύνει τον προσανατολισμό των επιτιθέμενων. Σύμφωνα με το εγχειρίδιο, είναι ενεργή μόνο όταν έχει οριστεί το pm.status_path. Τότε ο διακομιστής ιστού πρέπει να περιορίζει τη διαδρομή σε εσωτερικές διευθύνσεις.

Πηγές

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

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

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

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