У меня очень простой тестовый скрипт:
<?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 выполняет его?
Если это дистрибутив 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
.
У меня была такая же проблема для PHP ftp ftp_connect, и мне пришлось установить
setsebool -P httpd_can_network_connect=1
Это сбивает с толку, потому что другие вещи, такие как fil_get_contents
и curl, работают через PHP и apache просто отлично, прежде чем устанавливать это.
Кроме того, используя принятый выше ответ
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
Такая же проблема, но другая причина здесь
Мое решение было просто простой apt-get install php-mysql
away
Обязательно проверьте pdo_mysql в своей phpinfo ()
Нашел это на этом посту: PDOException «не смог найти драйвер»
Интересно, почему CLI работал в таких условиях O_o Возможно, что-то неправильно установлено или переопределено? Ну, теперь все работает отлично!