Skip to content

MariaDB 安全最佳实践

数据库安全是企业信息安全的核心组成部分,关系到业务数据的完整性、机密性和可用性。MariaDB 作为广泛使用的开源数据库,其安全性需要从多个层面进行保障。

访问控制最佳实践

1. 用户管理

最小权限原则

  • 仅授予用户完成其工作所需的最小权限
  • 避免使用 ALL PRIVILEGES 权限
  • 定期审查用户权限,回收不必要的权限

用户创建与管理

  • 使用强密码策略

  • 限制用户的访问主机

  • 避免使用默认的 root 用户进行日常操作

  • 创建专用的管理员用户和应用用户

  • 定期清理无用用户和过期用户

  • 示例

sql
-- 创建应用用户,仅允许从指定IP访问
CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'StrongPassword123!';

-- 创建只读用户
CREATE USER 'readonly_user'@'localhost' IDENTIFIED BY 'ReadOnlyPassword456!';

-- 授予最小必要权限
GRANT SELECT, INSERT, UPDATE, DELETE ON ecommerce_db.* TO 'app_user'@'192.168.1.%';
GRANT SELECT ON ecommerce_db.* TO 'readonly_user'@'localhost';

-- 定期清理无用用户
DROP USER IF EXISTS 'old_user'@'localhost';

密码策略

  • 使用复杂密码,包含大小写字母、数字和特殊字符

  • 定期更换密码

  • 禁用弱密码

  • 使用密码过期策略

  • 版本差异

    • MariaDB 10.4+ 支持 caching_sha2_password 插件,提供更安全的密码存储
    • MariaDB 10.1+ 支持密码验证插件 validate_password
  • 配置示例

ini
# my.cnf 配置
[mysqld]
# 启用密码验证插件
plugin_load_add = validate_password.so
validate_password_policy = STRONG
validate_password_length = 12
validate_password_number_count = 2
validate_password_special_char_count = 1

# 密码过期策略(90天)
default_password_lifetime = 90

2. 权限管理

权限类型

  • 全局权限:影响整个 MariaDB 实例
  • 数据库权限:影响特定数据库
  • 表权限:影响特定表
  • 列权限:影响特定列
  • 存储过程/函数权限:影响特定存储过程或函数

权限授予原则

  • 遵循最小权限原则

  • 避免授予 SUPERFILEPROCESS 等敏感权限

  • 限制 GRANT OPTION 权限的使用

  • 定期使用 SHOW GRANTS 检查用户权限

  • 示例

sql
-- 查看用户权限
SHOW GRANTS FOR 'app_user'@'192.168.1.%';

-- 回收权限
REVOKE DELETE ON ecommerce_db.orders FROM 'app_user'@'192.168.1.%';

-- 刷新权限
FLUSH PRIVILEGES;

3. 角色管理

  • 使用角色管理权限,便于统一管理和批量分配

  • 定期审查角色权限

  • 限制角色的创建和分配权限

  • 版本差异:MariaDB 10.0+ 支持角色管理

  • 示例

sql
-- 创建角色
CREATE ROLE 'app_role', 'readonly_role';

-- 授予角色权限
GRANT SELECT, INSERT, UPDATE ON ecommerce_db.* TO 'app_role';
GRANT SELECT ON ecommerce_db.* TO 'readonly_role';

-- 分配角色给用户
GRANT 'app_role' TO 'app_user'@'192.168.1.%';
GRANT 'readonly_role' TO 'readonly_user'@'localhost';

-- 激活角色(MariaDB 10.4+ 默认为自动激活)
SET DEFAULT ROLE ALL TO 'app_user'@'192.168.1.%';

网络安全最佳实践

1. 端口管理

  • 修改默认端口 3306,减少暴力攻击风险

  • 仅监听必要的网络接口

  • 配置 bind-address 参数,限制监听的 IP 地址

  • 配置示例

ini
# my.cnf 配置
[mysqld]
# 修改默认端口
bind-address = 192.168.1.100
port = 3307

2. 防火墙配置

  • 使用防火墙限制对 MariaDB 端口的访问

  • 仅允许信任的 IP 地址访问数据库

  • 配置防火墙规则,拒绝所有未明确允许的访问

  • 示例(Linux iptables):

bash
# 允许来自 192.168.1.0/24 网段的访问
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 3307 -j ACCEPT

# 拒绝其他所有访问
iptables -A INPUT -p tcp --dport 3307 -j DROP

# 保存防火墙规则
service iptables save

