PDO соединение работает из командной строки, а не через Apache? - PullRequest
8 голосов
/ 15 ноября 2011

У меня очень простой тестовый скрипт:

<?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";

}

?>

Когда я запускаю этот скрипт из командной строки, он отлично работает:

$ 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

Но когда я получаю доступ к тому же самому сценарию через мой веб-браузер, он говорит:

Could not connect to database, rawr. :-(

Я попытался var_dump на ошибке, и сообщение: «SQLSTATE [HY000] [2003] Не удается подключиться к серверу MySQL на« db.example.edu »(13)».

Это озадачивает. Это точно такой же сценарий на том же сервере - почему он работает, когда я выполняю его из командной строки, но не работает, когда Apache выполняет его?

Ответы [ 4 ]

30 голосов
/ 15 ноября 2011

Если это производный от Red Hat дистрибутив (RHEL, CentOS, Fedora, ScientificLinux), на котором запущен SELinux (или любой не производный от Red Hat, использующий SELinux), по умолчанию на момент написания этой статьи параметр политики по умолчанию запрещает Apache делать внешние подключения к другим серверам или базам данных. В качестве пользователя root вы должны включить следующие два логических значения SELinux. Используйте параметр -P, чтобы сохранить изменения после перезагрузки.

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

Обратите внимание, что httpd_can_network_connect может быть необязательным. Попробуйте сначала включить только httpd_can_network_connect_db.

0 голосов
/ 26 октября 2017

Кроме того, используя вышеуказанный принятый ответ

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

Мне также пришлось изменить контекст безопасности файла, к которому httpd пытался получить доступ.

Сценарий php, запущенный через apache, пытался получить доступ к файлу сертификата, который находился за пределами обычного корня документа httpd. Изменение разрешений на доступ к файлу для разрешения доступа httpd было недостаточно для разрешения доступа httpd к этому файлу. Мне также пришлось перейти в контекст безопасности, поэтому перед изменением:

[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

Изменить контекст, используя:

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

чтобы получить:

[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

Теперь все хорошо. Хороший ресурс, на который стоит обратить внимание, это /var/log/audit/audit.log и обратите пристальное внимание на ошибки. В моем случае ошибка, указывающая на направление разрешения, была:

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
0 голосов
/ 31 октября 2016

Та же проблема, но другая причина здесь
Мое решение было простым apt-get install php-mysql прочь

Обязательно проверьте pdo_mysql в вашем phpinfo ()
Нашел по этому посту: PDOException «не удалось найти драйвер»

Интересно, почему CLI работал в таких условиях? О_о Возможно, что-то установлено неправильно или переопределено? Ну, теперь все работает отлично!

0 голосов
/ 26 февраля 2015

У меня была такая же проблема для PHP ftp ftp_connect, и мне пришлось установить

setsebool -P httpd_can_network_connect=1

Это сбивает с толку, потому что другие вещи, такие как fil_get_contents и curl, работают нормально через PHP и apache перед установкой этого.

...