錯誤全文:Host 'xxx.xxx.xxx.xxx' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'。本質是 MySQL 內建**連線錯誤計數器防暴力破解機制**觸發。本文解析原理、提供臨時/永久解決方案、監控建議與安全最佳實踐。
max_user_connections 限制等。**成功連線會重置計數器為 0**。max_connect_errors 閾值 (預設 **100**),該 Host 被加入**阻塞列表**,後續連線直接拒絕,不再驗證密碼。FLUSH HOSTS / mysqladmin flush-hosts。mysql> SHOW VARIABLES LIKE 'max_connect_errors';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| max_connect_errors | 100 | -- 預設值,極低!
+--------------------+-------+
mysql> SHOW STATUS LIKE 'Aborted_connects';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| Aborted_connects | 1245 | -- 歷史累積中斷連線數
+------------------+-------+
預設 100 極易誤觸發:自動化腳本重試、應用啟動期密碼輪換、網路抖動、掃描器探測,幾分鐘即達標。
-- 1. 立即解封被阻塞 Host (需 RELOAD/ADMIN 權限)
FLUSH HOSTS;
-- 或命令列
mysqladmin flush-hosts -u root -p
-- 2. 動態調大閾值 (需 SUPER 權限)
SET GLOBAL max_connect_errors = 1000000; -- 100萬,足夠緩衝
-- 3. 驗證
SHOW VARIABLES LIKE 'max_connect_errors';
注意:FLUSH HOSTS 會清空**所有** Host 錯誤計數器,不針對單一 IP。
# 編輯 my.cnf (Linux: /etc/my.cnf 或 /etc/mysql/my.cnf; Windows: my.ini)
vim /etc/my.cnf
[mysqld]
# 設定足夠大的閾值,防止誤封正常客戶端
max_connect_errors = 1000000
# 重啟生效
systemctl restart mysqld
調大閾值 ≠ 關閉防護。必須配合以下措施:
Aborted_connects 增長率、Host_blocked 事件 (需啟用審計日誌/Error Log 解析)。bind-address 僅綁定內網 IP。| 可能原因 | 排查方法 | 解決 |
|---|---|---|
| 應用配置舊密碼 | 對比應用配置中心與數據庫實際密碼 | 同步更新配置、滾動重啟應用 |
| 連線池耗盡/配置錯誤 | 檢查應用日志:Connection refused, Timeout, Pool exhausted | 調整連線池大小、檢查洩漏 |
| 自動化腳本/備份工具密碼錯 | 檢查 cron、備份腳本、ETL 任務日志 | 修正腳本憑證 |
| 網路不穩/防火牆間歇性阻斷 | ping/telnet 持續測試、抓包分析 RST/FIN | 網路層面解決、調整 keepalive |
| 惡意掃描/暴力破解 | Error log 大量 "Access denied for user 'root'@'x.x.x.x'" | 防火牆封禁、fail2ban、修改端口、禁用 root 遠程 |
| MySQL 服務重啟導致應用斷線重連風暴 | 對應時間點應用報錯峰值 | 應用優雅重連、MySQL 維護窗口通知 |
Host is blocked 是 MySQL 內建的**輕量級防暴力破解**。**臨時解封 FLUSH HOSTS + 永久調大 max_connect_errors=1000000** 是標準操作。但**核心在於消除根因**:應用重試策略、密碼管理、網路穩定、前置防火牆。將閾值調大僅為「購買時間」排查根因,而非「一勞永逸」忽視安全。