3. SSL/TLS 配置

  • 启用 SSL/TLS 加密数据库连接

  • 使用有效证书,避免自签名证书

  • 配置 require_secure_transport 强制使用 SSL 连接

  • 定期更新证书

  • 版本差异

    • MariaDB 10.2+ 支持 TLS 1.3
    • MariaDB 10.3+ 支持加密连接的性能优化
  • 配置示例

ini
# my.cnf 配置
[mysqld]
# SSL/TLS 配置
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
  • 客户端连接示例
bash
mysql --ssl-ca=/etc/mysql/ssl/ca.pem --ssl-cert=/etc/mysql/ssl/client-cert.pem --ssl-key=/etc/mysql/ssl/client-key.pem -u app_user -p -h 192.168.1.100

4. 连接限制

  • 限制最大连接数,防止连接耗尽攻击

  • 配置 max_connections 参数

  • 配置 connect_timeoutwait_timeout 参数,限制连接超时

  • 使用 max_connect_errors 限制失败连接尝试次数

  • 配置示例

ini
# my.cnf 配置
[mysqld]
# 最大连接数
max_connections = 500

# 连接超时(秒)
connect_timeout = 10
wait_timeout = 28800

# 最大连接错误次数
max_connect_errors = 100

数据安全最佳实践

1. 数据加密

传输加密

  • 使用 SSL/TLS 加密数据库连接
  • 配置客户端强制使用 SSL 连接
  • 验证服务器证书,防止中间人攻击

存储加密

  • 表级加密:使用 ENCRYPTED=YES 选项创建加密表

  • 列级加密:对敏感列使用 AES_ENCRYPT()AES_DECRYPT() 函数

  • 透明数据加密(TDE):加密整个数据文件,对应用透明

  • 版本差异

    • MariaDB 10.1+ 支持表级加密
    • MariaDB 10.3+ 支持透明数据加密(TDE)
  • 示例

sql
-- 创建加密表
CREATE TABLE user_secure (
    user_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(64) NOT NULL,
    password_hash VARCHAR(255) NOT NULL
) ENCRYPTED=YES;

-- 列级加密示例
INSERT INTO user_secure (username, password_hash) 
VALUES ('user1', AES_ENCRYPT('password123', 'encryption_key'));

-- 列级解密示例
SELECT username, AES_DECRYPT(password_hash, 'encryption_key') AS password 
FROM user_secure WHERE user_id = 1;

2. 敏感数据保护

数据分类

  • 对数据进行分类,识别敏感数据
  • 根据数据敏感度采取不同的保护措施
  • 常见敏感数据包括:个人身份信息(PII)、财务数据、医疗数据等

数据脱敏

  • 对敏感数据进行脱敏处理,如:

    • 身份证号:显示前6位和后4位,中间用*代替
    • 手机号:显示前3位和后4位,中间用*代替
    • 邮箱:显示用户名前2位和域名,中间用*代替
  • 示例

sql
-- 身份证号脱敏
SELECT CONCAT(SUBSTR(id_card, 1, 6), '********', SUBSTR(id_card, 15, 4)) AS masked_id_card FROM users;

-- 手机号脱敏
SELECT CONCAT(SUBSTR(phone, 1, 3), '****', SUBSTR(phone, 8)) AS masked_phone FROM users;

访问控制

  • 限制敏感数据的访问权限

  • 使用列级权限,仅允许授权用户访问敏感列

  • 记录敏感数据的访问日志

  • 示例

sql
-- 授予列级权限
GRANT SELECT (user_id, username, email) ON users TO 'app_user'@'192.168.1.%';
-- 不授予访问身份证号和手机号的权限

3. 备份安全

  • 遵循 3-2-1 备份原则:3份备份,2种不同介质,1份异地备份

  • 加密备份文件

  • 限制备份文件的访问权限

  • 定期验证备份的可用性

  • 测试恢复流程

  • 示例

bash
# 使用 mariabackup 进行加密备份
mariabackup --backup --target-dir=/backup/full --user=backup --password=backup_password --encrypt=AES256 --encrypt-key-file=/etc/mysql/backup_key

