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

MySQL 授權陷阱:localhost vs % 區別與 OpenStack 實戰排查

     編輯:MySQL 綜合教學

MySQL 授權陷阱:localhost vs % 區別與 OpenStack 實戰排查

在部署 OpenStack Keystone 服務時,雖對 'keystone'@'%' 授權,卻持續報 Access denied for user 'keystone'@'controller'。根因在於 **MySQL 授權主機匹配機制與系統 hostname 解析的交互差異**。

核心知識點

  1. % 不包含 localhost: MySQL 官方文檔明確說明,通配符 % 匹配「任意非本地主機」。本地連接(Unix Socket 或 127.0.0.1)屬於 localhost 或 127.0.0.1,需單獨授權。
  2. 用戶身份三元組: MySQL 用戶由 'user'@'host' 唯一標識。'keystone'@'%' 和 'keystone'@'localhost' 是兩個完全不同的賬號,權限獨立。
  3. 主機名解析影響: 客戶端連接時,MySQL 會對客戶端 IP 做反向 DNS 解析(可用 skip_name_resolve=ON 關閉)。若 /etc/hosts 將 controller 解析到 127.0.0.1,則連接被識別為 localhost。

故障現場還原

-- 已執行授權
GRANT ALL ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'PASS';
GRANT ALL ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'PASS';

-- /etc/hosts 內容
127.0.0.1   localhost
192.168.38.100  controller

-- keystone.conf 連接串
connection = mysql://keystone:PASS@controller/keystone

-- 報錯
Access denied for user 'keystone'@'controller' (using password: YES)

根因分析

  1. Keystone 進程解析 controller → 192.168.38.100(本機 IP)。
  2. MySQL 服務端收到連接,來源 IP 為 192.168.38.100。
  3. MySQL 執行反向 DNS 解析 192.168.38.100 → controller(若啟用 DNS 或 /etc/hosts 映射)。
  4. 匹配用戶 'keystone'@'controller',**無此用戶**,授權失敗。

關鍵點: 即使 /etc/hosts 有 127.0.0.1 localhost controller,MySQL 看到的是 TCP 連接的來源 IP(192.168.38.100),而非 127.0.0.1,因此不走 localhost 授權。

解決方案對比

方案操作優點缺點
方案 A:授權實際主機名(推薦)GRANT ALL ON keystone.* TO 'keystone'@'controller' IDENTIFIED BY 'PASS';精確匹配,符合最小權限需預知所有客戶端主機名/IP
方案 B:授權具體 IPGRANT ALL ON keystone.* TO 'keystone'@'192.168.38.100' IDENTIFIED BY 'PASS';不依賴 DNS/hosts 解析IP 變更需重新授權
方案 C:修改連接串用 127.0.0.1connection = mysql://keystone:PASS@127.0.0.1/keystone走 localhost 授權,繞過解析僅適用同機部署,不利於高可用漂移
方案 D:關閉主機名解析my.cnf: skip_name_resolve=ON直接用 IP 匹配,性能略增授權必須用 IP,不可用主機名

最佳實踐建議

  1. 生產環境啟用 skip_name_resolve=ON,避免 DNS 故障導致連接超時,授權統一使用 IP 或 %。
  2. 服務之間通訊優先用 VIP/域名,在 MySQL 授權該 VIP/IP,而非依賴 /etc/hosts 別名。
  3. 授權腳本化: 部署腳本中批量授權 localhost、127.0.0.1、VIP、%(內網),覆蓋所有連接場景。
  4. 驗證命令: SELECT user, host FROM mysql.user WHERE user='keystone'; 確認授權覆蓋面。

總結

MySQL 授權看似簡單,實則涉及網絡層(IP/主機名)、傳輸層、應用層連接串的多層交互。**「授權 % 以為萬事大吉」是危險的誤區**。理解 localhost、127.0.0.1、具體IP/主機名、% 的匹配優先級與差異,結合 skip_name_resolve 策略,才能構建穩健的數據庫訪問控制體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved