当前位置: 首页 > news >正文

MySQL全面安全加固实战指南

MySQL 加固核心目标:限制未授权访问、最小化权限暴露、加密敏感数据、审计操作行为,以下方案覆盖从基础配置到高级防护的全流程,适配 MySQL 5.7+ / 8.0+(标注版本差异处需重点注意)。

一、基础环境加固(系统 + 安装层面)

1. 升级到稳定安全版本

旧版本(如 5.6 及以下)存在大量未修复漏洞(如权限绕过、SQL 注入),优先升级至:

  • MySQL 5.7.30+(LTS 长期支持版)
  • MySQL 8.0.20+(推荐,安全性更强,默认认证插件更安全)

升级检查

SELECT VERSION(); -- 查看当前版本

2. 以非 root 用户运行 MySQL

默认 MySQL 可能以 root 用户启动,若被入侵可能导致服务器提权,需创建专用低权限用户:

# 1. 创建 mysql 系统用户(若未创建)
useradd -r -s /sbin/nologin mysql# 2. 修改数据目录/配置文件权限(Linux 示例)
chown -R mysql:mysql /var/lib/mysql  # 数据目录
chown -R mysql:mysql /etc/my.cnf      # 配置文件
chmod 700 /var/lib/mysql              # 仅属主可读写
chmod 600 /etc/my.cnf                 # 仅属主可修改# 3. 重启 MySQL 并验证运行用户
systemctl restart mysqld
ps -ef | grep mysqld | grep -v grep  # 确认进程属主为 mysql

3. 清理无用组件与文件

  • 卸载未使用的存储引擎(如 CSV、BLACKHOLE,仅保留 InnoDB);
  • 删除安装残留的测试数据库(test 库)和示例表;
  • 移除无用的脚本(如 mysql_install_db 旧脚本,MySQL 8.0 已废弃)。

删除 test 库

DROP DATABASE IF EXISTS test;

二、访问控制加固(核心:限制 “谁能连、从哪连”)

1. 初始化安全配置(必做)

MySQL 提供内置工具 mysql_secure_installation,一键完成基础加固(需登录 MySQL 后执行):

mysql_secure_installation

按提示完成以下操作:

  • 设置 / 修改 root 密码(若未设置);
  • 移除匿名用户(anonymous 用户,允许空密码登录);
  • 禁止 root 用户远程登录(默认仅允许 localhost 访问);
  • 删除 test 数据库及匿名用户对所有数据库的访问权限;
  • 刷新权限表(FLUSH PRIVILEGES)。

2. 清理冗余 / 危险用户

(1)查看所有用户及登录主机
-- MySQL 5.7+
SELECT user, host, authentication_string FROM mysql.user;
-- MySQL 8.0+(默认认证插件为 caching_sha2_password)
SELECT user, host, plugin FROM mysql.user;
(2)删除无用用户
  • 匿名用户(user='' 或 host='%' 的空用户);
  • 长期未使用的账号;
  • 权限过大的普通用户。
-- 删除匿名用户(示例)
DROP USER IF EXISTS ''@'localhost';
DROP USER IF EXISTS ''@'%';-- 删除指定用户(如 test@'%')
DROP USER IF EXISTS 'test'@'%';FLUSH PRIVILEGES; -- 刷新权限

3. 限制用户登录主机(最小化访问范围)

避免用户以 host='%'(允许所有主机登录),仅授权信任的 IP / 网段:

-- 示例1:仅允许本地登录(推荐 root 用户)
CREATE USER IF NOT EXISTS 'root'@'localhost' IDENTIFIED BY 'StrongP@ss123';-- 示例2:允许指定 IP 登录(如办公网 192.168.1.0/24 网段)
CREATE USER IF NOT EXISTS 'appuser'@'192.168.1.%' IDENTIFIED BY 'AppP@ss456';-- 错误示例(禁止):允许所有主机登录
CREATE USER 'baduser'@'%' IDENTIFIED BY 'weakpass'; -- 风险极高

