6.3.7 常见安全风险与加固检查清单
本节汇总 MySQL 运维中最常见的安全风险与对应的加固检查清单,便于巡检与基线验收。提供可执行命令、配置示例、排错思路与练习,便于直接落地。
原理与风险面示意图#
常见安全风险#
- 弱口令与默认账户:root/空密码、通用口令未禁用或未改。
- 权限过大:应用账号被授予全库/全局权限(如
ALL PRIVILEGES、GRANT OPTION)。 - 暴露对公网:3306 直接开放或安全组过宽。
- 未限制访问来源:
%泛匹配主机授权。 - 敏感数据未加密:明文存储、未启用 TLS 传输。
- 审计缺失:无登录、权限变更、数据访问的审计日志。
- 权限变更无审批:授权/回收无流程与记录。
- 高危功能未禁用:
LOCAL INFILE、FILE权限、UDF 任意执行。 - 备份泄露:备份文件未加密、存放路径不安全。
- 系统层面风险:数据库运行账户权限过高、文件权限过宽。
加固检查清单#
账户与权限#
- [ ] 禁用或重命名默认高危账户(如
test、匿名用户)。 - [ ] root 仅本地/跳板机可访问,禁止远程
%授权。 - [ ] 所有账号使用强口令策略并定期轮换。
- [ ] 应用账号最小权限,仅授予所需库表和操作。
- [ ] 禁止普通账号使用
GRANT OPTION。 - [ ] 定期清理长期未使用账号与权限。
访问控制与网络#
- [ ] 仅内网访问,关闭公网 3306;安全组/防火墙最小开放。
- [ ] 明确允许的客户端 IP/网段,不使用
%。 - [ ] 配置
skip_name_resolve避免 DNS 风险并使用 IP 授权。 - [ ] 禁止非必要的远程管理端口与账户。
认证与传输安全#
- [ ] 使用安全认证插件(如 caching_sha2_password)。
- [ ] 启用 TLS 加密连接,客户端强制使用 SSL。
- [ ] 禁用或限制
LOCAL INFILE。 - [ ] 禁止
FILE权限或仅授予可信运维账号。
数据与审计#
- [ ] 关键表字段加密(应用层或 TDE/加密函数)。
- [ ] 启用审计日志,记录登录、权限变更、DDL/DCL。
- [ ] 审计日志单独存储并限制访问权限。
- [ ] 定期审计权限与访问日志。
系统与文件权限#
- [ ] MySQL 运行账户为最小权限用户,禁止 root 启动。
- [ ] 数据目录、配置文件权限最小化(如 750/640)。
- [ ] 禁止其他用户读取配置文件中的明文密码。
- [ ] 备份文件加密、访问控制、定期清理。
变更与应急#
- [ ] 权限变更必须审批并留痕。
- [ ] 发现异常登录/权限变更可快速冻结账号。
- [ ] 具备安全事件应急预案与演练记录。
关键命令与示例(可执行)#
1) 账户清理与权限核查#
目标:找出空密码、% 授权、过大权限账号。
-- 1. 查找空密码(MySQL 8+)
SELECT user, host FROM mysql.user WHERE authentication_string = '';
-- 2. 查找通配符主机授权
SELECT user, host FROM mysql.user WHERE host = '%';
-- 3. 查找高权限账号
SELECT user, host, Super_priv, Grant_priv, File_priv
FROM mysql.user
WHERE Super_priv='Y' OR Grant_priv='Y' OR File_priv='Y';
-- 4. 查看账号实际权限
SHOW GRANTS FOR 'app'@'10.10.10.%';
预期效果:输出的账号清单用于整改,避免不合规授权。
整改示例:
-- 删除匿名用户/测试库
DELETE FROM mysql.user WHERE user='';
DROP DATABASE IF EXISTS test;
FLUSH PRIVILEGES;
-- 移除通配符授权
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'app'@'%';
DROP USER 'app'@'%';
-- 仅允许指定网段
CREATE USER 'app'@'10.10.10.%' IDENTIFIED BY 'StrongP@ssw0rd!';
GRANT SELECT,INSERT,UPDATE,DELETE ON appdb.* TO 'app'@'10.10.10.%';
2) 强口令与认证插件#
配置示例(/etc/my.cnf):
[mysqld]
default_authentication_plugin=caching_sha2_password
validate_password.policy=STRONG
validate_password.length=12
validate_password.mixed_case_count=1
validate_password.number_count=1
validate_password.special_char_count=1
生效方式:
# 重启服务使配置生效
systemctl restart mysqld
验证:
SHOW VARIABLES LIKE 'default_authentication_plugin';
SHOW VARIABLES LIKE 'validate_password%';
3) TLS 加密连接#
服务端证书部署示例:
# 生成 CA 与服务端证书(示例路径)
mkdir -p /etc/mysql/ssl && cd /etc/mysql/ssl
openssl genrsa -out ca.key 2048
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/CN=MySQL-CA"
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/CN=mysql-server"
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650
chmod 600 server.key
MySQL 配置:
[mysqld]
ssl-ca=/etc/mysql/ssl/ca.crt
ssl-cert=/etc/mysql/ssl/server.crt
ssl-key=/etc/mysql/ssl/server.key
require_secure_transport=ON
客户端连接测试:
mysql -u app -h 10.10.10.10 -p --ssl-mode=REQUIRED
预期效果:非 TLS 连接将被拒绝。
4) 禁用高危功能#
[mysqld]
local_infile=0
-- 校验参数
SHOW VARIABLES LIKE 'local_infile';
-- 收回 FILE 权限
REVOKE FILE ON *.* FROM 'app'@'10.10.10.%';
5) 审计与日志#
建议插件:MySQL Enterprise Audit 或 MariaDB Audit Plugin(社区替代需评估)。
示例(MariaDB audit plugin):
[mysqld]
plugin_load_add=server_audit
server_audit_logging=ON
server_audit_events=CONNECT,QUERY,DDL
server_audit_file_path=/var/log/mysql/audit.log
权限保护:
chown mysql:mysql /var/log/mysql/audit.log
chmod 640 /var/log/mysql/audit.log
6) 系统与文件权限#
# 确保 mysqld 以 mysql 用户运行
ps -ef | grep mysqld
# 数据目录权限(示例)
chown -R mysql:mysql /var/lib/mysql
chmod 750 /var/lib/mysql
# 配置文件权限
chmod 640 /etc/my.cnf
快速巡检建议(带命令)#
# 1. 端口暴露
ss -lntp | grep 3306
# 2. 防火墙规则(示例)
firewall-cmd --list-all | grep 3306
# 3. 可疑授权
mysql -e "SELECT user,host FROM mysql.user WHERE host='%'"
# 4. TLS 状态
mysql -e "SHOW STATUS LIKE 'Ssl_cipher'"
常见排错#
- 启用 TLS 后客户端连不上
- 现象:ERROR 2026 (HY000): SSL connection error
- 排查:确认require_secure_transport=ON,证书路径与权限正确;客户端使用--ssl-mode=REQUIRED。 - 启用强口令策略导致创建用户失败
- 现象:ERROR 1819 (HY000): Your password does not satisfy...
- 处理:调整策略或更换强口令。 - 启用审计导致性能下降
- 排查:缩小server_audit_events范围,仅记录 CONNECT/DDL;将日志落盘到独立磁盘。
练习题#
- 创建一个仅允许 10.10.10.0/24 访问的应用账号,并限制其只能访问
appdb的SELECT/INSERT/UPDATE。 - 配置 TLS 并验证非 TLS 连接被拒绝。
- 使用 SQL 查找
Super_priv为Y的账号,并输出user/host。 - 在
/etc/my.cnf中禁用local_infile,重启后验证参数。
练习参考答案(关键命令)#
CREATE USER 'app'@'10.10.10.%' IDENTIFIED BY 'StrongP@ssw0rd!';
GRANT SELECT,INSERT,UPDATE ON appdb.* TO 'app'@'10.10.10.%';
mysql -u app -h 10.10.10.10 -p --ssl-mode=REQUIRED
mysql -u app -h 10.10.10.10 -p --ssl-mode=DISABLED # 预期失败
SELECT user,host FROM mysql.user WHERE Super_priv='Y';
[mysqld]
local_infile=0
SHOW VARIABLES LIKE 'local_infile';
以上清单可作为 MySQL 安全基线与季度巡检模板,结合业务合规要求进一步细化。