2011-11-15 13 views
7

Tengo una muy simple script de prueba:La conexión de PDO funciona desde la línea de comandos, pero no a través de Apache.

<?php 

$DSN = "mysql:host=db.example.edu;port=3306;dbname=search_data"; 

try { 

    $DB = new PDO($DSN, "username", "super-secret-password!"); 

} catch (PDOException $e) { 

    header('Content-Type: text/plain'); 
    print "Could not connect to database, rawr. :-("; 
    exit; 

} 


$SQL = "SELECT phrase FROM search ORDER BY RAND() LIMIT 10"; 

foreach($DB->query($SQL) as $row){ 

    print $row['phrase']."\n"; 

} 

?> 

Cuando ejecuto este script desde la línea de comandos, funciona perfectamente:

$ php test.php 
corporal punishment 
Stretches 
voluntary agencies and the resettlement of refugees 
music and learning 
Nike Tiger Woods Scandal 
Hermeneia 
PSYCHINFO 
anthony bourdain 
Black-White Couples and their Social Worlds 
colonization, hodge 

Pero cuando accedo a la misma escritura exacta a través de mi navegador web , que dice:

Could not connect to database, rawr. :-(

he intentado var_dump en el error, y el mensaje es: "SQLSTATE [HY000] [2003] no se puede conectar al servidor MySQL en ' db.example.edu '(13) ".

Esto es desconcertante. Es exactamente la misma secuencia de comandos en el mismo servidor exacto: ¿por qué funciona cuando lo ejecuto desde la línea de comandos, pero falla cuando Apache lo ejecuta?

+0

¿Se trata de un servidor Linux? ¿Red Hat o CentOS ejecutan SELinux? Si es así, puede necesitar habilitar los booleanos de SELinux 'httpd_can_network_connect' y' httpd_can_network_connect_db' para permitir que Apache establezca conexiones con un host de base de datos remota. –

+1

más información sobre este error (13 = permiso denegado) está aquí: http://www.filonov.com/blog/2009/08/07/sqlstatehy000-2003-cant-connect-to-mysql-server-on-xxx -xxx-xxx-xxx-13/ – thetaiko

+0

@Michael Sí, es un servidor RHEL 6.1, y uno brillante nuevo en eso. Además, @thetaiko - ¡funcionó! Fue SELinux bloqueando la conexión, y ejecutando 'setsebool -P httpd_can_network_connect = 1' como root lo arregló. Si quieres publicar eso como respuesta, aceptaré y votaré felizmente. –

Respuesta

24

Si se trata de una distribución derivada de Red Hat (RHEL, CentOS, Fedora, ScientificLinux) que ejecuta SELinux (o cualquier derivado que no sea de Red Hat utilizando SELinux), la configuración de política predeterminada en este momento es prohibir que Apache conexiones externas a otros servidores o bases de datos. Como root, debe habilitar los siguientes dos booleanos de SELinux. Use la opción -P para conservar el cambio en un reinicio.

setsebool -P httpd_can_network_connect=1 
setsebool -P httpd_can_network_connect_db=1 

Tenga en cuenta que httpd_can_network_connect puede que no sea necesario. Pruébelo primero encendiendo solo httpd_can_network_connect_db.

+2

¡Gracias! La línea 'httpd_can_network_connect' no era necesaria en mi caso, solo la línea' httpd_can_network_connect_db'. –

+0

Usted me salvó el día. Muchas gracias ◕‿◕ – PHPst

+0

si no ha votado a favor, por favor hágalo ... – bart2puck

0

tuve el mismo problema para ftp_connect PHP FTP y tuvo que ajustar la

setsebool -P httpd_can_network_connect=1 

Es confuso porque otras cosas como fil_get_contents y el trabajo rizo a través de PHP y Apache bien antes de eso.

-1

mismo problema pero diferente porque aquí
Mi solución era sólo un simple apt-get install php-mysql distancia

Asegúrese de cheque por pdo_mysql en su phpinfo()
encontró en este post: PDOException “could not find driver”

Me pregunto por qué CLI funcionó en tales condiciones O_o ¿Quizás algo se ha instalado incorrectamente o se ha sobrescrito? Bueno, ahora, funciona bien!

+0

¿Le importa explicar en lugar de limitar su voto? Todavía no tengo idea de por qué funcionó en CLI y no a través de Apache. Si me perdí algo obvio, solo díganos QUÉ. Publiqué mi solución porque * realmente resolvió mi problema *, y podría ayudar a otros. Si hice algo completamente incorrecto, enlight nosotros por favor. – Balmipour

0

Además, el uso de la respuesta anterior aceptado

setsebool -P httpd_can_network_connect=1 
setsebool -P httpd_can_network_connect_db=1 

que tenía que cambiar también el contexto de seguridad de un archivo que httpd estaba tratando de acceder.

Un script php ejecutado a través de apache intentaba acceder a un archivo de certificado que estaba fuera de la raíz del documento normal de httpd. Cambiar los permisos del archivo para permitir el acceso httpd no fue suficiente para permitir el acceso httpd a ese archivo.Tenía que cambiar el contexto de seguridad, así que antes del cambio:

[admin]$ ls -Z ../../certs/rds-ca-2015-root-us-east-1-BUNDLE.pem 
-rw-r--r--. admin apache unconfined_u:object_r:unlabeled_t:s0 ../../certs/rds-ca-2015-root-us-east-1-BUNDLE.pem 

Cambie el contexto usando:

sudo chcon -v --type=httpd_sys_content_t ../../certs/rds-ca-2015-root-us-east-1-BUNDLE.pem``` 

Para obtener:

[admin]$ ls -Z ../../certs/rds-ca-2015-root-us-east-1-BUNDLE.pem 
-rw-r--r--. admin apache unconfined_u:object_r:httpd_sys_content_t:s0 ../../certs/rds-ca-2015-root-us-east-1-BUNDLE.pem 

Ahora todo es bueno. Un buen recurso para mirar es /var/log/audit/audit.log y preste mucha atención a los errores. En mi caso, el error que apuntaba a la dirección de una resolución era:

type=AVC msg=audit(1509047616.042:4049): avc: denied { read } for pid=17096 comm="httpd" name="rds-ca-2015-root-us-east-1-BUNDLE.pem" dev="xvdb" ino=262146 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:unlabeled_t:s0 tclass=file 
Cuestiones relacionadas