4. 最小权限原则分配权限

(1)拒绝给普通用户高危权限

以下权限仅授予 root 或管理员,禁止给应用用户:

  • SUPER:修改全局参数、终止线程(可能用于提权);
  • FILE:读写服务器文件(可能泄露敏感数据或写入恶意文件);
  • SHUTDOWN:关闭 MySQL 服务;
  • CREATE USER:创建 / 删除用户(权限滥用风险);
  • ALTER/DROP:修改 / 删除表(误操作或恶意破坏)。
(2)应用用户权限示例(仅授予必要权限)
-- 给应用用户仅授予指定库的查询/插入/更新权限
GRANT SELECT, INSERT, UPDATE ON appdb.* TO 'appuser'@'192.168.1.%';-- 给只读用户仅授予查询权限
GRANT SELECT ON appdb.* TO 'readuser'@'192.168.1.%';FLUSH PRIVILEGES;
(3)定期回收未使用权限
-- 查看用户权限
SHOW GRANTS FOR 'appuser'@'192.168.1.%';-- 回收权限(如回收 UPDATE 权限)
REVOKE UPDATE ON appdb.* FROM 'appuser'@'192.168.1.%';

三、密码安全加固(防止暴力破解)

1. 设置强密码策略

(1)MySQL 5.7+ 配置(通过 validate_password 插件)
-- 启用密码验证插件(默认已启用,若未启用则执行)
INSTALL PLUGIN validate_password SONAME 'validate_password.so';-- 查看当前密码策略
SHOW VARIABLES LIKE 'validate_password%';-- 设置强密码规则(修改 my.cnf 永久生效)
[mysqld]
validate_password_length = 12  # 密码最小长度 12 位
validate_password_policy = STRONG  # 强策略(需包含大小写、数字、特殊字符)
validate_password_special_char_count = 1  # 至少 1 个特殊字符
validate_password_mixed_case_count = 1  # 至少 1 个大小写字母
(2)MySQL 8.0+ 配置(默认启用 validate_password,策略更严格)
-- 8.0 新增参数,禁止密码与用户名/主机名相同
SET GLOBAL validate_password_check_user_name = ON;-- 永久生效(my.cnf)
[mysqld]
validate_password_length = 12
validate_password_policy = STRONG
validate_password_check_user_name = ON

2. 定期更换密码 + 密码过期策略

-- 设置用户密码过期时间(90 天,MySQL 5.7+ 支持)
ALTER USER 'appuser'@'192.168.1.%' PASSWORD EXPIRE INTERVAL 90 DAY;-- 强制用户下次登录修改密码
ALTER USER 'appuser'@'192.168.1.%' PASSWORD EXPIRE FORCE;-- 禁止重复使用最近 5 次密码(MySQL 8.0+ 支持)
SET GLOBAL password_history = 5;

3. 禁用明文存储密码

  • MySQL 5.7+ 默认使用 mysql_native_password 插件(哈希存储,仍有破解风险);
  • MySQL 8.0+ 默认使用 caching_sha2_password 插件(更安全,支持加盐哈希),建议所有用户切换至此插件:
-- 修改用户认证插件(MySQL 8.0+)
ALTER USER 'appuser'@'192.168.1.%' IDENTIFIED WITH caching_sha2_password BY 'NewStrongP@ss789';-- 全局默认使用 caching_sha2_password(my.cnf)
[mysqld]
default_authentication_plugin = caching_sha2_password

四、网络安全加固(防止网络层面攻击)

1. 绑定内网 IP,禁止公网监听

默认 MySQL 监听 0.0.0.0(所有网卡),易被公网扫描,修改 my.cnf 绑定内网 IP:

[mysqld]
bind-address = 192.168.1.100  # 仅监听内网 IP
# 若无需远程访问,直接绑定 localhost
# bind-address = 127.0.0.1

重启 MySQL 后验证:

netstat -tuln | grep 3306  # 确认仅监听指定 IP:3306

