![Apache 无法连接到远程 MySQL,但同一服务器的 mysql 命令行可以](https://linux22.com/image/642789/Apache%20%E6%97%A0%E6%B3%95%E8%BF%9E%E6%8E%A5%E5%88%B0%E8%BF%9C%E7%A8%8B%20MySQL%EF%BC%8C%E4%BD%86%E5%90%8C%E4%B8%80%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%20mysql%20%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%AF%E4%BB%A5.png)
症状:
- 我正在运行 CentOS 6。
- 我可以从命令行连接到远程 MySQL
mysql -h a.b.c.d -u user -p -D db
:。 - 在本地命令行上运行的 Laravel artisan 命令也可以连接:
artisan migrate
。 - 但是相同的 Laravel 代码在通过 Apache 运行时无法连接。
- 错误是:
SQLSTATE[HY000] [2003] Can’t connect to MySQL server on ‘a.b.c.d’ (13)
- MySQL 关于“访问被拒绝”原因的帮助没有帮助。
我做错了什么?(我正在为后人自我回答。)
答案1
查看 httpd 进程上设置了哪些标志
getsebool -a | grep httpd
允许 Apache 通过 SELinux 连接到远程数据库
setsebool httpd_can_network_connect_db 1
使用 -P 选项可使更改永久生效。如果没有此选项,则布尔值将在重启时重置为 0。
setsebool -P httpd_can_network_connect_db 1
答案2
这个问题的关键是(13)
,意思是“权限被拒绝”(通过perror
)。因为我可以从命令行连接,所以权限一定在 Web 应用程序中。由于我知道 Web 应用程序中的凭据与命令行上的凭据相匹配,所以剩下的唯一事情就是 Web 服务器。
通过strace
,我发现 SELinux 阻止了它。要修复:
sudo setsebool -P httpd_can_network_connect=1
这将永久设置 SELinux 以允许 httpd 之外的网络连接。