背景 服务器每天 03:00 自动备份,产出业务包 + GPG 加密的 secrets 包。看起来挺完善------直到某天想到一个问题:
如果整台服务器被删了、被黑了、硬盘坏了,备份还在吗?
不在。因为备份包就在同一台机器上。
原因 这是备份的经典盲点:同机备份只能防"误删文件",不能防"整机丢失"。
要真正安全,备份必须在物理隔离的另一台设备上。
解决:Windows 主动拉取方案 为什么是"电脑拉"而不是"服务器推" 家里电脑不是 24 小时开机,服务器推过去没人接。反过来让电脑主动来取,最现实。
服务器端:建专用只读用户
bash
# 1. 建用户
sudo useradd -m -s /bin/bash backup_reader
# 2. 放公钥,加 4 项限制
sudo mkdir -p /home/backup_reader/.ssh
sudo tee /home/backup_reader/.ssh/authorized_keys > /dev/null <<'EOF'
no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 <YOUR_PUBLIC_KEY> backup-reader
EOF
sudo chown -R backup_reader:backup_reader /home/backup_reader/.ssh
sudo chmod 700 /home/backup_reader/.ssh
sudo chmod 600 /home/backup_reader/.ssh/authorized_keys
# 3. 用 ACL 开一扇窗(只允许穿过,不允许列目录)
sudo apt install -y acl
sudo setfacl -m u:backup_reader:x /home/user
这四行 no- 限制是什么意思?*
这四行限制写在公钥前面,作用是把 backup_reader 这个账号锁死成"只会拉文件"的机器人,防止它被当成跳板干别的事:
| 限制项 | 作用 |
|---|---|
no-pty |
不许开交互终端,登录后拿不到 shell |
no-port-forwarding |
不许当隧道,不能把服务器端口转发出去 |
no-X11-forwarding |
不许传图形界面,X11 转发被禁用 |
no-agent-forwarding |
不许转发密钥,防止用它去登录别的机器 |
合起来:只能取件,不能干别的。
Windows 端:任务计划自动拉
bash
# 每天 4:00
$Action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NoProfile -ExecutionPolicy Bypass -File C:\pull_backup.ps1"
$Trigger = New-ScheduledTaskTrigger -Daily -At 4:00AM
Register-ScheduledTask -TaskName "PullBackup" -Action $Action -Trigger $Trigger
# 登录后 5 分钟(防止关机错过 4:00)
$Trigger2 = New-ScheduledTaskTrigger -AtLogOn
$Trigger2.Delay = "PT5M"
Register-ScheduledTask -TaskName "PullBackupOnLogon" -Action $Action -Trigger $Trigger2
拉取脚本核心逻辑
javascript
$Key = "$HOME\.ssh\backup_reader_ed25519"
$Server = "backup_reader@SERVER_IP"
$RemoteDir = "/home/user/backups"
function Pull-Latest($Pattern) {
$remote = ssh -i $Key $Server "ls -t $RemoteDir/$Pattern 2>/dev/null | head -1"
$name = Split-Path $remote.Trim() -Leaf
scp -i $Key "${Server}:$remote" "$HOME\backups_offsite\$name"
}
Pull-Latest "business_*.tar.gz"
Pull-Latest "secrets_*.tar.gz.gpg"
验证效果 模拟整机丢失:
只拿 Windows 本地的 business_.tar.gz + secrets_.tar.gz.gpg + 密码
在没有服务器的情况下解密 secrets 包
解开业务包,能看到 dashboard 代码、数据库 dump、Kuma 数据
全部能恢复。 这就是异地备份的价值。 三个坑 坑 1:ACL 不是 chmod
setfacl -m u:backup_reader:x 只给"穿过"权限,不给"列目录"。这样备份用户能按名字取文件,但逛不了整个家目录。
如果你用了 chmod o+x,那全世界都能穿过,太开放。ACL 是精确到"某一个人"的。
坑 2:CRLF 让 GPG 解密失败
Windows 写密码文件时如果用 Set-Content,会多一个 \r,GPG 说"密码错误"。用 WriteAllText 解决。
坑 3:单一触发时间会错过
只设"每天 4:00",但电脑经常关机。加一个"登录后 5 分钟"触发,双保险。