2. 防火墙限制 3306 端口访问

仅允许信任的 IP / 网段访问 MySQL 端口(3306),禁止公网开放。

(1)Linux 防火墙(firewalld)
# 允许 192.168.1.0/24 网段访问 3306
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="3306" accept'# 禁止其他所有 IP 访问 3306
firewall-cmd --permanent --remove-port=3306/tcp# 重新加载防火墙规则
firewall-cmd --reload# 验证规则
firewall-cmd --list-rich-rules
(2)Windows 防火墙

在 “高级设置” 中创建入站规则:仅允许指定 IP 访问 3306 端口,拒绝其他所有。

3. 启用 SSL/TLS 加密传输(防止数据窃听)

MySQL 传输默认明文,需启用 SSL 加密客户端与服务器的通信(MySQL 5.7+ 支持,8.0+ 默认推荐)。

(1)生成 SSL 证书(自签或 CA 签发)
# 生成 CA 证书(有效期 3650 天)
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3650 -key ca-key.pem > ca.pem# 生成服务器证书
openssl req -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem > server-req.pem
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem# 生成客户端证书(供应用连接使用)
openssl req -newkey rsa:2048 -days 3650 -nodes -keyout client-key.pem > client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 02 > client-cert.pem# 修改证书权限(仅 mysql 用户可读)
chmod 600 *.pem
chown mysql:mysql *.pem
mv *.pem /etc/mysql/ssl/  # 移动到安全目录
(2)配置 MySQL 启用 SSL(my.cnf)
[mysqld]
ssl-ca = /etc/mysql/ssl/ca.pem
ssl-cert = /etc/mysql/ssl/server-cert.pem
ssl-key = /etc/mysql/ssl/server-key.pem# 强制客户端使用 SSL 连接(可选,增强安全性)
require_secure_transport = ON  # MySQL 8.0+ 支持;5.7 用 ssl=1
(3)验证 SSL 启用
-- 服务器端验证
SHOW VARIABLES LIKE '%ssl%';  # 若 have_ssl 为 YES 则启用成功-- 客户端连接验证(需携带证书)
mysql -u appuser -p -h 192.168.1.100 --ssl-ca=/etc/mysql/ssl/ca.pem --ssl-cert=/etc/mysql/ssl/client-cert.pem --ssl-key=/etc/mysql/ssl/client-key.pem-- 连接后验证 SSL 状态
STATUS;  # 查看 SSL 行是否为 Cipher in use: xxx

4. 禁用 LOAD DATA LOCAL INFILE(防止文件泄露)

LOAD DATA LOCAL INFILE 允许客户端读取服务器本地文件,可能被利用泄露敏感数据(如 /etc/passwd),禁用:

[mysqld]
local-infile = 0  # 服务器端禁用[mysql]
local-infile = 0  # 客户端禁用

五、数据安全加固(保护数据不泄露、不丢失)

1. 启用 InnoDB 透明加密(TDE,MySQL 8.0.16+ 支持)

对数据文件加密,防止磁盘被盗导致数据泄露:

[mysqld]
innodb_encrypt_tables = ON  # 全局启用表加密
innodb_encrypt_log = ON     # 重做日志加密
innodb_encryption_threads = 4  # 加密线程数
innodb_encryption_rotate_key_age = 90  # 90 天轮换密钥
(1)创建加密密钥(需先设置密钥环插件)
-- 启用密钥环插件(my.cnf 中配置)
[mysqld]
early-plugin-load-add = keyring_file.so
keyring_file_data = /var/lib/mysql-keyring/keyring  # 密钥存储路径-- 创建加密表(自动加密)
CREATE TABLE appdb.user (id INT, name VARCHAR(20)) ENGINE=InnoDB;

2. 敏感字段应用层加密

对密码、手机号、身份证号等敏感字段,在应用层加密后存储(避免数据库管理员直接查看):

  • 推荐算法:AES-256-GCM(对称加密,需妥善保管密钥);
  • 示例(MySQL 内置 AES 加密,仅作演示,建议应用层加密):
