首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 遠端連線失敗完整排查:Host not allowed、權限設定與防火牆

     編輯:MySQL 綜合教學

前言

「Host 'x.x.x.x' is not allowed to connect to this MySQL server」是遠端連線最經典的錯誤。本文系統梳理 MySQL 遠端連線失敗的三大核心原因:使用者帳號主機限制、權限授予、網路/防火牆,並提供分步驟排查與解決方案。

一、核心機制:MySQL 使用者 = '用戶名'@'主機'

MySQL 使用者身份由 用戶名 + 主機 組成,兩者必須完全匹配:

root@localhost      -- 僅允許本機連線
root@192.168.1.%    -- 允許 192.168.1.x 網段
root@%              -- 允許任意主機 (生產慎用)
root@'specific.host' -- 允許特定主機名

二、錯誤代碼對應原因

三、解決方案一:建立遠端存取帳號 (推薦)

1. 登入 MySQL 建立帳號並授權

-- 登入本機 root
mysql -u root -p

-- 建立帳號並授權特定資料庫
CREATE USER 'app_user'@'192.168.1.100' IDENTIFIED BY 'StrongPass123!';
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app_user'@'192.168.1.100';

-- 或授權所有權限 (慎用)
GRANT ALL PRIVILEGES ON mydb.* TO 'app_user'@'192.168.1.100';

-- 生效權限
FLUSH PRIVILEGES;

2. 通配符主機 (開發/測試環境)

CREATE USER 'dev_user'@'%' IDENTIFIED BY 'DevPass123!';
GRANT ALL PRIVILEGES ON dev_db.* TO 'dev_user'@'%';
FLUSH PRIVILEGES;

⚠️ 生產環境禁止使用 %_,應限定具體 IP/網段。

3. 修改現有帳號主機

-- 查看現有帳號
SELECT User, Host FROM mysql.user;

-- 方法 1:更新 Host 欄位 (需重啟或 FLUSH PRIVILEGES)
UPDATE mysql.user SET Host = '%' WHERE User = 'app_user' AND Host = 'localhost';
FLUSH PRIVILEGES;

-- 方法 2:重建帳號 (更乾淨)
DROP USER 'app_user'@'localhost';
CREATE USER 'app_user'@'%' IDENTIFIED BY 'password';
GRANT ...; FLUSH PRIVILEGES;

四、解決方案二:直接操作 mysql 資料庫表 (舊版/緊急)

USE mysql;

-- 插入 user 表
INSERT INTO user (Host, User, Password, Select_priv, Insert_priv, Update_priv, Delete_priv, ...)
VALUES ('192.168.1.100', 'app_user', PASSWORD('StrongPass123!'), 'Y', 'Y', 'Y', 'Y', ...);

-- 插入 db 表 (資料庫級權限)
INSERT INTO db (Host, Db, User, Select_priv, Insert_priv, ...)
VALUES ('192.168.1.100', 'mydb', 'app_user', 'Y', 'Y', ...);

FLUSH PRIVILEGES;

⚠️ MySQL 5.7+ Password 欄位改為 authentication_string,建議用 CREATE USER / GRANT 方式。

五、解決方案三:phpMyAdmin 遠端連線設定

/* config.inc.php */
$cfg['Servers'][$i]['host'] = '192.168.1.50';  -- 遠端 MySQL IP
$cfg['Servers'][$i]['user'] = 'remote_user';
$cfg['Servers'][$i]['password'] = 'password';
$cfg['Servers'][$i]['port'] = 3306;
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['auth_type'] = 'cookie';

遠端 MySQL 必須已授權 remote_user@phpMyAdmin_Server_IP。

六、網路層排查清單

  1. MySQL 監聽地址:
    -- my.cnf
    bind-address = 0.0.0.0  -- 監聽所有介面
    # bind-address = 192.168.1.50  -- 僅特定 IP
    -- 重啟生效
    systemctl restart mysqld
  2. 防火牆開放 3306:
    # firewalld
    firewall-cmd --permanent --add-port=3306/tcp
    firewall-cmd --reload
    
    # iptables
    iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
    
    # 雲端安全組 (AWS SG / Azure NSG / GCP Firewall) 亦需開放
  3. SELinux / AppArmor:
    # SELinux
    setsebool -P mysql_connect_any 1
    # 或允許特定端口
    semanage port -a -t mysqld_port_t -p tcp 3306
  4. 測試連通性:
    telnet 192.168.1.50 3306
    nc -zv 192.168.1.50 3306
    mysql -u app_user -h 192.168.1.50 -p

七、常見坑與避雷指南

錯誤代碼訊息核心原因
1130Host 'x.x.x.x' is not allowed to connect使用者主機不匹配、無對應帳號
1045Access denied for user 'x'@'x' (using password: YES/NO)密碼錯誤、或帳號存在但主機不匹配
1044Access denied for user 'x'@'x' to database 'db'帳號存在但無資料庫權限
1129Host 'x.x.x.x' is blocked because of many connection errors連線錯誤過多被封鎖,需 FLUSH HOSTS

八、驗證腳本

#!/bin/bash
# check_mysql_remote.sh
HOST=$1
USER=$2
PASS=$3
DB=$4

mysql -h "$HOST" -u "$USER" -p"$PASS" -e "SELECT USER(), CURRENT_USER(), VERSION();" "$DB"
if [ $? -eq 0 ]; then
    echo "✅ 連線成功"
else
    echo "❌ 連線失敗"
    # 診斷
    nc -zv "$HOST" 3306
    mysql -h "$HOST" -u "$USER" -p"$PASS" -e "SELECT 1" 2>&1 | head -5
fi

結語

遠端連線失敗 90% 是「帳號主機不匹配」+「防火牆未開放」。建立標準化授權流程:建立特定 IP 帳號 → 授權最小權限 → 開放防火牆 → 驗證連線 → 記錄變更,即可避免反覆踩坑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
坑點現象解決
密碼含特殊字元Shell 解析錯誤、登入失敗單引號包裹、或用配置檔 --defaults-file
skip-name-resolveDNS 反解慢導致連線超時my.cnf: skip-name-resolve 禁用 DNS 反查
max_connect_errors錯誤過多被封鎖 (1129)FLUSH HOSTS、調大 max_connect_errors=100000
SSL 強制Require SSL 但客戶端未配置帳號 REQUIRE SSL 或客戶端啟用 SSL
plugin 認證8.0+ 預設 caching_sha2_password客戶端支援、或改用 mysql_native_password