MySQL-06-安全

MySQL 安全防护需构建 “网络 - 操作系统 - 文件系统 - 用户 - 数据” 五层防御体系

通过加密传输、强密码策略、权限管控、数据加密、防注入等手段

全面抵御窃听、篡改、未授权访问等安全风险。

  1. 识别并防范常见安全攻击(窃听、篡改、回放、拒绝服务等)
  2. 针对网络、密码、操作系统、文件系统、应用程序制定安全防护措施
  3. 保护数据传输与存储安全,避免非法拦截和访问
  4. 配置 SSL/TLS、SSH 等安全连接方式,保障远程访问安全
  5. 加密静态数据(InnoDB 表空间、日志文件),防范数据泄露
  6. 配置企业版防火墙,拦截恶意 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(如需远程连接)

通用网络安全措施

  1. 防火墙管控:严格限制 MySQL 端口(3306)的访问 IP 范围
  2. 绑定网络接口:通过bind-address参数指定 MySQL 仅监听内网 IP,拒绝外网访问
  3. 最小权限原则:MySQL 账号仅授予必要权限,禁止给普通用户分配SUPERFILE等高危权限
  4. 加密传输:所有远程连接强制使用 SSL/TLS,禁止明文传输
  5. 弱密码防护:禁用无密码账号,强制使用复杂密码(字母 + 数字 + 特殊字符)

连接安全(加密传输)

通过 SSL/TLS 或 SSH 隧道保障客户端与服务器之间的数据传输安全。

SSL/TLS 安全连接(推荐)

核心原理

  • 基于 OpenSSL 实现,实际使用更安全的 TLS 协议(MySQL 中仍沿用 SSL 相关配置项)
  • 采用 “非对称加密 + 对称加密” 结合模式:
    1. 客户端发起连接,服务器返回数字证书(含公钥)
    2. 客户端验证证书合法性,生成会话密钥(对称加密密钥)
    3. 客户端用服务器公钥加密会话密钥,发送给服务器
    4. 服务器用私钥解密会话密钥,后续通信通过会话密钥加密

关键配置

  • 服务器端(默认已启用 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
  • 客户端连接选项:

    • 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 加密传输

  • 操作步骤:

    1. 客户端建立 SSH 隧道:

      1
      
      ssh -L 33306:mysql-server-ip:3306 ssh-user@ssh-server-ip
      

      (本地 33306 端口转发到 MySQL 服务器 3306 端口)

    2. 客户端连接本地转发端口:

      1
      
      mysql -u root -p -P 33306 -h 127.0.0.1
      

密码安全

密码是用户身份验证的核心,需通过策略和工具强化防护。

密码验证组件(validate_password)

  • 作用:强制密码复杂度,拒绝弱密码

  • 安装(MySQL 8.0 默认已安装,需启用):

    1
    
    INSTALL 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
    2
    
    SET 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+):修改密码时保留旧密码,平滑过渡:

    1
    
    ALTER 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
    2
    
    chmod 700 /var/lib/mysql
    chown -R mysql:mysql /var/lib/mysql
    
  • 配置文件防护:my.cnf/my.ini 文件权限设置为 600,禁止非授权用户修改

    1
    2
    
    chmod 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';(绕过密码验证)

核心防护措施

  1. 使用参数化查询 / 预处理语句:避免直接拼接用户输入到 SQL 中

    • 示例(预处理语句):

      1
      2
      3
      
      PREPARE stmt FROM 'SELECT * FROM users WHERE username=? AND password=?';
      SET @user='user', @pass='pass';
      EXECUTE stmt USING @user, @pass;
      
  2. 输入验证与过滤:对用户输入的特殊字符(单引号、双引号、分号)进行转义或过滤

  3. 最小权限原则:应用连接 MySQL 的账号仅授予必要权限(如 SELECT、INSERT),禁止DROPALTER等高危权限

  4. 禁用敏感函数:限制LOAD_FILE()INTO OUTFILE等可能泄露文件的函数

  5. 使用 ORM 框架:如 MyBatis、Hibernate,自动处理 SQL 拼接,降低注入风险

8.3 检测与监控

  • 启用一般查询日志或慢查询日志,监控异常 SQL 语句
  • 通过 Performance Schema 跟踪高频执行的异常语句
  • 定期审计应用代码,排查未使用参数化查询的场景

MySQL 企业版防火墙(Enterprise Firewall)

仅 MySQL 企业版提供,通过白名单机制拦截恶意 SQL 操作。

核心功能

  • 基于账号的 SQL 语句白名单:仅允许预定义的 SQL 模式执行
  • 支持记录模式(RECORDING)、防护模式(PROTECTING)、检测模式(DETECTING)
  • 自动归一化 SQL 语句(替换参数为占位符),避免因参数不同误判

配置步骤

  1. 安装防火墙插件(执行企业版安装脚本):

    1
    
    mysql -u root -p < share/linux_install_firewall.sql
    
  2. 注册账号并设置模式:

    • 记录模式(学习合法 SQL):CALL mysql.sp_set_firewall_mode('user@host', 'RECORDING');
    • 防护模式(拦截非法 SQL):CALL mysql.sp_set_firewall_mode('user@host', 'PROTECTING');
  3. 查看防火墙状态:

    1
    2
    
    SELECT * FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS;
    SELECT * FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_WHITELIST;
    
  4. 监控防火墙事件:通过SHOW GLOBAL STATUS LIKE 'Firewall%'查看拦截 / 允许统计

安全审计与监控

  1. 启用审计日志(企业版):记录所有用户连接、SQL 执行操作,便于事后追溯
  2. 定期权限审计:检查 mysql.user、mysql.db 等授权表,回收冗余权限
  3. 监控异常连接:通过 Performance Schema 或 mysqladmin processlist 查看高频连接、异常 IP 连接
  4. 日志审计:定期分析错误日志、二进制日志,排查登录失败、异常 SQL 执行等情况

实践思路

  1. 分层防御:网络层(防火墙 + SSL)→ 系统层(最小账号 + 权限)→ 数据层(加密 + 审计)→ 应用层(防注入 + 参数化查询)
  2. 定期巡检:每月进行安全扫描,检查弱密码、冗余权限、未加密传输等问题
  3. 应急响应:制定安全事件处理流程,如账号泄露后立即锁定账号、修改密码、审计操作日志
  4. 备份与恢复:加密存储备份,定期测试恢复流程,确保数据泄露后可快速恢复
0 次浏览