保护您的数据库的7大MySQL安全最佳实践
七项实用的MySQL安全检查,涵盖访问控制、网络暴露、TLS、补丁管理、日志记录和加密。
保护数据库的7大MySQL安全最佳实践
MySQL安全始于减少可连接的用户、限制其操作权限,并降低主机被攻破后的暴露风险。以下七项检查为生产数据库提供了实用的基线,而非声称单一设置就能让MySQL“安全”。
1. 安全用户访问管理
控制谁能访问数据库以及他们能做什么是第一道防线。这包括根据最小权限原则创建特定用户账户,即用户仅拥有执行任务所需的权限。
创建强账户
避免共享应用用户和弱密码。在自管理服务器上使用 mysql_secure_installation 删除匿名用户、移除测试数据库(如适用),并收紧初始root账户设置。
授予最小权限
使用 GRANT 语句指定应用所需的数据库、表和操作。避免为应用账户授予 ALL PRIVILEGES。
示例:
CREATE USER 'webapp_user'@'10.0.10.%' IDENTIFIED BY 'use-a-real-secret-here';
GRANT SELECT, INSERT, UPDATE ON mydatabase.* TO 'webapp_user'@'10.0.10.%';
在正常的 CREATE USER 或 GRANT 语句后无需执行 FLUSH PRIVILEGES。MySQL会自动更新这些语句的授权表。
定期审计账户:
SELECT user, host, account_locked FROM mysql.user ORDER BY user, host;
SHOW GRANTS FOR 'webapp_user'@'10.0.10.%';
2. 限制网络访问
限制MySQL的网络路径。有效默认值取决于MySQL版本和软件包,因此请检查运行中的服务器,而非假设它仅监听本地。
检查监听端口:
ss -ltnp | grep 3306
当仅本地客户端需要访问时,将MySQL绑定到localhost:
[mysqld]
bind-address = 127.0.0.1
如果应用服务器远程连接,则绑定到私有接口,并使用安全组、防火墙或网络ACL仅允许这些源访问端口 3306。
3. 使用TLS加密连接
加密传输中的数据可防止窃听和中间人攻击。MySQL支持客户端-服务器连接的SSL/TLS加密。
服务器配置通常如下:
[mysqld]
ssl-ca=/path/to/ca.pem
ssl-cert=/path/to/server-cert.pem
ssl-key=/path/to/server-key.pem
客户端示例:
mysql -h your_host -u your_user -p --ssl-mode=REQUIRED
如需更严格的验证,请使用 --ssl-mode=VERIFY_IDENTITY,并确保主机名与证书匹配。REQUIRED 会加密连接,但不会强烈验证服务器身份。
4. 保持MySQL更新
软件漏洞经常被发现并修复。运行过时的MySQL版本可能使数据库暴露于已知漏洞。
跟踪您运行的发布流,应用安全更新,并在生产环境前在预发布环境中测试升级。如果使用托管数据库服务,请审查提供商的维护策略,并设置团队实际关注的维护窗口。
5. 强化MySQL服务器配置
除网络绑定外,其他配置选项也能增强安全性。
除非应用需要 LOAD DATA LOCAL INFILE,否则禁用 local_infile:
[mysqld]
local_infile = 0
确保配置文件、TLS密钥和备份凭据仅对适当的系统用户可读。同时检查已安装的插件,移除不使用的插件。
6. 审计和监控日志
日志记录对于检测可疑活动以及安全事件后的取证分析至关重要。
MySQL Enterprise包含审计日志插件。社区部署通常根据环境使用操作系统日志、错误日志、代理日志、云数据库审计功能或第三方审计插件。
至少监控:
- 失败的登录和身份验证错误。
- 新用户、权限变更和特权语句。
- 来自意外主机的连接。
- 备份作业失败和恢复测试失败。
除非有特定的短期故障排除需求,否则不要在繁忙的生产服务器上启用通用查询日志。它可能产生大量I/O并捕获敏感的查询值。
7. 保护静态数据
SSL/TLS保护传输中的数据,而加密静态数据可在底层存储被攻破时提供保护。
使用存储或卷加密作为广泛基线。对于敏感字段,考虑应用层加密,这样数据库就不必持有解密数据所需的所有信息。
MySQL还提供加密函数,如 AES_ENCRYPT() 和 AES_DECRYPT(),但不要将密钥硬编码在SQL中或将其与数据一起存储。
简化示例:
UPDATE users
SET sensitive_data = AES_ENCRYPT('user_private_info', @encryption_key)
WHERE user_id = 1;
SELECT AES_DECRYPT(sensitive_data, @encryption_key)
FROM users
WHERE user_id = 1;
对于实际系统,请使用适当的密钥管理流程。没有密钥轮换、访问控制和密钥材料备份的加密,可能将可恢复的事件转变为永久性数据丢失。
总结
从消除最多风险的控件开始:最小权限用户、私有网络访问、TLS、补丁管理和经过测试的备份。然后添加符合合规性和威胁模型的审计日志和加密控制。每次重大架构、基础设施或访问变更后,请重新审查设置。