-- 加密存储(密钥需保存在应用配置,而非数据库)
INSERT INTO appdb.user (id, phone) VALUES (1, AES_ENCRYPT('13800138000', 'app_aes_key_2025'));-- 解密查询
SELECT id, AES_DECRYPT(phone, 'app_aes_key_2025') AS phone FROM appdb.user;

3. 定期备份 + 异地存储(防止数据丢失)

(1)备份策略
  • 全量备份:每日 1 次(使用 mysqldump 或 Percona XtraBackup);
  • 增量备份:每小时 1 次(结合二进制日志 binlog);
  • 备份文件加密存储(如用 gpg 加密)。
(2)mysqldump 备份示例(Linux)
# 全量备份(含结构+数据,--master-data 记录 binlog 位置,用于增量备份)
mysqldump -u root -p --all-databases --master-data=2 --single-transaction --quick --lock-tables=false > full_backup_$(date +%Y%m%d).sql# 加密备份文件
gpg -c full_backup_20251113.sql  # 输入密码加密,生成 .gpg 文件# 复制到异地存储(如 FTP/OSS/S3)
scp full_backup_20251113.sql.gpg user@backup-server:/backup/mysql/
(3)关键要求
  • 定期测试恢复流程(确保备份可用);
  • 备份文件保留至少 30 天;
  • 异地存储与生产环境物理隔离。

六、日志与审计加固(追溯安全事件)

1. 启用关键日志

(1)错误日志(记录启动 / 关闭 / 异常错误)
[mysqld]
log-error = /var/log/mysql/mysqld-error.log
log-error-verbosity = 3  # 详细日志级别
(2)慢查询日志(优化性能,间接防范恶意慢查询攻击)
[mysqld]
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2  # 执行时间超过 2 秒的查询记录
log_queries_not_using_indexes = ON  # 记录未使用索引的查询
(3)二进制日志(binlog,用于增量备份 + 操作追溯)
[mysqld]
server-id = 1  # 唯一服务器 ID(主从复制/增量备份必需)
log_bin = /var/log/mysql/mysql-bin  # binlog 存储路径
binlog_format = ROW  # 行级格式(更安全,避免 SQL 注入篡改日志)
expire_logs_days = 7  # binlog 保留 7 天(避免磁盘满)

2. 启用审计日志(MySQL 企业版 / Percona Server)

社区版 MySQL 无内置审计功能,需安装第三方插件(如 audit_log)或使用 Percona Server(内置审计插件):

# Percona Server 审计配置(my.cnf)
[mysqld]
plugin-load-add = audit_log.so
audit_log_file = /var/log/mysql/audit.log
audit_log_format = JSON  # JSON 格式便于分析
audit_log_policy = ALL  # 记录所有操作(可按需调整为 LOGINS/DDL/DML)

3. 日志文件权限保护

