rsync 数据备份安全实战:加密备份与恢复演练配置

适用场景

rsync 数据备份安全方案适用于:需要跨服务器异地备份网站数据与数据库、担心备份传输被窃听或备份副本被加密勒索、希望在备份服务器被攻陷后备份本身仍不可读、要求定期做恢复演练验证备份可用性的场景。勒索软件攻击中攻击者的常规动作是先加密或删除备份再勒索,因此备份的加密与隔离设计和备份本身同等重要,本文给出一条可直接落地的 rsync 加密备份与恢复演练路径。

前置条件

  • 两台服务器:生产机(数据源)与备份机(异地),均可 SSH 访问
  • Linux 系统自带 rsync(CentOS/Ubuntu 默认安装),备份机安装 gpg 用于静态加密
  • 建议备份机使用独立账号,只授权备份目录的写权限
  • 了解业务数据的每日增量规模,用于规划 cron 时间窗口

原理说明

本方案分三层保障:第一层是传输加密,rsync 通过 ssh 通道传输,全程密文,避免 FTP/裸 rsync 端口的明文风险;第二层是静态加密,数据落到备份机前先用 gpg 对归档加密,密钥不存放在备份机上,即使备份机被攻破,攻击者拿到的也只是密文;第三层是拉取模式与权限隔离,由备份机主动拉取(pull)数据,备份机账号对生产机只有只读授权,攻击者攻陷生产机也无法反向删除备份。增量快照用 –link-dest 实现:仅硬链接未变化文件,节省空间的同时保留多天可独立恢复的历史版本。

操作步骤

第一步:配置免密互信并收紧授权

# 在备份机生成专用密钥对
ssh-keygen -t ed25519 -f ~/.ssh/id_backup -N ""
# 上传公钥到生产机
ssh-copy-id -i ~/.ssh/id_backup.pub backup@生产机IP
# 生产机 authorized_keys 加命令限制,仅允许该密钥执行 rsync
# 前缀写入(一行):
command="rsync --server --sender -e . /backup-src/",no-pty,no-port-forwarding ssh-ed25519 AAAA... backup@backup-server

第二步:创建拉取式备份脚本

在备份机创建 /opt/scripts/backup_pull.sh

#!/bin/bash
set -e
DATE=$(date +%F)
YESTERDAY=$(date -d "1 day ago" +%F)
DEST=/backup/web/$DATE
SRC=backup@生产机IP:/data/www/
mkdir -p "$DEST"
# --link-dest 指向昨日快照实现硬链接增量,--delete 同步删除
rsync -az --delete \
  --link-dest=/backup/web/$YESTERDAY \
  -e "ssh -i ~/.ssh/id_backup -p 22" \
  "$SRC" "$DEST/"
# 数据库导出后 gpg 加密落盘(公钥加密,私钥离线保存)
rsync -az -e "ssh -i ~/.ssh/id_backup" \
  backup@生产机IP:/backup/db/dump-$DATE.sql.gz /tmp/
gpg --encrypt --recipient ops@company.com \
  --output /backup/db/dump-$DATE.sql.gz.gpg /tmp/dump-$DATE.sql.gz
shred -u /tmp/dump-$DATE.sql.gz
# 保留 14 天,其余清理
find /backup/web -maxdepth 1 -type d -mtime +14 -exec rm -rf {} \;
chmod 700 /opt/scripts/backup_pull.sh
# 加入 cron,每天 02:30 执行
echo "30 2 * * * root /opt/scripts/backup_pull.sh >> /var/log/backup_pull.log 2>&1" > /etc/cron.d/backup-pull

第三步:配置备份完整性校验

生产机导出数据库时同步生成校验文件,备份机每次拉取后比对:

# 生产机:导出后生成 sha256
sha256sum dump-$(date +%F).sql.gz > dump-$(date +%F).sql.gz.sha256
# 备份机:解密后校验
gpg --decrypt dump-$DATE.sql.gz.gpg | sha256sum
diff <(sha256sum dump-$DATE.sql.gz) dump-$DATE.sql.gz.sha256 && echo OK

第四步:执行恢复演练

恢复演练每月至少一次,验证备份真正可还原:

# 1. 选定最近一次快照恢复到隔离目录(切勿直接覆盖生产目录)
rsync -az /backup/web/$(date +%F)/ /restore-test/web/
# 2. 解密数据库备份并恢复到测试库
gpg --decrypt dump-$DATE.sql.gz.gpg > /tmp/restore.sql.gz
gunzip -c /tmp/restore.sql.gz | mysql -h127.0.0.1 -utest -p test_db
# 3. 抽样比对关键文件
diff -rq /restore-test/web/ /data/www/ | head
# 4. 记录演练日期、恢复耗时、抽样结果,形成台账

配置验证

# 确认 cron 执行记录与日志无报错
tail -20 /var/log/backup_pull.log
# 确认快照目录按日期生成且占用正常
ls -1 /backup/web/ | tail -5
du -sh /backup/web/*
# 确认数据库备份为 gpg 加密格式
file /backup/db/dump-$(date +%F).sql.gz.gpg
# 确认私钥不在备份机上
find / -name "*secret*" -path "*gnupg*" 2>/dev/null

常见问题

FAQ 1:–delete 参数会不会把误删的生产文件同步删掉?

会,–delete 会让备份端与源端完全一致,源端误删会同步到备份。两种缓解方式:先用 –dry-run 预演确认变更清单再正式执行;或保留多天 –link-dest 快照(如本文 14 天),误删发生后从历史快照即可找回,这正是保留多版本快照的价值。

FAQ 2:生产机被入侵后,攻击者能否通过互信密钥反向删除备份?

按本文配置风险已被压缩到最低:备份采用备份机主动拉取模式,生产机上的授权密钥被限制为只读 rsync 命令(authorized_keys 的 command= 前缀),且 gpg 私钥不落备份机。需注意不要在反向(推送)模式下把备份机的写密钥放在生产机,那会让生产机失陷连累备份。

总结

rsync + ssh + gpg 的组合用最小成本实现了传输加密、静态加密、多版本快照与恢复验证的完整备份安全链路。落地要点:拉取模式替代推送、authorized_keys 限定单命令授权、gpg 公钥加密且私钥离线保存、–link-dest 保留 14 天快照、恢复演练月度化并留存台账。备份的价值只有在成功恢复那一刻才成立,演练不可省略。