Redis RDB文件默认明文存储,官方不支持内置加密;生产环境唯一可行方案是用inotifywait监听RDB落盘完成事件后调用gpg加密,并需定期验证解密恢复流程。
Redis 官方从未实现 RDB 文件的内置加密(如 AES 密封、密钥派生等),save 或 bgsave 生成的 dump.rdb 始终是明文二进制。指望配置项如 requirepass 或 tls-cert-file 保护 RDB 是无效的——它们只管连接和传输,不管磁盘文件内容。
因此,真正可行的路径只有两条:一是让 RDB 文件写入前就被加密(需修改 Redis 源码,不推荐);二是利用 save 后的 hook 机制,在文件写完但尚未被覆盖前,用外部工具加密它。后者是生产环境唯一稳定、可审计、免编译的方案。
save 和 bgsave 成功后会触发 config set notify-keyspace-events?不,这个和 RDB 无关;它只对 key 事件有效on-rdb-complete 回调,但有 save 命令返回成功 + INFO persistence 中 rdb_last_save_time 可观测,适合轮询判断redis.conf 的 dir 和 dbfilename,监控对应路径下文件的 mtime 变更,再校验 size 是否非零Linux 下最直接的方式是监听 dir 目录中 dbfilename 的写入完成事件。注意:不能监听 CREATE,因为 bgsave 先写临时文件(如 temp-123.rdb),再 rename 覆盖原文件——要捕获的是 MOVED_TO 事件。
inotifywait -m -e moved_to --format '%w%f' /var/lib/redis/ | while read file; do if [[ "$file" == "/var/lib/redis/dump.rdb" ]]; then gpg --batch --yes --passphrase-fd 0 --cipher-algo AES256 -c "$file" < /etc/redis/rdb-passphrase.txt # 加密后保留 .gpg 后缀,原文件可按策略删除或保留 rm "$file" fidone
--batch --yes 避免交互阻塞;--passphrase-fd 0 从 stdin 读密码,避免泄露到 ps aux
echo "xxx" | gpg ...,密码会出现在 shell 历史或进程参数里;改用 cat /path/to/passphrase.txt | gpg ... 或上述重定向方式inotifywait 进程需随 Redis 启动,建议用 systemd service 管理,且设置 Restart=always 防止崩溃漏监dump.rdb.gpg 无法被 Redis 直接加载;恢复时必须先 gpg -d dump.rdb.gpg > dump.rdb,再启动 RedisLUKS 加密的是块设备,只要系统未解锁,RDB 文件在磁盘上就是密文。但它**完全不解决运行时风险**:一旦 root 登录、Redis 进程运行、或备份脚本执行,dump.rdb 在内存和 page cache 中全程明文,且可被 cp、tar、rsync 等任意工具读出。
加密不是目的,可恢复才是。很多团队加密了却忘了验证还原流程,上线后才发现 gpg 版本不兼容、密钥丢失、或解密后文件损坏。
gpg -d dump.rdb.gpg > /tmp/test.rdb && redis-check-rdb /tmp/test.rdb
redis-check-rdb 是 Redis 自带工具,能快速验证 RDB 结构完整性,比启动 Redis 再 info keyspace 更快更安全file dump.rdb.gpg 判断是否加密成功——GPG 加密后仍是二进制,file 输出可能还是 “data”,得靠 gpg --list-packets 看 packet 类型openssl enc 替代 gpg,注意 OpenSSL 1.1.1+ 默认加 salt,但老版本不加;跨环境迁移时,salt 和 IV 处理逻辑必须一致,否则解密失败最常被跳过的一步:没把解密密钥纳入密钥管理系统(如 HashiCorp Vault、AWS KMS),而是硬编码在脚本或文件里。一旦服务器被入侵,加密形同虚设。