Εν συντομία: Το CGI (Common Gateway Interface) είναι μια παλιά διεπαφή, όπου ο διακομιστής ιστού ξεκινά για κάθε αίτημα ένα νέο πρόγραμμα, στην PHP το πρόγραμμα php-cgi. Το FastCGI είναι η εξέλιξή του: οι διεργασίες PHP εκτελούνται μόνιμα και δέχονται πολλά αιτήματα μέσω ενός socket. Το PHP-FPM είναι η σημαντικότερη υλοποίηση FastCGI για την PHP. Για την ασφάλεια έχουν σημασία κυρίως οι ρυθμίσεις cgi.* και ο κανόνας ότι μια πρόσβαση FastCGI δεν επιτρέπεται ποτέ να είναι δημόσια προσβάσιμη.
Τι είναι το CGI;
Το CGI είναι μία από τις παλαιότερες μεθόδους με τις οποίες οι διακομιστές ιστού παράγουν δυναμικό περιεχόμενο. Το εγχειρίδιο της PHP παραπέμπει στη ρύθμιση cgi.rfc2616_headers στο RFC 3875, την προδιαγραφή του Common Gateway Interface. Και οι απαρχές της PHP ήταν προγράμματα CGI: ο Rasmus Lerdorf έγραψε το 1994 τα πρώτα «Personal Home Page Tools» ως δυαδικά αρχεία CGI σε C.
Η αρχή: για κάθε αίτημα ο διακομιστής ιστού ξεκινά μια νέα διεργασία, παραδίδει τα δεδομένα του αιτήματος μέσω μεταβλητών περιβάλλοντος και της τυπικής εισόδου και διαβάζει την απάντηση από την τυπική έξοδο. Κατόπιν η διεργασία τερματίζεται. Σύμφωνα με το εγχειρίδιο της PHP, στο CGI και στο CLI η PHP διαβάζει το php.ini της εκ νέου σε κάθε κλήση, στις μονάδες διακομιστή μόνο κατά την εκκίνηση.
Αυτό κάνει το CGI στιβαρό, επειδή κάθε αίτημα ξεκινά με μια φρέσκια διεργασία. Το κάνει όμως και αργό: η εκκίνηση διεργασίας, η φόρτωση της διαμόρφωσης και η αρχικοποίηση των επεκτάσεων κοστίζουν χρόνο σε κάθε αίτημα.
Τι είναι το FastCGI;
Το FastCGI λύνει το πρόβλημα απόδοσης κρατώντας τις διεργασίες ζωντανές. Ο διακομιστής ιστού συνδέεται μέσω ενός Unix socket ή μιας θύρας TCP με μια εκτελούμενη διεργασία και της στέλνει το αίτημα στο πρωτόκολλο FastCGI. Η διεργασία το επεξεργάζεται και περιμένει το επόμενο.
| Χαρακτηριστικό | CGI | FastCGI με php-cgi | FastCGI με PHP-FPM |
|---|---|---|---|
| Διεργασία ανά αίτημα | ναι | όχι | όχι |
| Όνομα SAPI | cgi-fcgi |
cgi-fcgi |
fpm-fcgi |
| Pools με δικό τους χρήστη | όχι | όχι | ναι |
| Έλεγχος διεργασιών | διακομιστής ιστού | μονάδα διακομιστή ιστού, π.χ. mod_fcgid | δική του διεργασία master |
Διαβάζεται το .user.ini |
ναι | ναι | ναι |
Το PHP-FPM είναι σύμφωνα με το εγχειρίδιο η κύρια υλοποίηση FastCGI της PHP. Συμπληρώνει το πρωτόκολλο με διαχείριση διεργασιών, pools, σελίδες κατάστασης και slowlog. Οι λεπτομέρειες βρίσκονται στη σελίδα Το PHP-FPM εξηγημένο.
Οι ρυθμίσεις cgi στο php.ini
Για τη λειτουργία CGI η PHP διαθέτει δικές της ρυθμίσεις. Οι παρακάτω τιμές και περιγραφές προέρχονται από το εγχειρίδιο της PHP:
cgi.force_redirect(προεπιλογή 1,INI_SYSTEM): σύμφωνα με το εγχειρίδιο απαραίτητο, για να λειτουργεί η PHP ως CGI με ασφάλεια στους περισσότερους διακομιστές ιστού. Απενεργοποίηση μόνο «με δική σας ευθύνη»· στο IIS πρέπει να είναι απενεργοποιημένο.cgi.fix_pathinfo(προεπιλογή 1,INI_SYSTEM): φροντίζει για σωστές τιμέςPATH_INFOκαιPATH_TRANSLATED. Τα σενάρια πρέπει να χρησιμοποιούν τοSCRIPT_FILENAMEαντί για τοPATH_TRANSLATED.cgi.discard_path(προεπιλογή 0,INI_SYSTEM): επιτρέπει την ασφαλή τοποθέτηση του δυαδικού αρχείου CGI εκτός του καταλόγου ιστού, χωρίς να μπορεί να παρακαμφθεί η προστασία.htaccess.fastcgi.impersonate(προεπιλογή 0,INI_SYSTEM): σχετικό μόνο για το IIS στα Windows.user_ini.filenameκαιuser_ini.cache_ttl(προεπιλογή.user.iniκαι 300 δευτερόλεπτα): ελέγχουν αν και πόσο συχνά διαβάζει η PHP αρχεία.user.ini.
Στον Nginx ανήκει σε αυτά και μια σωστή παράδοση της διαδρομής του σεναρίου. Ένα ευανάγνωστο βασικό πρότυπο, χωρίς εγγύηση για κάθε περιβάλλον:
location ~ \.php$ {
try_files $uri =404; # να δίνονται στην PHP μόνο υπάρχοντα αρχεία
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Η γραμμή try_files $uri =404; εμποδίζει την προώθηση στην PHP αιτημάτων προς ανύπαρκτες διαδρομές .php.
Γιατί μια ανοιχτή πρόσβαση FastCGI είναι επικίνδυνη
Το εγχειρίδιο της PHP προειδοποιεί ρητά: όποιος μπορεί να ανοίξει μια σύνδεση FastCGI προς την PHP, ελέγχει τη διαμόρφωση του αιτήματος, για παράδειγμα το auto_prepend_file, και μπορεί έτσι να εκτελέσει αυθαίρετο κώδικα. Ο λόγος είναι ότι οι διακομιστές ιστού επιτρέπεται να στέλνουν ρυθμίσεις PHP μέσω παραμέτρων FastCGI όπως τα PHP_VALUE και PHP_ADMIN_VALUE.
Από αυτό προκύπτουν σαφείς κανόνες:
- Συνδέστε το PHP-FPM ή το php-cgi σε λειτουργία FastCGI μόνο μέσω Unix socket, όταν ο διακομιστής ιστού εκτελείται στον ίδιο host.
- Στο TCP ορίστε το
listen.allowed_clientsκαι αποκλείστε τη θύρα στο firewall· υποδείξεις στο άρθρο Firewall για διακομιστές ιστού. - Κρατήστε τα δικαιώματα του socket στενά με τα
listen.owner,listen.groupκαιlisten.mode.
Ελέγξτε με το ss -lntp | grep -i php αν κάποια διεργασία PHP ακούει σε διεύθυνση TCP. Μια δέσμευση στο 0.0.0.0 ή σε δημόσια διεύθυνση είναι επείγουσα περίπτωση παρέμβασης.
CGI, FastCGI και PHP2Shell
Το PHP2Shell επηρεάζει τόσο το php-cgi όσο και το PHP-FPM. Και για τα δύο ισχύει: ενημέρωση στις 8.5.12, 8.4.27, 8.3.36 ή 8.2.35, αντίστοιχα σε ένα επιβεβαιωμένο backport, και έπειτα τερματισμός και επανεκκίνηση όλων των εκτελούμενων διεργασιών PHP. Σε διαμορφώσεις FastCGI με php-cgi οι διεργασίες συχνά συνεχίζουν απαρατήρητες, επειδή καμία δική τους υπηρεσία δεν τις διαχειρίζεται. Πώς θα βρείτε και θα αντικαταστήσετε αυτή την παλιά κληρονομιά, περιγράφει η σελίδα php-cgi: παλιά κληρονομιά με κίνδυνο. Στο Plesk οι παραλλαγές ονομάζονται διαφορετικά· βοήθεια δίνει το άρθρο Plesk: κατανόηση των χειριστών PHP.
Πώς βοηθά συγκεκριμένα η PHP SOS;
- Καταγραφή χειριστών: Εντοπίζουμε αν οι ιστότοποί σας εκτελούνται μέσω CGI, FastCGI με php-cgi ή PHP-FPM.
- Κλείσιμο προσβάσεων: Ελέγχουμε sockets, θύρες και κανόνες firewall, ώστε καμία πρόσβαση FastCGI να μην είναι προσβάσιμη από έξω.
- Patch και καθαρισμός: Ενημερώνουμε την PHP και τερματίζουμε όλες τις παλιές διεργασίες, ακόμη και ορφανές εγκαταστάσεις php-cgi.
- Αντικατάσταση: Στο πλαίσιο της θωράκισης διακομιστή αντικαθιστούμε τις παλιές κληρονομιές CGI με PHP-FPM με δικά του pools.
Συχνές ερωτήσεις
Είναι το FastCGI το ίδιο με το PHP-FPM;
Όχι. Το FastCGI είναι ένα πρωτόκολλο μέσω του οποίου ένας διακομιστής ιστού μιλά με μια διεργασία εφαρμογής. Το PHP-FPM είναι ένα πρόγραμμα που υλοποιεί αυτό το πρωτόκολλο για την PHP και διαχειρίζεται τις διεργασίες. Και το php-cgi μπορεί να μιλά FastCGI, δεν προσφέρει όμως pools.
Γιατί το καθαρό CGI θεωρείται παρωχημένο;
Στο CGI ο διακομιστής ιστού ξεκινά για κάθε αίτημα μια νέα διεργασία και η PHP διαβάζει κάθε φορά τη διαμόρφωσή της. Αυτό κοστίζει χρόνο και πόρους. Το FastCGI και το PHP-FPM κρατούν διεργασίες μόνιμα έτοιμες και είναι γι' αυτό σαφώς πιο αποδοτικά.
Τι είναι ένα .user.ini;
Ένα .user.ini είναι ένα μικρό αρχείο διαμόρφωσης σε έναν κατάλογο ιστού. Σύμφωνα με το εγχειρίδιο της PHP διαβάζεται μόνο από τα SAPI CGI και FastCGI, άρα και από το PHP-FPM. Επιτρέπεται να περιέχει μόνο ρυθμίσεις με τους τρόπους INI_PERDIR, INI_USER ή INI_ALL.
Πώς καταλαβαίνω αν στον διακομιστή μου εκτελείται php-cgi;
Αναζητήστε με εντολές μόνο ανάγνωσης όπως το ps ή το pgrep διεργασίες με το όνομα php-cgi και δείτε στη διαμόρφωση του διακομιστή ιστού για εγγραφές όπως mod_fcgid, Action ή ScriptAlias με php-cgi. Στα πάνελ φιλοξενίας ο τρόπος λειτουργίας λέγεται συχνά CGI ή εφαρμογή FastCGI.