MySQL官方文檔提煉的23條安全準則,涵蓋網絡傳輸、認證授權、注入防範、權限最小化、審計監控、應急處置六大維度。本文結合生產環境實戰經驗,逐條深度解析並提供可執行的加固清單、驗證腳本與自動化巡檢方案,助力構建合規、可審計、高韌性的數據庫安全體系。
# my.cnf
[mysqld]
require_secure_transport = ON # 拒絕非SSL連接
ssl_ca = /etc/mysql/ssl/ca.pem
ssl_cert = /etc/mysql/ssl/server-cert.pem
ssl_key = /etc/mysql/ssl/server-key.pem
[client]
ssl_ca = /etc/mysql/ssl/ca.pem
ssl_cert = /etc/mysql/ssl/client-cert.pem
ssl_key = /etc/mysql/ssl/client-key.pem
應用層驅動啟用SSL:JDBC useSSL=true&verifyServerCertificate=true、PDO PDO::MYSQL_ATTR_SSL_CA。
bind-address = 192.168.10.5skip-name-resolve (提速+防DNS劫持)nmap -p 3306 、telnet 3306 禁止直接公網/跨VPC連接數據庫,運維通過堡壘機/SSH隧道:
# 本地端口轉發
ssh -L 13306:db_internal_ip:3306 bastion_user@bastion_host
# 本地連接 127.0.0.1:13306 即通達數據庫
-- 重命名 root
RENAME USER 'root'@'localhost' TO 'dbadmin'@'localhost';
-- 禁止遠程登錄
DELETE FROM mysql.user WHERE User='dbadmin' AND Host!='localhost';
FLUSH PRIVILEGES;
-- 強密碼:20+字符,大小寫數字特殊符號,定期輪換 (90天)
-- 8.0 默認 caching_sha2_password,更安全
SHOW VARIABLES LIKE 'default_authentication_plugin';
-- 啟用密碼複雜度驗證
INSTALL COMPONENT 'file://component_validate_password';
SET GLOBAL validate_password.length = 14;
SET GLOBAL validate_password.mixed_case_count = 1;
SET GLOBAL validate_password.number_count = 1;
SET GLOBAL validate_password.special_char_count = 1;
SET GLOBAL validate_password.policy = 'STRONG';
-- 應用賬號模板
CREATE USER 'app_user'@'192.168.10.%' IDENTIFIED BY 'StrongPass123!';
GRANT SELECT, INSERT, UPDATE, DELETE ON biz_db.* TO 'app_user'@'192.168.10.%';
-- 只讀賬號
CREATE USER 'ro_user'@'192.168.10.%' IDENTIFIED BY 'ReadOnlyPass!';
GRANT SELECT ON biz_db.* TO 'ro_user'@'192.168.10.%';
-- 遷移/備份賬號
CREATE USER 'backup_user'@'10.0.0.%' IDENTIFIED BY 'BackupPass!';
GRANT SELECT, LOCK TABLES, SHOW VIEW, PROCESS, REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'backup_user'@'10.0.0.%';
-- 禁用危險權限
REVOKE FILE, PROCESS, SUPER, SHUTDOWN, CREATE USER, RELOAD ON *.* FROM 'app_user'@'%';
ALTER USER 'app_user'@'%' WITH MAX_USER_CONNECTIONS 100;
-- 8.0 Resource Group 進一步限制 CPU/IO (企業版功能)
-- PHP PDO
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ? AND status = ?');
$stmt->execute([$userId, 1]);
-- Java PreparedStatement
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
ps.setLong(1, userId);
-- Go
rows, _ := db.Query("SELECT * FROM users WHERE id = ?", userId)
useradd -r -s /sbin/nologin mysql
chown -R mysql:mysql /var/lib/mysql /var/log/mysql /app/mysql
chmod 750 /var/lib/mysql /var/log/mysql
chmod 640 /etc/my.cnf
[mysqld]
local-infile = 0 # 禁用 LOAD DATA LOCAL INFILE
skip-symbolic-links = ON # 禁用符號鏈接
skip-show-database # 普通用戶不可 SHOW DATABASES
audit_log 插件 (JSON格式、過濾規則、異步寫入)MariaDB Audit Plugin、McAfee MySQL Audit、解析 General Log/Slow Log
# 定期抽檢明文傳輸
tcpdump -i eth0 -nn -s 0 -A port 3306 | strings
# 生產環境建議部署網絡層 IDS/IPS (Suricata/Zeek) 持續監控
# 1. 停止服務
systemctl stop mysqld
# 2. 跳過權限表啟動
systemctl set-environment MYSQLD_OPTS="--skip-grant-tables --skip-networking"
systemctl start mysqld
# 3. 本地無密碼登錄修復
mysql -u root
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPass123!';
-- 或修復權限表
-- UPDATE mysql.user SET authentication_string='' WHERE User='root'; (舊版本)
# 4. 恢復正常
systemctl stop mysqld
systemctl unset-environment MYSQLD_OPTS
systemctl start mysqld
--skip-networking 禁止網絡連接
#!/bin/bash
# mysql_security_audit.sh
echo "=== MySQL Security Audit $(date) ==="
# 1. 匿名用戶
mysql -uroot -p${PWD} -e "SELECT User,Host FROM mysql.user WHERE User='';" | grep -v "User" && echo "❌ 存在匿名用戶" || echo "✅ 無匿名用戶"
# 2. Root 遠程
mysql -uroot -p${PWD} -e "SELECT User,Host FROM mysql.user WHERE User='root' AND Host!='localhost';" | grep -v "User" && echo "❌ Root允許遠程" || echo "✅ Root僅本地"
# 3. 空密碼/弱密碼 (需插件支持)
mysql -uroot -p${PWD} -e "SELECT User,Host FROM mysql.user WHERE authentication_string='' OR LENGTH(authentication_string)<20;" | grep -v "User" && echo "⚠️ 疑似弱密碼" || echo "✅ 密碼長度達標"
# 4. Test 庫
mysql -uroot -p${PWD} -e "SHOW DATABASES LIKE 'test';" | grep test && echo "❌ Test庫殘留" || echo "✅ 無Test庫"
# 5. 危險權限
mysql -uroot -p${PWD} -e "SELECT User,Host FROM mysql.user WHERE File_priv='Y' OR Process_priv='Y' OR Super_priv='Y' OR Shutdown_priv='Y';" | grep -v "User" && echo "⚠️ 非DBA持有危險權限" || echo "✅ 危險權限收斂"
# 6. SSL 強制
mysql -uroot -p${PWD} -e "SHOW VARIABLES LIKE 'require_secure_transport';" | grep ON && echo "✅ SSL強制" || echo "❌ 未強制SSL"
# 7. 審計日誌
ls -la /var/log/mysql/audit.log 2>/dev/null && echo "✅ 審計日誌存在" || echo "❌ 缺少審計日誌"
# 8. 防火牆規則
firewall-cmd --list-all | grep -E '3306|mysql' && echo "✅ 防火牆放行規則存在" || echo "⚠️ 檢查防火牆"
echo "=== Audit Complete ==="
| 合規標準 | 對應加固條目 |
|---|---|
| 等保 2.0/3.0 | 身份鑑別、訪問控制、審計、入侵防範、惡意代碼防範 |
| PCI DSS | 需求2/3/7/8/10/12 (密碼策略、加密傳輸、最小權限、審計日誌) |
| GDPR | 數據保護設計、訪問控制、審計追蹤、數據最小化 |
| ISO 27001 | A.9 訪問控制、A.12 運營安全、A.13 通信安全、A.16 事件管理 |