同一代碼、同一 MySQL 賬號,機器 B 能連、機器 A 卻報 SQLSTATE[HY000] [2003] Can't connect to MySQL server。排除代碼、授權、防火牆、php.ini 後,真兇往往是 SELinux 策略阻擋 HTTPD 進程發起網絡連接。本文記錄排查全過程與一鍵修復方案。
telnet C_IP 3306 通,mysql -h C_IP -u user -p 也能連對比 /etc/selinux/config 發現:
SELINUX=enforcingSELINUX=disabled 或 permissiveSELinux 在 enforcing 模式下,默認策略 禁止 httpd_t 域進程主動發起 TCP 連接(httpd_can_network_connect = off),導致 PHP 連接遠程 MySQL 被內核攔截。
# 1. 編輯配置
vim /etc/selinux/config
# 修改
SELINUX=disabled
# 2. 重啟生效(或臨時生效:setenforce 0)
reboot
# 檢查當前策略
getsebool httpd_can_network_connect
# 輸出: httpd_can_network_connect --> off
# 永久開放(重啟不失效)
setsebool -P httpd_can_network_connect on
# 驗證
getsebool httpd_can_network_connect
# 輸出: httpd_can_network_connect --> on
此策略專門允許 HTTPD 進程發起網絡連接(含 MySQL、PostgreSQL、HTTP API 等),不降低整體安全等級。
<?php
$pdo = new PDO("mysql:host=REMOTE_IP;dbname=test", "user", "pass");
echo "連接成功!";
?>
刷新頁面,不再報 2003 錯誤,即修復成功。
/etc/selinux/config → 定位根因經驗之談:CentOS/RHEL 系列默認開啟 SELinux,遷移部署時必須檢查。建議採用「方案二」精準放行,兼顧安全與功能。