# 修改日志目录权限(仅 mysql 用户可读)
chown -R mysql:mysql /var/log/mysql
chmod 700 /var/log/mysql
chmod 600 /var/log/mysql/*

七、配置文件加固(my.cnf/my.ini)

汇总核心加固配置(直接替换或追加到 [mysqld] 段):

[mysqld]
# 基础安全
bind-address = 192.168.1.100
local-infile = 0
symbolic-links = 0  # 禁用符号链接(防止目录遍历攻击)
max_connections = 1000  # 限制最大连接数(防止DoS攻击)
wait_timeout = 600  # 空闲连接超时 10 分钟
interactive_timeout = 600# 密码策略(5.7+)
validate_password_length = 12
validate_password_policy = STRONG
validate_password_special_char_count = 1# SSL 加密(8.0+)
ssl-ca = /etc/mysql/ssl/ca.pem
ssl-cert = /etc/mysql/ssl/server-cert.pem
ssl-key = /etc/mysql/ssl/server-key.pem
require_secure_transport = ON# 数据加密(8.0.16+)
innodb_encrypt_tables = ON
innodb_encrypt_log = ON
early-plugin-load-add = keyring_file.so
keyring_file_data = /var/lib/mysql-keyring/keyring# 日志配置
log-error = /var/log/mysql/mysqld-error.log
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_bin = /var/log/mysql/mysql-bin
binlog_format = ROW
expire_logs_days = 7# 禁用危险功能
disable-log-bin = OFF  # 启用 binlog(前面已配置,此处强调)

八、定期维护与监控

1. 定期安全检查

  • 每月执行 mysql_secure_installation 复查;
  • 每季度扫描 MySQL 漏洞(使用工具如 Nessus、OpenVAS);
  • 每半年更新 MySQL 补丁(关注 Oracle 安全公告)。

2. 监控关键指标

  • 异常登录:监控 Host 为陌生 IP 的登录记录(查询 mysql.general_log 或审计日志);
  • 慢查询 / 大事务:通过 slow.log 或监控工具(如 PMM、Zabbix)预警;
  • 权限变更:定期对比 mysql.user 表,发现未授权的用户 / 权限变更。

3. 应急响应预案

  • 若发现数据泄露:立即禁用可疑账号、切断公网访问、备份当前数据、追溯攻击源;
  • 若遭遇暴力破解:临时封禁攻击 IP(防火墙 / 安全组)、修改所有账号密码、启用二次验证(如结合 PAM 插件)。

总结

MySQL 加固核心是 “最小权限 + 加密传输 + 数据保护 + 审计追溯”,优先完成 mysql_secure_installation、防火墙限制、密码策略、禁用公网监听这 4 项基础操作,再逐步推进 SSL 加密、TDE 存储加密、审计日志等高级防护。

根据业务场景灵活调整(如内网数据库可简化 SSL 配置,但必须限制登录 IP;公网数据库需强制 SSL + 二次验证),定期复查加固效果,确保安全策略持续有效。

http://www.dtcms.com/a/606377.html

相关文章:

  • Go语言编译型特点与应用场景分析 | 探讨Go语言编译型特性及其在实际开发中的应用
  • 辽宁朝阳哪家做网站好产品seo是什么意思
  • 【问题已解决】无法定位程序输入点于XXX动态链接库***.dll上
  • 今天我们开始学习ansible之playbook的简单运用
  • 易语言反编译技术分析与应用
  • 车联网蓝牙测试:经典蓝牙拒绝服务测试.
  • rtaoscfg配置ISR
  • 企业采购平台哪个好宁波seo优化公司排名
  • 国家林业建设工程协会网站企业网站制作排名
  • 搜索引擎网站分析项目管理软件开发案例
  • DeepHunt微服务故障定位系统核心技术解析2
  • 怎么制作单页网站泉州网站排名
  • 【钉钉表单(周/日报)】每天定时发送,实现收集每天信息
  • TpriDatavue 软件架构与功能文档
  • 建设网站弹出后加载不进去360网站怎么建设
  • 熊海CMS v1.0代码审计实战
  • Go语言编译 | Go语言的编译流程与优化技巧
  • 建立网站的正确方法租网站空间
  • 工程公司手机网站公司网站建设合规吗
  • 寒流感双预警,冠心病患者需备威立芯(硝酸甘油舌下片)筑牢心防线
  • 深入理解HTTPS和HTTP的区别、工作原理及安全重要性
  • 重庆网站建设机构网站建设中怎样进入后台
  • [ 项目开发 1.0 ] 新闻网站的开发流程和注意事项
  • ip加端口可以做网站吗wordpress模仿做slider
  • 长沙flash网站制作提升学历选什么专业比较好
  • 文化礼堂建设情况网站微信公众号怎么登录账号
  • 构建AI原生型营销团队的“大脑-神经-肢体”模型
  • Closed-Loop Evaluation in Robotics: A Practical Template (for openvla + LIBERO)
  • 字体文件大小压缩指南
  • 异步IO的其他特性