feat: secure offsite backups

This commit is contained in:
2026-07-19 13:01:20 +08:00
parent 1e01f3295e
commit 21395c19e9
6 changed files with 53 additions and 4 deletions
+16 -2
View File
@@ -13,7 +13,11 @@
- `hub.db`:由正在執行的 SQLite 資料庫建立的一致性備份。
- `uploads.tar.gz`Hub 本機上傳的附件。
每次備份都會執行 SQLite `integrity_check`、驗證附件壓縮檔,並在 `SHA256SUMS` 記錄雜湊。`data/backups/` 已由 Git 排除。
每次備份都會執行 SQLite `integrity_check`、驗證附件壓縮檔,並在 `SHA256SUMS` 記錄雜湊。`data/backups/` 已由 Git 排除。也可隨時執行不改動正式資料的驗證:
```bash
./scripts/verify-backup.sh data/backups/<時間>
```
可設定保留與異地複製(例如掛載的 NAS、加密磁碟或 rclone 掛載點):
@@ -21,6 +25,16 @@
BACKUP_RETENTION_DAYS=30 BACKUP_OFFSITE_DIR=/mnt/nas/mebbling ./scripts/backup.sh
```
若異地目的地可能由他人讀取,使用 `age` 加密。設定加密後,異地只會收到 `backup.tar.gz.age`,本機仍保留可供快速還原的已驗證備份:
```bash
BACKUP_AGE_RECIPIENT=age1你的收件人公鑰 \
BACKUP_RCLONE_REMOTE='remote:bucket/mebbling' \
BACKUP_RETENTION_DAYS=30 ./scripts/backup.sh
```
`BACKUP_RCLONE_REMOTE` 可使用已在主機設定好的 rclone S3、B2、SFTP 等 remote;腳本會在缺少 `age``rclone` 時安全失敗,不會假裝已完成異地備份。加密檔要還原時,先以持有的 age identity 解密並解壓為原本的備份目錄,再使用下列還原命令。請把 `verify-backup.sh` 的成功輸出保留在 cron log 中,作為每日可用性驗證報告;完整還原演練仍應定期在隔離環境執行。
在 WSL 主機安裝每日 03:15 排程:
```bash
@@ -61,7 +75,7 @@ Hub 原生附件預設只接受圖片、PDF、純文字與 Markdown。若要串
## 外部告警
設定 `ALERT_WEBHOOK_URL` 後,Worker 會在同步重試耗盡、或簽章 Webhook 超過 7 天未收到事件時發送告警。支援 Discord incoming webhook 或 ntfy topic URL;同一事件每小時最多通知一次。
設定 `ALERT_WEBHOOK_URL` 後,Worker 會在同步重試耗盡、或簽章 Webhook 超過 7 天未收到事件時發送告警。支援 HTTPS Discord incoming webhook 或 ntfy topic URL;同一事件每小時最多通知一次。告警會保存於 SQLite,失敗時以指數退避重試、最多五次;`/api/metrics``mebbling_alert_deliveries` 可監看最終失敗。
## 監控指標與健康檢查