現象:mysql -u root -p 輸入正確密碼卻報錯:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
但有時又能登入成功。經排查,**數據庫內存在匿名用戶 (user='')** 是核心原因。MySQL 認證機制按 user@host 排序匹配,匿名用戶優先級高於具體用戶,導致正確密碼被誤判。
mysql.user 表按 Host, User 排序。典型數據:
+------+-----------------------+----------+
| User | Host | Password |
+------+-----------------------+----------+
| root | % | *hash |
| root | localhost | *hash |
| root | 127.0.0.1 | *hash |
| | localhost | | ← 匿名用戶,密碼為空
| | localhost.localdomain | | ← 匿名用戶
+------+-----------------------+----------+
連接時 MySQL 依次嘗試匹配:
root@localhost (密碼正確 → 應通過)''@localhost (匿名用戶,密碼為空 → 若客戶端發送密碼,認證失敗)由於匿名用戶在排序中可能優先或干擾匹配邏輯,導致間歇性「密碼正確卻拒絕訪問」。
systemctl stop mysqld
# 或 service mysql stop
mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
--skip-grant-tables:禁用權限檢查,無密碼可登入--skip-networking:僅允許本地 Socket 連接,安全隔離&:後台運行mysql -u root mysql
mysql> DELETE FROM user WHERE User = '';
Query OK, 2 rows affected (0.01 sec)
mysql> FLUSH PRIVILEGES;
mysql> QUIT
# 先殺掉 skip-grant-tables 進程
pkill -f "mysqld_safe.*skip-grant-tables"
# 或找到 PID kill -9
systemctl start mysqld
# 或 service mysql start
mysql -u root -p
Enter password: <輸入正確密碼>
Welcome to the MySQL monitor...
mysql> SELECT User, Host FROM mysql.user WHERE User = '';
Empty set (0.00 sec) -- 匿名用戶已清除
mysql_secure_installation:自動移除匿名用戶、禁止 root 遠程、移除 test 庫、重載權限mysql.user:SELECT User, Host, authentication_string FROM mysql.user WHERE User = '' OR authentication_string = '' OR authentication_string IS NULL;skip-grant-tables 啟動:僅緊急恢復密碼時短時使用,立即重啟恢復正常模式CREATE USER 'app'@'10.0.%.%' ... 縮小攻擊面| 原因 | 現象 | 解決 |
|---|---|---|
| 密碼確實錯誤 | 持續報 1045 | 跳過權限表重置密碼:ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpass'; |
| Host 不匹配 | ERROR 1130 (HY000) | 創建匹配宿主的用戶或修改現有用戶 Host |
| 密碼插件不匹配 | 8.0 默認 caching_sha2_password,舊客端不支持 | ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'pass'; |
| 連接數耗盡 | ERROR 1040 (HY000) / 1045 | 增大 max_connections、排查泄漏、殺死閒置連接 |
| SSL 強制但客戶端不支持 | ERROR 2026 (HY000) SSL connection error | 客戶端啟用 SSL 或服務端放寬 REQUIRE SSL |
ERROR 1045 間歇發生 + 密碼確認正確 → 90% 是匿名用戶干擾。標準修復:「停服務 → skip-grant-tables → 刪除 User='' → 重啟驗證」。配合 mysql_secure_installation 常態化執行,從源頭杜絕匿名用戶隱患。