三台伺服器:A、B、C。C 為 MySQL 資料庫伺服器,已開放遠端連線。
B 可正常用 PHP 連線 C。
A 同樣代碼、同樣參數,連線失敗(通常為 Can't connect to MySQL server 或 Permission denied)。
排除項目:
php.ini 無特殊限制對比 A、B 兩台伺服器 /etc/selinux/config,發現 A 為 Enforcing,B 為 Disabled 或 Permissive。
SELinux 預設禁止 httpd 進程發起外部網路連線(httpd_can_network_connect = off)。
# 1. 編輯配置
vim /etc/selinux/config
# 修改
SELINUX=disabled
# 2. 重啟生效
reboot
# 或臨時生效(無需重啟)
setenforce 0
# 檢查當前布林值
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
-P 參數寫入持久化策略,重啟後依然生效。
# 允許 httpd 連線任意埠
setsebool -P httpd_can_network_connect on
# 或針對特定埠(如 3306)透過 semanage
yum install policycoreutils-python-utils
semanage port -a -t mysqld_port_t -p tcp 3306
# 確認
semanage port -l | grep mysqld_port_t
<?php
$mysqli = new mysqli('db-server-c', 'user', 'pass', 'dbname', 3306);
if ($mysqli->connect_errno) {
die("連線失敗: " . $mysqli->connect_error);
}
echo "連線成功!Server version: " . $mysqli->server_info;
$mysqli->close();
在 A 伺服器執行,應顯示「連線成功!」
php-mysqlnd 已安裝(B 正常即證明)。0.0.0.0 或具體 IP(B 正常即證明)。iptables/nftables/firewalld 已放行(B 正常即證明)。當「同樣代碼、同樣網路、同樣資料庫」只在特定伺服器連線失敗時,優先檢查 SELinux。使用 setsebool -P httpd_can_network_connect on 精準放行,比完全關閉 SELinux 更安全、更專業。