MySQL从入门到生产(四):安全加固
一、引言
在当今数据驱动的商业环境中,数据库作为企业核心数据载体,其安全性直接关系到信息资产的保密性、完整性和可用性。根据近年来的数据泄露事件分析,超过68%的企业因数据库基础安全配置不足而遭受数据泄露 。MySQL 8.0 作为全球最流行的开源数据库管理系统,提供了一系列强大的安全增强功能,能够帮助企业构建纵深防御体系,满足等保2.0、GDPR等合规要求 。
本文将系统介绍MySQL 8.0的安全整改实践,从传输加密、访问控制、审计日志等多个维度,为企业提供一套完整的安全加固方案。无论您是数据库管理员、安全工程师还是系统架构师,都能从中获得实用的配置指导和技术洞察。
二、传输加密:杜绝明文通信
1.风险分析
账号、密码、业务数据通过明文传输,易被网络嗅探或中间人攻击(MITM)截获,造成凭证泄露与非授权访问。
2.整改目标
强制所有客户端连接使用 SSL/TLS 加密,禁用非安全通道。
3.实施步骤
生成 SSL 证书(以 mysql 用户身份)
cd /opt/mysql/data/
sudo -u mysql mysql_ssl_rsa_setup --datadir=/opt/mysql/data/
私钥必须严格保护
sudo chmod 600 server-key.pem
sudo chmod 644 *.pem
sudo chown mysql:mysql *.pem
配置 my.cnf
[mysqld]
require_secure_transport = ON
ssl-ca = ca.pem
ssl-cert = server-cert.pem
ssl-key = server-key.pem
tls_version = TLSv1.2,TLSv1.3 # 禁用弱协议
Java 应用连接(推荐 PEM 直接引用)
JDBC 8.0.22+ 支持直接读取 PEM 文件,无需 keytool 转换:
jdbc:mysql://db-host:3306/mydb?
useSSL=true&
requireSSL=true&
verifyServerCertificate=true&
sslMode=VERIFY_CA&
trustCertificateKeyStoreUrl=file:/opt/mysql/data/ca.pem&
trustCertificateKeyStoreType=PEM
若必须使用 JKS,再执行:
keytool -importcert -alias mysql-ca -file ca.pem -keystore truststore -storepass YourStrongPass
验证
SELECT @@have_ssl, @@have_openssl; -- 应为 YES
SELECT @@require_secure_transport; -- 应为 1
SHOW STATUS LIKE 'Ssl_cipher'; -- 非空表示当前连接已加密
三、安全审计:实现行为可追溯
1.危害分析
缺乏审计能力会导致安全事件无法追溯,难以发现潜在威胁和违规操作。特别是在等保合规要求下,审计日志是满足合规性的必要条件 。
2.整改建议
开启完整的审计日志功能,覆盖所有用户行为和安全事件。MySQL 8.0提供了强大的审计插件,可记录所有数据库操作。
3.实施方案
1. 安装审计插件
-- 安装审计插件
INSTALL PLUGIN audit_log SONAME 'audit_log.so';
-- 验证插件状态
SHOW PLUGINS;
2. 配置审计日志
在my.cnf配置文件中添加:
[mysqld]
# 基础日志配置
general_log = 1
general_log_file = /opt/mysql/logs/query.log
log_error = /opt/mysql/logs/error.log
log_bin = /opt/mysql/logs/binlog
# 审计插件配置
plugin-load-add = audit_log.so
audit_log_format = JSON
audit_log_file = /opt/mysql/logs/audit.log
audit_log_policy = ALL
audit_log_rotate_on_size = 100000000
audit_log_flush = ON
3. 审计日志管理
-- 查看审计相关配置
SHOW VARIABLES LIKE 'audit_log%';
-- 手动轮转审计日志
ALTER INSTANCE ROTATE AUDIT LOG;
审计内容分析
审计日志通常包含以下关键信息 :
- 用户身份和来源IP
- 操作类型(查询、更新、删除等)
- 执行时间和时间戳
- 受影响的对象和数据库
- 操作结果(成功或失败)
验证方法
SHOW VARIABLES LIKE 'log_error'; -- 错误日志路径
SHOW VARIABLES LIKE 'general_log'; -- 应为ON
SHOW VARIABLES LIKE 'log_bin'; -- 应为ON
-- 检查审计日志是否正常记录
tail -f /opt/mysql/logs/audit.log
四、身份认证安全:强化密码策略
1.危害分析
弱密码和空密码容易被暴力破解,成为安全体系的薄弱环节。据统计,弱密码是导致数据库未授权访问的主要原因之一 。
2.整改建议
实施强密码策略,确保密码复杂度和定期更换。MySQL 8.0提供了密码验证插件,可强制实施密码策略。
3.实施方案
1. 安装密码验证插件
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
2. 配置密码策略
[mysqld]
# 密码验证插件配置
plugin-load-add = validate_password.so
validate_password_policy = MEDIUM
validate_password_length = 12
validate_password_mixed_case_count = 1
validate_password_number_count = 1
validate_password_special_char_count = 1
validate_password_check_user_name = ON
# 密码有效期配置
default_password_lifetime = 90
password_reuse_interval = 365
password_require_current = ON
3. 密码策略参数说明
- validate_password_policy:密码策略等级(LOW=0, MEDIUM=1, STRONG=2)
- validate_password_length:密码最小长度
- validate_password_mixed_case_count:大小写字母最少数量
- validate_password_number_count:数字最少数量
- validate_password_special_char_count:特殊字符最少数量
验证方法
-- 查看密码策略配置
SHOW VARIABLES LIKE 'validate_password%';
-- 检查用户密码状态
SELECT user, host, password_lifetime, password_last_changed
FROM mysql.user;
-- 检查空密码账户
SELECT user, host FROM mysql.user WHERE authentication_string = '';
五、静态数据加密:守护存储层安全
1.风险分析
.ibd 表空间文件、binlog、备份若未加密,一旦磁盘被盗或云存储泄露,数据将完全暴露。
2.整改目标
启用 InnoDB 表空间加密 + 二进制日志加密。
3.配置
[mysqld]
# 加载密钥环插件
early-plugin-load = keyring_file.so
keyring_file_data = /opt/mysql/keyring/.keyring
# 启用表空间加密(需 innodb_file_per_table=1)
innodb_file_per_table = 1
# 启用 binlog 加密(MySQL 8.0.14+)
binlog_encryption = ON
创建加密表
CREATE TABLE user_info (
id INT PRIMARY KEY,
ssn VARCHAR(20)
) ENCRYPTION = 'Y';
验证
-- 检查加密表
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE CREATE_OPTIONS LIKE '%ENCRYPTION="Y"%';
-- 检查 binlog 是否加密
SHOW VARIABLES LIKE 'binlog_encryption'; -- ON
注意:密钥文件 /opt/mysql/keyring/.keyring 必须严格保护(权限 600,属主 mysql)。
六、权限控制:践行最小权限原则
1.风险分析
过度授权(如 GRANT ALL、SUPER 权限)使普通用户具备管理员能力,极易被利用。
2.整改目标
按需授权,定期审计,回收冗余权限。
3.最佳实践
1. 创建专用应用账户
CREATE USER 'app_user'@'192.168.1.%'
IDENTIFIED WITH caching_sha2_password BY 'Str0ngP@ss!2026';
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_user'@'192.168.1.%';
2. 回收危险权限
-- 禁止非 DBA 用户拥有 FILE、SUPER 等权限
REVOKE FILE, PROCESS, SUPER, SHUTDOWN, RELOAD ON *.* FROM 'dev_user'@'%';
3. 定期审计
-- 查找拥有 SUPER 权限的用户
SELECT user, host FROM mysql.user WHERE super_priv = 'Y';
-- 检查全局权限
SELECT user, host, Select_priv, Insert_priv, Grant_priv FROM mysql.user;
七、访问控制:缩小攻击面
1.风险分析
默认 bind-address = * 允许任意 IP 连接,极大增加暴露风险。
2.整改目标
限制监听地址 + 防火墙双重防护。
3.配置
1. MySQL 绑定地址
[mysqld]
bind-address = 127.0.0.1 # 仅本地访问
# 或 bind-address = 192.168.1.100 # 指定内网IP
2. 防火墙规则(UFW 示例)
sudo ufw allow from 192.168.1.0/24 to any port 3306
sudo ufw deny 3306 # 默认拒绝
验证
SHOW VARIABLES LIKE 'bind_address';
严禁将 3306 端口暴露至公网!
八、服务安全:非特权运行
1.风险分析
以 root 运行 MySQL,一旦被攻破,攻击者将获得系统最高权限。
2.整改目标
使用专用低权限账户运行服务。
3.配置
1. 创建专用用户(若未存在)
sudo groupadd mysql
sudo useradd -r -g mysql -s /bin/false mysql
2. 设置目录权限
sudo chown -R mysql:mysql /opt/mysql/data /opt/mysql/logs /opt/mysql/keyring
sudo chmod 750 /opt/mysql/data
3. 配置 systemd 服务
编辑 /etc/systemd/system/mysqld.service:
[Service]
User=mysql
Group=mysql
验证
ps -ef | grep mysqld | grep -v grep
# 输出应为:mysql ... /usr/sbin/mysqld ...
- 本文标签: MySQL
- 本文链接: https://xiaolanzi.cyou/article/55
- 版权声明: 本文由卓原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
