本页是 PmaControl 的原创文档。它保留了用于 MySQL 优化工作的实用索引结构,不复制第三方内容,也不依赖外部产品。
目标
MySQL 安全检查用于降低攻击面:权限过大的账号、未加密连接、弱密码、不必要的全局权限以及网络暴露。
优先检查
- 匿名账号或无密码账号。
- 拥有无依据的
SUPER、FILE、PROCESS、GRANT OPTION或全局权限的用户。 - 可以使用明确主机时却使用
%访问。 - 敏感流量未强制 TLS。
- 无需求却启用
local_infile。 - 二进制日志和备份可被权限过宽的系统账号读取。
基础 SQL
SELECT user, host, account_locked, password_expired
FROM mysql.user
ORDER BY user, host;
SHOW GRANTS FOR 'app_user'@'%';
要点
原则很简单:每个权限都必须有负责人、理由和生命周期。
明确范围并收集账户证据
盘点数据库服务器、代理、应用账户、管理员、复制节点和备份工具。为每个账户指定负责人和预期来源主机。下列账户字段适用于 MySQL;MariaDB 的账户存储方式因版本而异。使用获得适当授权的审计账户,避免将密码哈希或凭据导出到报告中。
SELECT VERSION() AS server_version,
CURRENT_USER() AS matched_account, USER() AS connection_identity;
SELECT user, host, plugin, account_locked, password_expired, ssl_type
FROM mysql.user
ORDER BY user, host;
SELECT grantee, privilege_type, is_grantable
FROM information_schema.user_privileges
ORDER BY grantee, privilege_type;
CURRENT_USER() 标识权限检查所用账户,USER() 描述连接身份。仅全局权限清单并不完整:还应通过 SHOW GRANTS 检查数据库和表权限、动态权限以及分配的角色,包括默认和当前活动角色。认证字符串为空并不能证明账户不安全,因为认证插件各不相同。需检查插件、来源限制、锁定状态及实际认证策略。
验证实际连接的传输安全
SHOW GLOBAL VARIABLES WHERE Variable_name IN (
'require_secure_transport', 'tls_version', 'local_infile',
'secure_file_priv', 'bind_address', 'port'
);
SHOW SESSION STATUS WHERE Variable_name IN ('Ssl_cipher', 'Ssl_version');
会话 TLS 字段仅描述当前连接。Unix socket 可作为安全的本地传输方式,且不一定具有 TLS cipher。TCP 连接应在应用驱动中检查加密及证书、主机名验证。若代理终止 TLS,应分别测试客户端到代理和代理到服务器两段链路。服务器支持 TLS 不代表所有客户端都强制使用它。
mysql --host=db.example --user=app_reader --password \
--ssl-mode=VERIFY_IDENTITY --ssl-ca=/path/to/ca.pem
此 MySQL 客户端示例会提示输入密码并验证服务器身份;请替换主机名和 CA 路径。其他客户端应检查自身连接器的选项。制定证书轮换方案,并在强制启用新策略之前测试应用新建连接,防止现有会话掩盖重新连接失败。
检查 SQL 权限之外的暴露面
| 控制项 | 需保留的证据 |
|---|---|
| 网络访问 | 监听、防火墙及预期来源的可达性 |
| 文件与备份 | 权限、加密、密钥保管及恢复访问 |
| 审计与凭据 | 受保护日志、保留策略、凭据轮换和过期账户清理 |
按任务落实最小权限:区分常规应用流量、迁移、监控与备份。用新连接测试权限收回和来源限制,保留原授权以便回滚,并监测被拒绝的操作。按文档化升级路径更新服务器及连接器;认证插件支持依赖具体版本。每项安全发现最终都应明确负责人、整改期限与已验证的结果。