# php_admin_value: κλείδωμα ρυθμίσεων κατά της αντικατάστασης

> php_admin_value και php_admin_flag: πώς κλειδώνετε τιμές PHP σε pool FPM και Apache έναντι ini_set(), .htaccess και .user.ini και πώς το ελέγχετε.

Πηγή: https://phpsos.de/el/blog/php-admin-value-sperren/  
Ημερομηνία: 25/10/2026  
Πάροχος: PHP SOS, Επείγουσα βοήθεια PHP και ασφάλεια διακομιστών. Άμεση βοήθεια μέσω WhatsApp: https://wa.me/491736494914?text=%CE%93%CE%B5%CE%B9%CE%B1%20%CF%83%CE%B1%CF%82%2C%20PHP%20SOS%2C%20%CF%87%CF%81%CE%B5%CE%B9%CE%B1%CE%B6%CF%8C%CE%BC%CE%B1%CF%83%CF%84%CE%B5%20%CE%B2%CE%BF%CE%AE%CE%B8%CE%B5%CE%B9%CE%B1%20%CE%BC%CE%B5%20%CF%84%CE%BF%CE%BD%20%CE%B4%CE%B9%CE%B1%CE%BA%CE%BF%CE%BC%CE%B9%CF%83%CF%84%CE%AE%20PHP%20%CE%BC%CE%B1%CF%82.%20%CE%95%CF%84%CE%B1%CE%B9%CF%81%CE%B5%CE%AF%CE%B1%3A%20%E2%80%A6%20%CE%99%CF%83%CF%84%CF%8C%CF%84%CE%BF%CF%80%CE%BF%CF%82%3A%20%E2%80%A6

**Εν ολίγοις:** Τα `php_admin_value` και `php_admin_flag` ορίζουν ρυθμίσεις PHP στο pool του PHP-FPM ή στη διαμόρφωση του Apache έτσι ώστε οι εφαρμογές να μην μπορούν να τις αλλάξουν ούτε με `ini_set()` ούτε με `.htaccess`. Το php.net απαιτεί ακριβώς αυτό για τα μεταβατικά μέτρα του PHP2Shell, για παράδειγμα για το `memory_limit=-1`. Μετά τον ορισμό η υπηρεσία πρέπει να επανεκκινηθεί και η τιμή να ελεγχθεί στο πλαίσιο του web.

## Γιατί «ορισμένο» δεν σημαίνει «κλειδωμένο»

Τις ημέρες μετά τις 21 Οκτωβρίου 2026 πολλοί διαχειριστές έγραψαν τα μεταβατικά μέτρα του php.net στο php.ini τους. Μια λεπτομέρεια της σύστασης συχνά χάθηκε: το `memory_limit=-1` πρέπει να οριστεί έτσι ώστε οι εφαρμογές να μην μπορούν να το αντικαταστήσουν. Το php.net αναφέρει γι' αυτό ρητά το `php_admin_value` στο pool FPM ή στη διαμόρφωση του Apache.

Ο λόγος είναι απλός. Πολλά CMS, καταστήματα και frameworks ορίζουν τις δικές τους τιμές, για παράδειγμα υψηλότερο όριο μνήμης για εισαγωγές. Αν η τιμή βρίσκεται μόνο στο php.ini, η εφαρμογή την αντικαθιστά στην επόμενη κλήση. Το μέτρο προστασίας υπάρχει τότε στα χαρτιά, αλλά όχι στη διεργασία που εκτελείται.

Αυτό δεν αφορά μόνο το PHP2Shell. Κάθε σκλήρυνση, από τις απενεργοποιημένες εξόδους σφαλμάτων έως τα όρια ανεβάσματος, είναι τόσο ισχυρή όσο το πιο αδύναμο επίπεδό της.

## Ποιος επιτρέπεται να αλλάζει ρυθμίσεις PHP

Η PHP γνωρίζει τέσσερις τρόπους αλλαγής. Κάθε ρύθμιση έχει έναν από αυτούς και καθορίζει σε ποια σημεία μπορεί να οριστεί. Οι σημασίες προέρχονται από το εγχειρίδιο της PHP.

