讲解
数据库安全的思路是分层设防。账号层:root 保持仅 localhost,应用账号按最小权限授予、按来源网段限制 host;密码层:8.0 默认的 caching_sha2_password 插件本身足够强,配合 validate_password 组件可以强制密码复杂度(最小长度、大小写数字混合),账号还可以设置密码过期和失败锁定。网络层:3306 端口绝不直接暴露公网,bind-address 只绑定需要的网卡,前面再有防火墙或安全组收口。
传输层:客户端到服务器的连接可以强制 SSL/TLS,防止内网嗅探——建账号时加 REQUIRE SSL,该账号就拒绝明文连接。审计层:general log 会记录所有语句(量太大,只适合短期排查),长期审计用企业版的 audit log 或第三方方案。最后是补丁纪律:MySQL 的次要版本修复大量安全漏洞,跟进 8.0.x 的升级是性价比最高的安全投资。
应用侧还有一条老朋友必须重申:SQL 注入。数据库权限做得再好,应用把用户输入拼进 SQL 就全破防了。所有参数用预编译占位符传入,这是应用层的纪律,但 DBA 可以通过「应用账号不给 DROP、不给 FILE 权限」把注入的破坏力压到最小——纵深防御的意义就在这里。
示例
安全体检三连:账号与认证插件、密码策略组件、有没有不该存在的远程 root(第三条的空结果就是好消息):
SELECT user, host, plugin FROM mysql.user;
SHOW VARIABLES LIKE 'validate_password%';
SELECT user, host FROM mysql.user WHERE user = 'root' AND host != 'localhost';
创建一个强制 SSL 连接的账号(REQUIRE SSL),用 SHOW CREATE USER 核对安全属性,然后清理:
CREATE USER IF NOT EXISTS sec_demo@'%' IDENTIFIED BY 'Sec#Strong2026' REQUIRE SSL;
SHOW CREATE USER sec_demo@'%';
DROP USER IF EXISTS sec_demo@'%';
常见坑
- 3306 直接暴露公网:公网扫描器昼夜不停地扫 3306,弱密码账号分分钟被撞开。端口只对应用服务器开放,远程管理走 SSH 隧道或 VPN。
- 密码写进脚本和代码仓库:备份脚本、部署脚本里的明文密码迟早泄露。用 login-path、密钥管理服务,泄露过的密码按「已泄露」处理立刻轮换。
- 应用账号权限过剩:一个 CMS 的注入漏洞配上 ALL PRIVILEGES 账号,等于送出整台数据库。权限最小化是给应用漏洞上的保险。
- 以为内网就安全:内网横向移动是攻击的常规路径,办公网失陷后内网数据库就是下一个目标。内网同样要最小权限、要传输加密、要审计。
小结
安全分四层:账号最小权限、网络收口、传输加密、补丁跟进;REQUIRE SSL 强制加密连接,validate_password 强制密码强度;应用层参数化查询防注入。最后一章把一切收拢:性能监控与调优速查。