# 1. 檢查用戶 host 字段
SELECT user, host FROM mysql.user WHERE user='root';
# 2. 檢查監聽地址
SHOW VARIABLES LIKE 'bind_address';
# 若為 127.0.0.1 → 僅本地可連,需改為 0.0.0.0 或具體內網 IP
# 3. 檢查防火牆
iptables -L -n | grep 3306
# 或 firewall-cmd --list-ports
mysql -uroot -p -e "USE mysql; UPDATE user SET host='%' WHERE user='root' AND host='localhost'; FLUSH PRIVILEGES;"
# 風險:root 從任何 IP 可連,極不安全,僅測試環境可用
| 場景 | SQL |
|---|---|
| 指定用戶、指定 IP、全庫全表、可授權 | GRANT ALL PRIVILEGES ON *.* TO 'app_user'@'192.168.1.100' IDENTIFIED BY 'StrongPass#2024' WITH GRANT OPTION; |
| 指定用戶、指定 IP、指定庫 | GRANT ALL PRIVILEGES ON biz_db.* TO 'app_user'@'192.168.1.100' IDENTIFIED BY 'StrongPass#2024'; |
| 指定用戶、任意 IP(%)、指定庫 | GRANT SELECT,INSERT,UPDATE,DELETE ON biz_db.* TO 'app_user'@'%' IDENTIFIED BY 'StrongPass#2024'; |
| 只讀賬號、內網段 | GRANT SELECT ON *.* TO 'readonly'@'10.0.%.%' IDENTIFIED BY 'ReadOnly#2024'; |
必須執行:FLUSH PRIVILEGES; 使權限立即生效(8.0+ 可省略,但保留習慣無害)。
[mysqld]
# 監聽所有網卡(生產建議綁定具體內網 IP,如 10.0.1.50)
bind-address = 0.0.0.0
# 或僅本地(拒絕遠程)
# bind-address = 127.0.0.1
# 禁用域名解析(加快連接、避免 DNS 劫持)
skip-name-resolve
# SSL 強制(可選)
# require_secure_transport=ON
修改後 systemctl restart mysqld 生效。
# iptables(永久生效需 save/service iptables save)
iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j DROP
# firewalld(CentOS 7+)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="3306" accept'
firewall-cmd --reload
# ufw(Ubuntu)
ufw allow from 192.168.1.0/24 to any port 3306
# 客戶端測試
mysql -h 192.168.1.50 -u app_user -p -e "SELECT USER(), CURRENT_USER();"
# 抓包確認 SSL
tcpdump -i eth0 -nn port 3306 -w mysql.pcap
# Wireshark 打開檢查 TLS Handshake
| 錯誤碼/信息 | 原因 | 解決 |
|---|---|---|
| 1130 Host 'x.x.x.x' is not allowed to connect | user 表無匹配 host | GRANT 授權對應 IP 或 % |
| 2003 Can't connect to MySQL server | 網絡不通/bind-address/防火牆 | telnet ip 3306、檢查 bind-address、防火牆 |
| 1045 Access denied for user | 密碼錯誤/插件不匹配 | 確認密碼、authentication_plugin(caching_sha2_password vs mysql_native_password) |
| SSL connection error | 客戶端不支持服務端要求的 TLS 版本 | 升級驅動/連接器、或服務端降級 TLS 版本 |
require_secure_transport=ONSELECT user, host FROM mysql.user WHERE host != 'localhost'; 清理無用賬號**授權三部曲**:GRANT 精準賦權 → bind-address 綁定監聽 → 防火牆/安全組 網絡層收口。**永遠不要為了方便把 root 改成 %**,哪怕是測試環境也要養成最小權限習慣。MySQL 8.0+ 推薦使用 CREATE USER ... REQUIRE SSL + GRANT 分離語法,更清晰安全。