| Τρόπος | Πού μπορεί να οριστεί η τιμή | Παραδείγματα |
|---|---|---|
| `INI_USER` | στο σενάριο με `ini_set()` και στο `.user.ini` | λίγες τιμές εκτέλεσης |
| `INI_PERDIR` | php.ini, `.htaccess`, `httpd.conf`, `.user.ini` | `post_max_size`, `session.upload_progress.enabled` |
| `INI_SYSTEM` | μόνο php.ini ή `httpd.conf` | `file_uploads`, `disable_functions` |
| `INI_ALL` | παντού, ακόμη και με `ini_set()` | `memory_limit`, `display_errors`, `open_basedir` |

Επικίνδυνες είναι κυρίως οι τιμές `INI_ALL`: μπορούν να αλλάξουν από οποιοδήποτε σενάριο. Οι τιμές `INI_PERDIR` δεν αλλάζουν μεν με `ini_set()`, αλλάζουν όμως μέσω ενός `.htaccess` με mod_php ή ενός `.user.ini` με PHP-FPM. Όποιος έχει δικαιώματα εγγραφής στο webroot, άρα και ο κώδικας που έχει εισαχθεί, μπορεί να δημιουργήσει τέτοια αρχεία.

## php_admin_value στο pool FPM και στον Apache

Στο PHP-FPM οι τιμές βρίσκονται στο αρχείο του pool. Το εγχειρίδιο της PHP ορίζει: οι τιμές που ορίζονται με `php_admin_value` και `php_admin_flag` δεν μπορούν να αντικατασταθούν με `ini_set()`. Για τιμές ενεργοποίησης-απενεργοποίησης χρησιμοποιείτε `php_admin_flag`, για όλες τις άλλες `php_admin_value`.

```ini
; /etc/php/8.3/fpm/pool.d/seite1.conf (απόσπασμα)
[seite1]
user = seite1
group = seite1
listen = /run/php/seite1.sock

php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_flag[session.upload_progress.enabled] = off
php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php/seite1-fehler.log
php_admin_value[open_basedir] = /var/www/seite1/:/tmp/seite1/
```

