MySQL 安全防护需构建 “网络 - 操作系统 - 文件系统 - 用户 - 数据” 五层防御体系
通过加密传输、强密码策略、权限管控、数据加密、防注入等手段
全面抵御窃听、篡改、未授权访问等安全风险。
- 识别并防范常见安全攻击(窃听、篡改、回放、拒绝服务等)
- 针对网络、密码、操作系统、文件系统、应用程序制定安全防护措施
- 保护数据传输与存储安全,避免非法拦截和访问
- 配置 SSL/TLS、SSH 等安全连接方式,保障远程访问安全
- 加密静态数据(InnoDB 表空间、日志文件),防范数据泄露
- 配置企业版防火墙,拦截恶意 SQL 操作
核心安全风险与攻击类型
整体安全风险
- 多用户并发访问场景下,MySQL 服务器及所在主机均可能被入侵
- 风险蔓延性:单一环节漏洞可能导致整个数据库系统被控制
- 核心攻击类型:
- 窃听(Eavesdropping):拦截网络传输数据,窃取账号密码或敏感业务数据
- 篡改(Altering):修改传输中的数据或存储的数据,破坏数据完整性
- 回放(Playback):截取合法请求并重复发送,伪装合法用户操作
- 拒绝服务(Denial of Service):通过高频请求或恶意操作耗尽服务器资源,导致服务不可用
MySQL 安装默认安全风险
| 风险层面 | 具体风险 | 危害 |
|---|---|---|
| 网络层面 | 未加密传输、弱密码账号、开放不必要的网络端口 | 账号泄露、数据被窃听、非法连接 |
| 操作系统层面 | 服务器存在多余用户账号、权限分配过宽 | 攻击者通过系统账号间接入侵 MySQL |
| 文件系统层面 | 数据库目录、数据文件、日志文件权限过松 | 未授权用户直接访问或篡改文件 |
| 用户层面 | 匿名账号、超权限账号、长期未修改密码 | 越权访问、账号被盗用 |
网络安全防护
网络是 MySQL 的第一道防线,需限制访问来源、加密传输数据。
公共网络环境防护
- 禁止 MySQL 服务器直接暴露在互联网中,需部署防火墙或 DMZ( demilitarized zone,非军事区)
- 防火墙仅开放 MySQL 端口(默认 3306)给授权客户端 IP
- 多防火墙架构:互联网→外网防火墙→DMZ(应用服务器)→内网防火墙→MySQL 服务器
- 同一主机部署互联网应用与 MySQL 时:
- 禁用 MySQL 网络功能,仅允许通过 Unix Socket(Linux)或命名管道(Windows)本地连接
- 避免网络层面暴露 MySQL 服务
私有网络环境防护
- 私有网络仍存在风险(内部员工恶意操作、钓鱼攻击控制内部主机)
- 核心措施:
- 对所有网络传输启用加密(SSL/TLS 或 SSH 隧道)
- 限制 MySQL 端口仅对授权主机开放,禁止全网可见
- 禁用不必要的网络协议,仅保留 TCP/IP(如需远程连接)
通用网络安全措施
- 防火墙管控:严格限制 MySQL 端口(3306)的访问 IP 范围
- 绑定网络接口:通过
bind-address参数指定 MySQL 仅监听内网 IP,拒绝外网访问 - 最小权限原则:MySQL 账号仅授予必要权限,禁止给普通用户分配
SUPER、FILE等高危权限 - 加密传输:所有远程连接强制使用 SSL/TLS,禁止明文传输
- 弱密码防护:禁用无密码账号,强制使用复杂密码(字母 + 数字 + 特殊字符)
连接安全(加密传输)
通过 SSL/TLS 或 SSH 隧道保障客户端与服务器之间的数据传输安全。
SSL/TLS 安全连接(推荐)
核心原理
- 基于 OpenSSL 实现,实际使用更安全的 TLS 协议(MySQL 中仍沿用 SSL 相关配置项)
- 采用 “非对称加密 + 对称加密” 结合模式:
- 客户端发起连接,服务器返回数字证书(含公钥)
- 客户端验证证书合法性,生成会话密钥(对称加密密钥)
- 客户端用服务器公钥加密会话密钥,发送给服务器
- 服务器用私钥解密会话密钥,后续通信通过会话密钥加密
关键配置
-
服务器端(默认已启用 SSL 支持):
- 检查 SSL 支持:
SHOW VARIABLES LIKE 'have_ssl';(返回 YES 表示支持) - 证书配置(默认自动生成,可自定义):
ssl_ca:CA 证书文件(默认 ca.pem)ssl_cert:服务器证书文件(默认 server-cert.pem)ssl_key:服务器私钥文件(默认 server-key.pem)
- 禁用 SSL(不推荐):启动时添加
--ssl=0或--skip-ssl
- 检查 SSL 支持:
-
客户端连接选项:
-
1--ssl-mode:指定 SSL 连接模式(核心参数)
- PREFERRED(默认):优先 SSL 连接,失败则降级为明文
- REQUIRED:强制 SSL 连接,失败则拒绝
- VERIFY_CA:验证 CA 证书合法性
- VERIFY_IDENTITY:验证证书与服务器主机名匹配
-
示例:
mysql -u root -p --ssl-mode=REQUIRED -h 192.168.1.100
-
-
账号强制 SSL 连接:
- 创建账号时指定:
CREATE USER 'user'@'host' REQUIRE SSL; - 修改已有账号:
ALTER USER 'user'@'host' REQUIRE SSL;
- 创建账号时指定:
TLS 版本与加密套件
- 限制 TLS 版本(禁用低版本 TLSv1):
SET GLOBAL tls_version='TLSv1.2,TLSv1.3'; - 指定加密套件(优先强加密算法):
--ssl-cipher=DHE-RSA-AES256-SHA:AES128-SHA
SSH 隧道安全连接(适合无 SSL 环境)
-
原理:通过 SSH 隧道转发 MySQL 连接,所有数据通过 SSH 加密传输
-
操作步骤:
-
客户端建立 SSH 隧道:
1ssh -L 33306:mysql-server-ip:3306 ssh-user@ssh-server-ip(本地 33306 端口转发到 MySQL 服务器 3306 端口)
-
客户端连接本地转发端口:
1mysql -u root -p -P 33306 -h 127.0.0.1
-
密码安全
密码是用户身份验证的核心,需通过策略和工具强化防护。
密码验证组件(validate_password)
-
作用:强制密码复杂度,拒绝弱密码
-
安装(MySQL 8.0 默认已安装,需启用):
1INSTALL COMPONENT 'file://component_validate_password'; -
核心配置变量:
validate_password.policy:密码强度策略(0=LOW:仅长度;1=MEDIUM:长度 + 数字 + 大小写 + 特殊字符;2=STRONG:MEDIUM + 字典校验)validate_password.length:最小密码长度(默认 8)validate_password.number_count:至少包含的数字个数(默认 1)validate_password.special_char_count:至少包含的特殊字符个数(默认 1)
-
动态修改配置:
1 2SET GLOBAL validate_password.policy=2; # 强策略 SET GLOBAL validate_password.length=12; # 最小12位
密码生命周期管理
- 全局默认策略:
SET GLOBAL default_password_lifetime=90;(90 天过期) - 账号级配置:
- 创建账号时:
CREATE USER 'user'@'host' PASSWORD EXPIRE INTERVAL 30 DAY;(30 天过期) - 禁用自动过期:
ALTER USER 'user'@'host' PASSWORD EXPIRE NEVER; - 手动强制过期:
ALTER USER 'user'@'host' PASSWORD EXPIRE;(用户下次登录需改密码)
- 创建账号时:
其他密码防护措施
-
禁用空密码账号:
DELETE FROM mysql.user WHERE authentication_string=''; -
定期修改密码:管理员账号每 30-90 天修改一次,普通账号根据业务需求调整
-
避免密码泄露:不在配置文件、脚本中明文存储密码,使用
mysql_config_editor存储加密密码 -
双重密码支持(MySQL 8.0.14+):修改密码时保留旧密码,平滑过渡:
1ALTER USER USER() IDENTIFIED BY 'new_password' RETAIN CURRENT PASSWORD;
操作系统与文件系统安全
MySQL 的运行依赖操作系统,需加固底层环境安全。
操作系统安全
- 最小化系统账号:仅保留必要的系统账号(如 root、mysql),删除多余账号
- 专用 MySQL 账号:用低权限的 mysql 系统账号运行 MySQL 服务,禁止 root 账号启动
- 禁用不必要服务:关闭服务器上无关的网络服务(如 FTP、Telnet),减少攻击面
- 及时打补丁:定期更新操作系统安全补丁,修复已知漏洞
- 限制 SSH 访问:仅允许授权 IP 通过 SSH 登录服务器,禁用密码登录(改用密钥)
文件系统安全
-
数据目录权限:MySQL 数据目录(默认 /var/lib/mysql)权限设置为 700,仅 mysql 用户可访问
1 2chmod 700 /var/lib/mysql chown -R mysql:mysql /var/lib/mysql -
配置文件防护:my.cnf/my.ini 文件权限设置为 600,禁止非授权用户修改
1 2chmod 600 /etc/my.cnf chown mysql:mysql /etc/my.cnf -
日志文件保护:错误日志、二进制日志、审计日志等设置严格权限,避免敏感信息泄露
-
备份文件安全:数据库备份文件加密存储,传输过程中启用加密,定期测试备份可用性
静态数据加密(数据 - at-rest 加密)
对存储在磁盘上的数据(表空间、日志文件)进行加密,防范文件泄露风险。
密钥管理(Keyring)
-
作用:安全存储加密密钥(如 InnoDB 表空间加密密钥)
-
核心插件(MySQL 8.0 支持):
keyring_file(社区版):密钥存储在本地文件keyring_encrypted_file(企业版):密钥存储在加密文件keyring_okv(企业版):对接外部密钥管理系统(如 Oracle Key Vault)
-
启用配置(以 keyring_file 为例):
1 2 3[mysqld] early-plugin-load-add=keyring_file.so keyring_file_data=/var/lib/mysql-keyring/keyring
InnoDB 表空间加密
- 独立表空间加密:
- 创建表时加密:
CREATE TABLE t1 (id int) ENCRYPTION='Y'; - 现有表加密:
ALTER TABLE t1 ENCRYPTION='Y';
- 创建表时加密:
- 系统表空间加密:
ALTER TABLESPACE mysql ENCRYPTION='Y'; - 通用表空间加密:
CREATE TABLESPACE ts1 ENCRYPTION='Y' ADD DATAFILE 'ts1.ibd';
日志文件加密
-
二进制日志加密:
SET GLOBAL binlog_encryption=ON;(MySQL 8.0.14+) -
InnoDB redo/undo 日志加密:
1 2 3[mysqld] innodb_redo_log_encrypt=ON innodb_undo_log_encrypt=ON
SQL 注入防护
SQL 注入是最常见的应用层攻击,需通过代码规范和工具防护。
注入攻击原理
- 攻击者通过应用输入框注入恶意 SQL 片段,篡改原 SQL 逻辑,如:
- 正常查询:
SELECT * FROM users WHERE username='user' AND password='pass'; - 注入后:
SELECT * FROM users WHERE username='user' OR 1=1 --' AND password='pass';(绕过密码验证)
- 正常查询:
核心防护措施
-
使用参数化查询 / 预处理语句:避免直接拼接用户输入到 SQL 中
-
示例(预处理语句):
1 2 3PREPARE stmt FROM 'SELECT * FROM users WHERE username=? AND password=?'; SET @user='user', @pass='pass'; EXECUTE stmt USING @user, @pass;
-
-
输入验证与过滤:对用户输入的特殊字符(单引号、双引号、分号)进行转义或过滤
-
最小权限原则:应用连接 MySQL 的账号仅授予必要权限(如 SELECT、INSERT),禁止
DROP、ALTER等高危权限 -
禁用敏感函数:限制
LOAD_FILE()、INTO OUTFILE等可能泄露文件的函数 -
使用 ORM 框架:如 MyBatis、Hibernate,自动处理 SQL 拼接,降低注入风险
8.3 检测与监控
- 启用一般查询日志或慢查询日志,监控异常 SQL 语句
- 通过 Performance Schema 跟踪高频执行的异常语句
- 定期审计应用代码,排查未使用参数化查询的场景
MySQL 企业版防火墙(Enterprise Firewall)
仅 MySQL 企业版提供,通过白名单机制拦截恶意 SQL 操作。
核心功能
- 基于账号的 SQL 语句白名单:仅允许预定义的 SQL 模式执行
- 支持记录模式(RECORDING)、防护模式(PROTECTING)、检测模式(DETECTING)
- 自动归一化 SQL 语句(替换参数为占位符),避免因参数不同误判
配置步骤
-
安装防火墙插件(执行企业版安装脚本):
1mysql -u root -p < share/linux_install_firewall.sql -
注册账号并设置模式:
- 记录模式(学习合法 SQL):
CALL mysql.sp_set_firewall_mode('user@host', 'RECORDING'); - 防护模式(拦截非法 SQL):
CALL mysql.sp_set_firewall_mode('user@host', 'PROTECTING');
- 记录模式(学习合法 SQL):
-
查看防火墙状态:
1 2SELECT * FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS; SELECT * FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_WHITELIST; -
监控防火墙事件:通过
SHOW GLOBAL STATUS LIKE 'Firewall%'查看拦截 / 允许统计
安全审计与监控
- 启用审计日志(企业版):记录所有用户连接、SQL 执行操作,便于事后追溯
- 定期权限审计:检查 mysql.user、mysql.db 等授权表,回收冗余权限
- 监控异常连接:通过 Performance Schema 或 mysqladmin processlist 查看高频连接、异常 IP 连接
- 日志审计:定期分析错误日志、二进制日志,排查登录失败、异常 SQL 执行等情况
实践思路
- 分层防御:网络层(防火墙 + SSL)→ 系统层(最小账号 + 权限)→ 数据层(加密 + 审计)→ 应用层(防注入 + 参数化查询)
- 定期巡检:每月进行安全扫描,检查弱密码、冗余权限、未加密传输等问题
- 应急响应:制定安全事件处理流程,如账号泄露后立即锁定账号、修改密码、审计操作日志
- 备份与恢复:加密存储备份,定期测试恢复流程,确保数据泄露后可快速恢复