2011-09-08 19 views
9

Attualmente sto migrando la mia LAMP dal mio Windows Server a un VPS con Debian 6. La maggior parte di tutto funziona, tuttavia, uno degli script PHP non riusciva a scrivere al suo file di registro configurato. Non sono riuscito a determinare il motivo, quindi ho scritto un nuovo script PHP semplice e ingegnoso per testare il problema.PHP fopen() non riesce sui file anche con permessi aperti

<?php 
     ini_set('display_errors', 1); 
     error_reporting(E_ALL); 
     echo exec('whoami'); 
     $log = fopen('/var/log/apache2/writetest/writetest.log', 'a'); 
     if ($log != NULL) 
     { 
       fflush($log); 
       fclose($log); 
       $log = NULL; 
     } 
?> 

Tuttavia, non riesce con il risultato:

www-data Warning: fopen(/var/log/apache2/writetest/writetest.log): failed to open stream: Permission denied in /var/www/_admin/phpwritetest.php on line 5 
  • Mentre non avrei mai farlo normalmente, per aiutare a diagnosticare, ho impostato /var/log/apache2/writetest/writetest.log a chmod 777.
  • Sia la directory e il file è di proprietà di www-data:www-data.
  • Il file è stato creato con touch.

ho corse strace per verificare quale processo stava eseguendo all'aperto:

[pid 21931] lstat("/var/log/apache2/writetest/writetest.log", 0x7fff81677d30) = -1 EACCES (Permission denied) 
[pid 21931] lstat("/var/log/apache2/writetest", 0x7fff81677b90) = -1 EACCES (Permission denied) 
[pid 21931] open("/var/log/apache2/writetest/writetest.log", O_RDWR|O_CREAT|O_TRUNC, 0666) = -1 EACCES (Permission denied) 

ho controllato e PID 21931 era davvero uno dei processi apache2 bambino che corre sotto www-data. Come puoi vedere, ho incluso anche echo exec('whoami'); nella sceneggiatura che ha confermato che lo script era in esecuzione da www-data.

Altre note:

  • PHP non è in esecuzione in modalità provvisoria
  • PHP open_basedir non è impostato informazioni
  • Versione: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze3 with Suhosin-Patch mod_ssl/2.2.16 OpenSSL/0.9.8o
  • uname -a: 2.6.32-238.19.1.el5.028stab092.2 #1 SMP Thu Jul 21 19:23:22 MSD 2011 x86_64 GNU/Linux
  • questo è su una VPS in esecuzione con OpenVZ
  • ls -l (file): -rwxrwxrwx 1 www-data www-data 0 Sep 8 18:13 writetest.log
  • ls -l (directory): drwxr-xr-x 2 www-data www-data 4096 Sep 8 18:13 writetest
  • processo padre di Apache2 gira sotto root, ed i processi bambino di età inferiore www-data
  • SELinux non è installato (grazie a Fabio per avermi ricordato di menzionare questo)
  • ho riavviato Apache molte volte e riavviato il server pure

risposta

13

Ricordare che per raggiungere un file, TUTTE le directory madri devono essere leggibili da www-data. L'output strace sembra indicare che anche l'accesso a/var/log/apache2/writetest non funziona. Assicurarsi che www-data ha autorizzazioni per le seguenti directory:

  • / (r-x)
  • /var (r-x)
  • /var/log (r-x)
  • /var/log/apache2 (r-x)
  • /var/log/apache2/writetest (rwx)
  • /var/log/apache2/writetest/writetest.log (rw-)
+1

Questo era quello che avevo trascurato. '/ var/log/apache' mancava (r-x) mentre il resto era corretto. Grazie mille. – Gregyski

+1

Devi amare quei sentimenti istintivi. –

0

Il file php che esegue la scrittura ha le autorizzazioni corrette impostate? Prova a cambiarli per vedere se questo è il problema.

+0

Il permesso è '0666' come indicato dal suo stret – Cyclone

+0

Non lo vedo nel post? Vedo che i file .log sono 0666 e la cartella contenente ma non le autorizzazioni al file .php che sta scrivendo. – Adam

+0

Se il file php può essere eseguito, non dovrebbe essere in grado di scrivere sul file se le autorizzazioni dell'altro file sono accurate? – Cyclone

0

Potrebbe essere un problema SELinux, anche se Debian non lo spedisce nell'installazione predefinita, il provider potrebbe averlo abilitato. Se vuoi inserire messaggi in /var/log con

grep -i selinux /var/log/{syslog,messages} 

Se questo è la causa ed è necessario disabilitarlo, qui le istruzioni: cercare il file /etc/selinux/config, qui è contenuto predefinito. Modificare la direttiva SELINUX su disabled e riavviare il sistema.

# This file controls the state of SELinux on the system. 
# SELINUX= can take one of these three values: 
# enforcing - SELinux security policy is enforced. 
# permissive - SELinux prints warnings instead of enforcing. 
# disabled - SELinux is fully disabled. 
SELINUX=disabled 
# SELINUXTYPE= type of policy in use. Possible values are: 
# targeted - Only targeted network daemons are protected. 
# strict - Full SELinux protection. 
SELINUXTYPE=targeted 
+0

Grazie per il suggerimento e l'eccellente spiegazione su come controllarlo, ma selinux non è sicuramente installato. Avevo controllato prima, ma avevo dimenticato di menzionarlo nella mia domanda. Ma ho visto altri per i quali questa era la causa, quindi spero che la tua risposta aiuti gli altri in futuro. – Gregyski