备份文件被直接下载是因未设访问控制,应移出Web根目录并限制权限;mysqldump不支持原生加密,需用gpg/openssl流式加密;KEYRING插件仅加密运行时表空间,不影响备份明文;自动脚本须严控umask、chmod及rsync权限。

备份文件被直接下载是因为没设访问控制
MySQL 本身不负责备份文件的 Web 访问权限管理,mysqldump 生成的 .sql 文件如果放在 Web 根目录(比如 /var/www/html/backup/),Nginx/Apache 默认会把它当静态资源返回——用户输个 URL 就能直接下载。这不是 MySQL 的漏洞,是部署配置疏漏。
实操建议:
- 把备份目录挪出 Web 根目录,例如改到
/data/backups/或/home/mysql/backups/ - 确认 Web 服务无任何别名(
alias)或重写规则(rewrite)意外暴露该路径 - 用
ls -ld /data/backups/检查目录权限,确保非www-data用户不可读(如700或750配合正确属组)
mysqldump 不支持原生加密,但可以管道加密
mysqldump 本身没有 --encrypt 这类参数,导出内容默认明文。想让备份文件即使泄露也难读,得靠外部工具链在写入磁盘前加密。
常见做法是用 gpg 或 openssl 做流式加密:
mysqldump -u root -p database_name | gzip | gpg --cipher-algo AES256 --symmetric --armor > backup_$(date +%F).sql.asc
注意点:
-
--symmetric表示使用密码而非密钥对,适合运维脚本,但密码必须安全保管(别硬编码在脚本里) -
--armor输出 base64 文本格式,方便传输;若要二进制加密文件,去掉它,后缀改用.gpg - 解密时需手动输入密码:
gpg -d backup_2024-06-01.sql.asc | gunzip | mysql -u root -p database_name
用 MySQL 8.0+ 的 KEYRING 插件加密备份?不行
KEYRING 插件只管 InnoDB 表空间的**运行时加密**(ENCRYPTION='Y'),不影响 mysqldump 输出。哪怕你开了表加密,mysqldump 仍会导出明文 SQL——因为 dump 是从服务器内存/缓冲区读取逻辑数据,不是直接复制加密后的 ibd 文件。
所以:
- 不要指望开启
keyring_file就能保护备份文件 - KEYRING 对备份泄露问题完全不生效,它防的是磁盘被盗后物理文件被拖走解密
- 真正要防备份泄露,还是得回到文件存放位置 + 传输加密 + 访问权限三者配合
自动备份脚本里最容易漏掉的三个权限点
很多定时备份脚本跑在 root 或 mysql 用户下,看似“够权限”,但实际埋了隐患:
- 备份文件创建时继承了执行用户的 umask,默认可能是
0022→ 文件权限变成-rw-r--r--,其他用户可读 - 脚本里用
cp或mv移动备份文件,没加chmod 600修正权限 - 用
rsync推送到远程备份机时,没加--chmod=Go-rwx,导致远端文件仍开放给组/其他用户
最稳妥的做法是在脚本末尾强制加固:
chmod 600 /data/backups/backup_$(date +%F).sql.gz
或者在 crontab 中用 umask 077 开头,让整个上下文默认不放权。
加密和权限不是二选一,而是两道独立防线:权限控制谁能看到文件,加密决定看到后能不能读懂——少一道,风险就翻倍。