# 限制备份文件权限
chmod 600 /backup/full/*
chown backup:backup /backup/full/*

审计与日志最佳实践

1. 审计日志

启用审计日志

  • 启用 MariaDB 审计日志,记录数据库操作

  • 配置审计日志格式和存储位置

  • 记录关键操作,如用户登录、权限变更、数据修改等

  • 版本差异

    • MariaDB 10.3+ 支持官方审计插件 server_audit
    • 第三方审计插件:Percona Audit Log Plugin、McAfee MySQL Audit Plugin
  • 配置示例

ini
# my.cnf 配置
[mysqld]
# 启用审计插件
plugin_load_add = server_audit.so
server_audit_logging = ON
server_audit_events = CONNECT,QUERY,TABLE,QUERY_DDL,QUERY_DML,QUERY_DCL
server_audit_log_format = JSON
server_audit_file_path = /var/log/mariadb/audit.log
server_audit_file_rotate_size = 1000000
server_audit_file_rotations = 10

审计日志分析

  • 定期分析审计日志,查找异常操作
  • 使用日志分析工具(如 ELK Stack、Splunk)
  • 设置审计日志告警,及时发现安全事件

2. 错误日志

配置错误日志

  • 启用错误日志,记录数据库错误信息

  • 配置错误日志级别和存储位置

  • 定期清理错误日志,避免占用过多磁盘空间

  • 配置示例

ini
# my.cnf 配置
[mysqld]
# 错误日志配置
log_error = /var/log/mariadb/mariadb-error.log
log_warnings = 2

[mysqld_safe]
# 安全模式下的错误日志
log_error = /var/log/mariadb/mariadb-safe-error.log

3. 慢查询日志

配置慢查询日志

  • 启用慢查询日志,记录慢查询语句

  • 配置慢查询阈值,如 2 秒

  • 定期分析慢查询日志,优化查询语句

  • 注意:慢查询日志可能包含敏感数据,需限制访问权限

  • 配置示例

ini
# my.cnf 配置
[mysqld]
# 慢查询日志配置
slow_query_log = ON
slow_query_log_file = /var/log/mariadb/mariadb-slow.log
long_query_time = 2
log_queries_not_using_indexes = ON
log_slow_admin_statements = ON

4. 二进制日志

配置二进制日志

  • 启用二进制日志,用于数据恢复和复制

  • 配置二进制日志格式为 ROW,提供更好的数据恢复能力

  • 定期清理二进制日志,避免占用过多磁盘空间

  • 配置示例

ini
# my.cnf 配置
[mysqld]
# 二进制日志配置
binlog_format = ROW
binlog_row_image = FULL
log_bin = /var/lib/mysql/binlog
expire_logs_days = 7
max_binlog_size = 100M

漏洞管理最佳实践

1. 补丁管理

  • 定期更新 MariaDB 版本,修复已知漏洞

  • 关注 MariaDB 官方发布的安全公告

  • 测试补丁在测试环境中的兼容性

  • 制定补丁更新计划,避免业务高峰期更新

  • 版本选择

    • 使用长期支持(LTS)版本,如 MariaDB 10.6 LTS、MariaDB 10.11 LTS
    • 避免使用已结束生命周期的版本

2. 安全扫描

  • 定期使用安全扫描工具扫描数据库服务器

  • 扫描内容包括:

    • 操作系统漏洞
    • 数据库配置漏洞
    • 弱密码
    • 不必要的服务和端口
  • 常用扫描工具

    • Nessus
    • OpenVAS
    • MariaDB Enterprise Security
    • Percona Toolkit

3. CVE 响应

  • 关注 MariaDB 官方发布的 CVE 信息

  • 及时评估 CVE 对系统的影响

  • 制定 CVE 修复计划

  • 优先修复高危 CVE

  • 示例

bash
# 使用 MariaDB 官方工具检查 CVE
mysql_secure_installation

# 或使用 Percona Toolkit 检查
pt-secure-collect

4. 安全加固

  • 运行 mysql_secure_installation 脚本,进行基本安全加固

  • 移除匿名用户

  • 禁用远程 root 登录

  • 移除测试数据库

  • 刷新权限表

  • 示例

bash
# 运行安全加固脚本
mysql_secure_installation

操作安全最佳实践

1. 最小权限原则

  • 所有操作都应遵循最小权限原则
  • 管理员用户仅用于管理操作,不用于日常业务操作
  • 应用用户仅用于应用访问,不用于管理操作

2. 变更管理

  • 所有数据库变更都应遵循变更管理流程
  • 变更前进行风险评估
  • 变更前进行备份
  • 测试变更在测试环境中的效果
  • 选择业务低峰期执行变更
  • 记录变更过程和结果

3. 应急响应

  • 制定数据库安全应急响应计划
  • 建立应急响应团队
  • 定期进行应急演练
  • 及时响应安全事件
  • 记录安全事件的处理过程

4. 安全培训

  • 对数据库管理员和开发人员进行安全培训
  • 培训内容包括:
    • MariaDB 安全配置
    • SQL 注入防护
    • 数据保护
    • 安全最佳实践

云环境下的安全最佳实践

1. 云服务选择

  • 选择可靠的云服务提供商
  • 评估云服务的安全特性,如:
    • 数据加密
    • 访问控制
    • 审计日志
    • 漏洞管理

2. 云环境配置

  • 配置云安全组,限制对数据库的访问
  • 使用云提供商的密钥管理服务(KMS)管理加密密钥
  • 启用云提供商的数据库审计服务
  • 配置云备份服务,确保数据安全

3. 云迁移安全

  • 迁移过程中确保数据加密
  • 验证迁移后的数据完整性
  • 调整云环境的安全配置
  • 测试云环境的安全特性

常见问题 (FAQ)

Q: 如何确保 MariaDB 密码安全?

A: 密码安全建议:

  1. 使用强密码,包含大小写字母、数字和特殊字符
  2. 定期更换密码
  3. 启用密码验证插件 validate_password
  4. 配置密码过期策略
  5. 避免在代码中硬编码密码
  6. 使用密钥管理服务(KMS)存储密码

Q: 如何防止 SQL 注入攻击?

A: 防止 SQL 注入建议:

  1. 使用参数化查询,避免直接拼接 SQL 语句
  2. 输入验证,对用户输入进行严格验证
  3. 限制数据库用户权限,遵循最小权限原则
  4. 使用存储过程,减少直接 SQL 执行
  5. 启用 MariaDB 防火墙,如 MariaDB Firewall

Q: 如何配置 MariaDB 审计日志?

A: 审计日志配置:

  1. 安装审计插件:INSTALL PLUGIN server_audit SONAME 'server_audit.so';
  2. 配置审计日志参数,如 server_audit_logging, server_audit_events, server_audit_log_format
  3. 重启 MariaDB 服务
  4. 检查审计日志是否正常记录

Q: 如何处理 MariaDB 安全漏洞?

A: 安全漏洞处理:

  1. 及时关注 MariaDB 官方发布的安全公告
  2. 评估漏洞对系统的影响
  3. 制定漏洞修复计划
  4. 测试补丁在测试环境中的兼容性
  5. 选择业务低峰期应用补丁
  6. 验证补丁应用效果

Q: 如何确保备份数据的安全?

A: 备份数据安全建议:

  1. 加密备份文件
  2. 限制备份文件的访问权限
  3. 遵循 3-2-1 备份原则
  4. 定期验证备份的可用性
  5. 测试恢复流程
  6. 存储备份文件到安全位置

Q: 如何配置 SSL/TLS 加密?

A: SSL/TLS 配置步骤:

  1. 生成或获取 SSL 证书
  2. 配置 MariaDB 使用 SSL 证书
  3. 重启 MariaDB 服务
  4. 配置客户端使用 SSL 连接
  5. 验证 SSL 连接是否正常

Q: 如何限制 MariaDB 的网络访问?

A: 网络访问限制建议:

  1. 配置 bind-address 参数,限制监听的 IP 地址
  2. 修改默认端口 3306
  3. 使用防火墙限制对数据库端口的访问
  4. 仅允许信任的 IP 地址访问数据库
  5. 启用 SSL/TLS 加密连接

Q: 如何进行 MariaDB 安全审计?

A: 安全审计步骤:

  1. 启用审计日志
  2. 定期分析审计日志
  3. 使用安全扫描工具扫描数据库服务器
  4. 检查用户权限,回收不必要的权限
  5. 检查数据库配置,确保符合安全最佳实践
  6. 测试数据恢复流程

总结

MariaDB 安全是一个持续的过程,需要从多个层面进行保障。通过遵循本文介绍的安全最佳实践,可以有效提高 MariaDB 数据库的安全性,保护业务数据的完整性、机密性和可用性。

安全最佳实践包括:

  1. 访问控制:用户管理、权限管理、角色管理、密码策略
  2. 网络安全:端口管理、防火墙配置、SSL/TLS 配置、连接限制
  3. 数据安全:数据加密、敏感数据保护、备份安全
  4. 审计与日志:审计日志、错误日志、慢查询日志、二进制日志
  5. 漏洞管理:补丁管理、安全扫描、CVE 响应、安全加固
  6. 操作安全:最小权限原则、变更管理、应急响应、安全培训
  7. 云环境安全:云服务选择、云环境配置、云迁移安全

安全是一个持续改进的过程,需要定期评估和更新安全策略,适应不断变化的安全威胁。同时,加强团队的安全意识和培训,提高整体安全水平。