MySQL备份必须用gpg或openssl流式加密,禁用明文落地;等保三级要求静态加密,密钥须与备份物理隔离并严格管理。

备份必须先加密再传输,不能依赖MySQL内置参数
MySQL本身不提供备份文件加密能力,mysqldump或xtrabackup输出的文件默认是明文。等保三级明确要求“备份数据静态存储时须加密”,只靠--ssl参数加密传输链路远远不够——传输途中加密,落地后解密存盘,等于没加。
实操上必须用外部工具在备份流中直接加密,或对已生成的备份文件立即加密。常见错误是把mysqldump --ssl当成合规动作,结果审计时看到backup_20260701.sql文件可直接head -n5读出表结构和数据,直接一票否决。
- 优先选
gpg:支持AES256对称加密且有成熟密钥管理生态 - 次选用
openssl enc -aes-256-cbc -pbkdf2:系统自带,但需确保-pbkdf2参数存在(旧版OpenSSL可能不支持) - 禁用
-k明文传密钥:比如openssl enc -k 'mypass' ...会把密码写进bash history和ps aux,等保现场会被扣分
gpg对称加密必须交互输密,自动化要用安全管道
直接运行mysqldump | gpg --symmetric会阻塞等待键盘输入,无法放进crontab。但硬编码密码到脚本里(如echo "pass" | gpg --batch --passphrase-fd 0)也不行——密码会留在进程参数里,ps可见。
正确做法是让密钥从受控渠道注入:
- 用
gpg --batch --passphrase-fd 0配合systemd-ask-password或HashiCorp Vault的vault read -field=backup_key输出 - 若用文件存密钥,该文件权限必须是
600且属主为非root独立用户(如backup),不能放在/tmp或/var/lib/mysql下 - 示例安全命令:
mysqldump -u backup_user db1 | gpg --cipher-algo AES256 --symmetric --armor --batch --passphrase-fd 0
加密后必须立刻删原始明文,且用shred而非rm
哪怕只存在1秒,未加密的.sql或.xbstream文件被扫描到就违规。普通rm只是删目录项,磁盘块内容还在,恢复工具能轻易还原。
等保检查会用strings /dev/sdb1 | grep -i "CREATE TABLE"扫磁盘裸区,所以必须用覆写删除:
-
shred -u backup.sql:默认覆写3遍,符合GB/T 25069-2010《信息安全技术 术语》要求 - 对gzip包:
gzip -c data.sql | gpg --symmetric > data.sql.gz.gpg && shred -u data.sql data.sql.gz - 注意:
shred对SSD或log-structured文件系统(如btrfs、zfs)效果有限,此时应配合全盘加密或使用支持TRIM的擦除工具
密钥管理比算法选择更关键
用AES256还是ChaCha20不是重点,等保不卡具体算法——它卡的是“密钥是否与备份文件物理隔离”。曾有案例:密钥文件和备份同存S3桶,且IAM策略允许同一角色读两者,测评时被判定为“密钥未分离”。
必须做到:
- 备份加密密钥不得存于数据库服务器本地,也不能和备份文件放同一云存储路径
- 若用KMS,调用
Decrypt权限必须限定到特定备份还原脚本的IAM Role,不能给整个EC2实例Profile - 每次备份记录使用的密钥标识(如GPG key ID或KMS key ARN),写入
backup_meta表,方便追溯和轮换审计
真正容易被忽略的是密钥生命周期——没人规定必须换密钥,但等保要求“密钥泄露风险可控”,意味着你得能说清:这个密钥用了多久、谁有权访问、上次审计是什么时候。没文档,就是没管理。


