Το `memory_limit=-1` ανήκει σύμφωνα με το php.net στη διαμόρφωση μόνο μαζί με όριο μνήμης μέσω container ή cgroup. Πώς επιτυγχάνεται αυτό με το systemd, αναφέρεται στο άρθρο [Ορισμός ορίων μνήμης με systemd και cgroups](https://phpsos.de/el/blog/speichergrenzen-systemd-cgroups/).

Στον Apache με mod_php οι οδηγίες ανήκουν στη διαμόρφωση διακομιστή ή στο VirtualHost. Σύμφωνα με το εγχειρίδιο της PHP δεν επιτρέπονται στο `.htaccess` και, μόλις οριστούν, ούτε το `.htaccess` ούτε το `ini_set()` μπορούν να τις αλλάξουν.

```apache
<VirtualHost *:443>
    ServerName www.example.de
    DocumentRoot /var/www/seite1/public
    <IfModule php_module>
        php_admin_value memory_limit -1
        php_admin_value post_max_size 32M
        php_admin_value upload_max_filesize 24M
        php_admin_flag session.upload_progress.enabled off
        php_admin_flag display_errors off
    </IfModule>
</VirtualHost>
```

Δύο λεπτομέρειες από το εγχειρίδιο: για να διαγράψετε μια τιμή που ορίστηκε νωρίτερα, χρησιμοποιήστε `none` ως τιμή. Και οι σταθερές PHP όπως το `E_ALL` δεν έχουν νόημα στη διαμόρφωση του Apache· για το `error_reporting` πρέπει να δώσετε εκεί την αριθμητική τιμή.

## Ποιες τιμές πρέπει να κλειδώσετε

Δεν χρειάζεται να κλειδωθεί κάθε ρύθμιση. Έχει νόημα για ό,τι αφορά την ασφάλεια ή χρησιμεύει ως μεταβατικό μέτρο:

1. Οι μεταβατικές τιμές του php.net για το PHP2Shell: `memory_limit`, `post_max_size`, `upload_max_filesize`, `session.upload_progress.enabled` και στην PHP 8.5 `fatal_error_backtraces`.
2. Έξοδος σφαλμάτων και καταγραφή: `display_errors`, `display_startup_errors`, `log_errors`, `error_log`.
3. Πρόσβαση σε αρχεία και απομόνωση: `open_basedir`, `upload_tmp_dir`, `session.save_path`.
4. Προσβάσεις δικτύου από την PHP: `allow_url_include` και, αν η εφαρμογή δεν το χρειάζεται, `allow_url_fopen`.
5. Αποκλεισμένες συναρτήσεις μέσω `disable_functions`, που στο pool συμπληρώνουν σύμφωνα με το εγχειρίδιο τη λίστα του php.ini και δεν την αντικαθιστούν. Λεπτομέρειες στον οδηγό [Σωστή χρήση του disable_functions](https://phpsos.de/el/ratgeber/disable-functions/).

Στο `session.upload_progress.enabled` το κλείδωμα είναι ιδιαίτερα σημαντικό, επειδή αλλιώς η τιμή θα μπορούσε να ενεργοποιηθεί ξανά μέσω ενός `.user.ini`. Περισσότερα στο [Απενεργοποίηση του session.upload_progress: σωστά και μόνιμα](https://phpsos.de/el/blog/session-upload-progress-abschalten/).

## Έλεγχος αν το κλείδωμα ισχύει

Μετά από κάθε αλλαγή επανεκκινείτε την υπηρεσία και ελέγχετε την τιμή στο πλαίσιο του web. Ένα σύντομο αρχείο ελέγχου που διαγράφεται αμέσως δείχνει αν το pool κρατά την τιμή, ακόμη κι όταν η εφαρμογή θέλει να την αλλάξει:

```php
<?php
// Αρχείο ελέγχου: αφήστε το για λίγο, καλέστε το μία φορά μέσω του domain, διαγράψτε το αμέσως
header('Content-Type: text/plain');
$vorher = ini_get('memory_limit');
$versuch = @ini_set('memory_limit', '256M');
echo "memory_limit: $vorher\n";
echo 'Änderung per ini_set() ', ($versuch === false ? 'blockiert' : 'MÖGLICH'), "\n";
```

Αναμένεται `-1` και «blockiert». Αν η έξοδος είναι «MÖGLICH», η τιμή δεν έχει οριστεί μέσω `php_admin_value` ή η υπηρεσία δεν έχει ακόμη επανεκκινηθεί. Επαναλάβετε τον έλεγχο για κάθε pool και κάθε έκδοση PHP.

> **Συμβουλή:**
> Κρατήστε τις κλειδωμένες τιμές κεντρικά, για παράδειγμα σε ένα πρότυπο pool ή στη διαχείριση διαμόρφωσής σας. Οι πίνακες ελέγχου φιλοξενίας αντικαθιστούν εν μέρει χειροκίνητα αλλαγμένα αρχεία pool στην επόμενη αποθήκευση· εκεί οι τιμές ανήκουν στα πεδία που προβλέπει ο πίνακας.

Πώς οργανώνει συνολικά η PHP τα επίπεδα διαμόρφωσής της, εξηγεί το [Το php.ini εξηγημένο: δομή, επίπεδα και προτεραιότητα](https://phpsos.de/el/php/php-ini-erklaert/). Τα πλήρη μεταβατικά μέτρα υπάρχουν στο [Άμεσα μέτρα όταν δεν μπορείτε ακόμη να εφαρμόσετε patch](https://phpsos.de/el/php2shell/sofortmassnahmen-ohne-patch/).

## Συμπέρασμα: μόνο το κλειδωμένο είναι πραγματικά ορισμένο

Τα μεταβατικά μέτρα του php.net για το PHP2Shell έφεραν στη συνείδηση μια διάκριση που πριν συχνά παραβλεπόταν: μια τιμή στο php.ini είναι για πολλές ρυθμίσεις απλώς πρόταση, μια τιμή στο `php_admin_value` είναι προδιαγραφή. Για ρυθμίσεις άνεσης όπως η ζώνη ώρας η διαφορά είναι αμελητέα. Για ρυθμίσεις ασφαλείας και μεταβατικά μέτρα αποφασίζει αν το μέτρο ισχύει καν στη λειτουργία.

Η προσπάθεια είναι διαχειρίσιμη: μια χούφτα γραμμές ανά pool ή VirtualHost, μια επανεκκίνηση, ένας σύντομος έλεγχος. Κρατήστε τη λίστα των κλειδωμένων τιμών μικρή και αιτιολογημένη, ώστε οι προγραμματιστές να κατανοούν γιατί η εφαρμογή τους δεν επιτρέπεται να αλλάξει μια τιμή. Και συντηρήστε τη λίστα στα πρότυπά σας, ώστε οι νέοι ιστότοποι να την κληρονομούν αυτόματα.

## Πώς βοηθά συγκεκριμένα η PHP SOS;

- **Ανάγνωση των επιπέδων:** Εντοπίζουμε για κάθε ιστότοπο ποιες τιμές από php.ini, pool, Apache, `.htaccess` ή `.user.ini` ισχύουν πραγματικά.
- **Ορισμός κλειδωμάτων:** Καταχωρίζουμε τις τιμές που αφορούν την ασφάλεια και τα μεταβατικά μέτρα του PHP2Shell ως `php_admin_value` αντίστοιχα `php_admin_flag` και επανεκκινούμε τις υπηρεσίες.
- **Δοκιμή της εφαρμογής:** Ελέγχουμε αν η εφαρμογή εκτελείται χωρίς σφάλματα με τις κλειδωμένες τιμές και αξιολογούμε το log σφαλμάτων.
- **Συντήρηση προτύπων:** Στο πλαίσιο της [σκλήρυνσης διακομιστή](https://phpsos.de/el/leistungen/server-haertung/) περνάμε τις τιμές σε πρότυπα pool και τεκμηρίωση.


## Συχνές ερωτήσεις

**Ποια είναι η διαφορά ανάμεσα στο php_value και στο php_admin_value;**  
Και τα δύο ορίζουν μια ρύθμιση PHP. Τις τιμές από το php_value μπορεί η εφαρμογή να τις αλλάξει αργότερα, για παράδειγμα με ini_set() ή .htaccess. Οι τιμές από το php_admin_value και το php_admin_flag είναι σύμφωνα με το εγχειρίδιο της PHP κλειδωμένες για το ini_set(), στον Apache και για το .htaccess.

**Μπορώ να γράψω το php_admin_value σε αρχείο .htaccess;**  
Όχι. Σύμφωνα με το εγχειρίδιο της PHP, το php_admin_value δεν επιτρέπεται σε αρχεία .htaccess. Ανήκει στη διαμόρφωση διακομιστή του Apache ή στο VirtualHost, στο PHP-FPM στο αρχείο του pool.

**Τι συμβαίνει όταν μια εφαρμογή θέλει να αλλάξει μια κλειδωμένη τιμή;**  
Η κλήση του ini_set() αποτυγχάνει και επιστρέφει false, η κλειδωμένη τιμή παραμένει. Οι καλά προγραμματισμένες εφαρμογές το διαχειρίζονται. Ελέγξτε παρ' όλα αυτά μετά τη μετάβαση το log σφαλμάτων και τις σημαντικότερες λειτουργίες.

**Πρέπει να κάνω επανεκκίνηση μετά από αλλαγή στο pool;**  
Ναι. Το PHP-FPM διαβάζει τα αρχεία των pools κατά την εκκίνηση ή κατά την επαναφόρτωση της υπηρεσίας. Στον Apache με mod_php ισχύει το ίδιο για τη διαμόρφωση του διακομιστή. Χωρίς επανεκκίνηση εξακολουθεί να ισχύει η παλιά τιμή.

**Μπορεί το disable_functions να επεκταθεί στο pool;**  
Ναι, με μια ιδιαιτερότητα: σύμφωνα με το εγχειρίδιο της PHP, το disable_functions στο pool FPM δεν αντικαθιστά τις τιμές από το php.ini, αλλά τις συμπληρώνει. Το pool μπορεί επομένως να αποκλείσει επιπλέον συναρτήσεις, αλλά δεν μπορεί να ελευθερώσει καμία.

## Πηγές

- [Εγχειρίδιο της PHP: διαμόρφωση FPM](https://www.php.net/manual/en/install.fpm.configuration.php)
- [Εγχειρίδιο της PHP: αλλαγή της διαμόρφωσης](https://www.php.net/manual/en/configuration.changes.php)
- [Εγχειρίδιο της PHP: τρόποι αλλαγής των ρυθμίσεων](https://www.php.net/manual/en/configuration.changes.modes.php)
- [php.net: ανακοινώσεις ασφαλείας](https://www.php.net/)
