MySQL 安全加固(状态审核、网络、TLS、身份验证、权限、审计、加密)
MySQL难度: 中级耗时: 5 分钟(审核)– 3 小时(完整加固)这不是安装指南:它用于发现并修补运行中的 MySQL 8.4 / 8.0 服务器的安全缺口。先由只读的状态审核按严重程度列出问题,并说明每条发现对应哪张卡片;然后逐项或按顺序全部修补:bind_address、防火墙和账户的 host 限制;TLS、require_secure_transport 和客户端 VERIFY_IDENTITY;caching_sha2_password、密码策略、远程 root 和匿名账户;角色和无 DDL 的应用账户;审计;InnoDB 表空间加密(keyring component);加密备份;操作系统;版本跟踪。Community 版没有审计:需要 MySQL Enterprise(付费订阅)或 Percona Server(免费);TDE 在 Community 版中也可用。最后再次运行审核。
架构: 单台 MySQL 服务器 + 应用服务器(客户端验证);replica/InnoDB Cluster 见注释
场景
- 状态审核:我有哪些安全缺口?(只读) — 首先运行的扫描:匿名、无密码和远程 root 账户,任意地址(%)访问,弱身份验证插件,全局权限,TLS,审计,加密,文件权限和防火墙;不做任何更改。
- 完整加固(全部按顺序) — 新安装或从未加固过的服务器:所有项按安全顺序执行;MySQL 会重启数次(需要维护窗口)。
- 网络和连接:谁能从哪里连接?(bind_address、防火墙、host 限制) — MySQL 在所有接口上监听,账户 host 为 '%',端口对所有人开放。修改 bind_address 需要重启。
- 加密连接(TLS、require_secure_transport、VERIFY_IDENTITY) — 正在使用自动生成的自签名证书、接受未加密连接,或客户端不验证证书。使用 ALTER INSTANCE RELOAD TLS 无需停机。
- 身份验证和密码(caching_sha2、密码策略、root) — mysql_native_password 账户、没有密码策略、远程 root、匿名账户和 test 数据库。无需停机。
- 最小权限:角色和无 DDL 的应用账户 — 应用账户拥有 CREATE/ALTER/DROP 或 . 权限,存在拥有 FILE/SUPER 的账户;读/写/DDL 角色及权限报告。无需停机。
- 审计:谁做了什么? — 审计人员要求记录会话和查询。MySQL Community 没有内置审计:可选 Enterprise Audit、Percona Server Audit Log Filter,或 Community 下有限的替代方案。许可: Enterprise Audit 仅随 MySQL Enterprise 订阅提供;Percona Audit Log Filter 免费。
- 静态数据加密(InnoDB 表空间加密、keyring) — 针对磁盘或备份副本被盗的表、redo、undo 和 binlog 加密;安装 keyring component 需重启一次,大表需要 ALTER 时间。在 Community 版中同样无需许可;加密/KMS keyring 属于 Enterprise。
- 备份安全(加密备份、login-path、权限) — 备份未加密或位于所有人可读的目录,脚本中有明文密码;mysqldump + GPG 或 XtraBackup --encrypt、备份账户和 login-path。
- 操作系统层面(服务账户、权限、core dump、SELinux) — 数据目录或证书文件对其他用户开放、secure_file_priv 为空、local_infile 已开启、SELinux 已关闭。部分设置在重启后生效。
- 补丁与版本:我用的是受支持的版本吗? — 版本、支持终止(8.0 已于 2026 年 4 月终止)和待安装的更新;执行升级请参阅升级指南。只读。
开始之前
- MySQL … 正在运行,并且在服务器上以 root 身份执行 mysql 命令无需密码即可登录(root@localhost 使用 auth_socket,或通过 mysql_config_editor 设置的 client login-path)。如果按 MySQL 安装指南 安装,这已就绪。步骤中的 SQL 以 root 通过 mysql -t 执行。
- 到服务器开着两个独立的 SSH 会话;其中一个保持 mysql 客户端打开。修改账户 host、require_secure_transport 和防火墙后,在另一个会话中测试新连接;确认成功之前不要关闭旧会话。本指南中 root@localhost 套接字登录始终不变:它一直是回退途径。
- 维护窗口:在所选的项中 MySQL 会重启(bind_address、keyring component、审计插件、core dump 限制)。有 replica 的环境请先在 replica 上执行。
- 所有连接 MySQL 的应用清单(服务器 IP、账户、驱动版本)。审核步骤会显示当前连接;不在清单上的客户端在限制后将无法连接。
- 有一份最新且恢复已验证过的备份(逻辑 或 XtraBackup)。加密(TDE)步骤中如果 keyring 文件丢失,数据将无法读取:请在配置 keyring 之前先做备份。
指南阶段
- 状态审核(只读) — 列出数据库内部的发现 · 审核操作系统层面
- 开始之前:回退点 — 备份当前设置、账户和权限 · 启用额外配置目录
- 权限 — 1. 诊断 — 显示账户的权限
- 权限 — 3. 实施 — 创建角色并授权 · 创建账户并关联到角色 · 移除应用账户的直接权限 · 权限报告
- 权限 — 4. 验证 — 验证实际权限中没有 DDL · 从应用服务器尝试 DDL
- 权限 — 5. 后续 — migration 账户不用时保持锁定
- 身份验证 — 1. 诊断 — 显示身份验证插件、密码设置和默认账户
- 身份验证 — 2. 安全网 — 检查驱动兼容性
- 身份验证 — 3. 实施 — 删除匿名账户、远程 root 和 test 数据库 · 设置密码策略(validate_password、历史) · 将 mysql_native_password 账户迁移到 caching_sha2_password · 创建个人 DBA 账户
- 身份验证 — 4. 验证 — 验证账户状态 · 从应用服务器尝试以 root 登录
- TLS — 1. 诊断 — 显示当前 TLS 设置和未加密的客户端
- TLS — 3. 实施 — 创建测试 CA 和服务器证书 · 创建私钥和证书签名请求(CSR) · 放置签发的证书 · 验证证书和私钥 · 设置 SELinux 标签 · 将服务器切换到新证书(无需停机) …
- TLS — 4. 验证 — 验证未加密连接被拒绝
- TLS — 5. 后续:证书续期 — 证书续期步骤
- 网络 — 1. 诊断:谁从哪里连接? — 显示监听地址、账户 host 和活动客户端
- 网络 — 3. 实施 — 将 host 为 '%' 的账户限制到应用网络 · 收紧监听地址(重启后生效) · 在防火墙中只对允许的网络开放端口 · 为监听地址重启 MySQL
- 网络 — 4. 验证 — 从应用服务器测试连接(新会话)
- 审计 — 1. 诊断 — 显示审计插件和日志设置
- 审计 — 3. 实施 — Community:记录登录失败和 DML 语句文本 · 安装 Enterprise Audit 插件 · 定义 Enterprise Audit 过滤器 · 安装 Percona Audit Log Filter 组件 · 定义 Percona 审计过滤器 · 将审计日志转发到中心服务器(rsyslog imfile) …
- 审计 — 4. 验证 — 做一项更改并查看其痕迹
- 备份 — 1. 诊断 — 显示备份的加密状态和密码文件
- 备份 — 3. 实施 — 以最小权限创建备份账户 · 将密码保存到 login-path · 导入 GPG 公钥 · 加密备份脚本 · 使用 XtraBackup 的加密备份脚本 · 密钥文件、备份目录和手动测试 …
- 备份 — 4. 验证 — 测试加密备份能否解密
- 操作系统 — 1. 诊断 — 服务账户、权限、文件权限和 SELinux
- 操作系统 — 3. 实施 — 限制文件导入/导出 · 修正数据目录和密钥文件的权限 · 关闭 core dump · 重新加载 systemd 并重启 MySQL · 防止密码进入命令历史 · 保持 SELinux 为 Enforcing
- 操作系统 — 4. 验证 — 验证更改
- 加密 — 1. 诊断 — 显示 keyring 和加密状态
- 加密 — 2. 安全网 — 加密前做完整备份
- 加密 — 3. 实施 — 写入 keyring component 清单文件 · 准备 keyring 目录和配置 · 重启以加载 keyring · 为 redo、undo、binlog 和新表启用加密 · 加密应用数据库的表 · 备份 keyring 文件
- 加密 — 4. 验证 — 验证加密和 keyring