Bitwarden是比较流行的开源密码管理软件。Vaultwarden是轻量级非官方服务端版本,通常自建服务器都采用这个版本。优势是比官方轻量很多,同时无需付费就可以使用TOTP功能。
自建Vaultwarden后马上面临如何备份问题。虽然Bitwarden密码都是本地保存,只要经常同步即使服务器端失效也不会导致所有密码丢失。但是如果长期使用,考虑到任何服务器和数据都有损毁风险,需要有一个恢复手段。
我采用的是rclone本地挂接onedrive网盘,然后配置自动备份脚本备份到网盘。具体方案如下。
1. 挂载网盘
通过rclone config命令配置onedrive并进行本地挂载。
rclone mount onedrive:/backup/ /mnt/onedrive --allow-non-empty --vfs-cache-mode full --daemon
配置自启动挂载
创建桌面文件
nano ~/.config/autostart/rclone-onedrive.desktop
编辑内容
[Desktop Entry]
Type=Application
Name=Mount OneDrive with rclone
Exec=rclone mount onedrive:/backup/ /mnt/onedrive --allow-non-empty --vfs-cache-mode full --daemon writes &
Terminal=false
Hidden=false
2. 编写自动备份脚本
我最开始是用专业的restic进行备份。但发现会自动创建上百个子目录,很影响网盘性能,而且备份文件查看也不直观。于是改回用最简单的tar打包备份。考虑到备份到公网网盘,虽然数据库文件有主密码加密,依然有被暴力破解风险,于是增加了打包加密,采用GPG加密。
Vaultwarden的核心是sqlite数据库,为了保证数据一致性,我采用sqlite3先热备数据库,然后打包。另外需要备份用于加解密的rsa_key.pem,因为不常变化,采用手工备份,不纳入自动备份计划。密码附件文件保存在/vw-data/attachments目录,如果用到也需要纳入备份计划。
备份计划每天一个日备份,保存在daily目录,保留30份,循环覆写。每个月一个月备份,保存在monthly目录,保留12份,循环覆写。
脚本文件如下:
#!/bin/bash
# 定义路径
DATA_DIR="/vw-data"
BACKUP_DIR="/mnt/onedrive"
DAILY_BACKUP_DIR="${BACKUP_DIR}/daily"
MONTHLY_BACKUP_DIR="${BACKUP_DIR}/monthly"
WORK_DIR="${BACKUP_DIR}/work"
DATE=$(date +%Y%m%d)
DAILY_BACKUP_RETENTION=30
MONTHLY_BACKUP_RETENTION=12
# 定义加密密码
GPG_PASSPHRASE="your_secret_passphrase_here" # 你的加密密码
# 确保目标目录存在
mkdir -p "$DAILY_BACKUP_DIR" "$MONTHLY_BACKUP_DIR" "$WORK_DIR"
# Step 1: 执行SQLite3热备份
sqlite3 "${DATA_DIR}/db.sqlite3" ".backup '${WORK_DIR}/db_${DATE}.sqlite3'"
# Step 2: 打包备份文件
tar -czf "${WORK_DIR}/backup_${DATE}.tar.gz" -C "${WORK_DIR}" "db_${DATE}.sqlite3"
# Step 3: 加密备份文件
echo "$GPG_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 --symmetric --cipher-algo AES256 --output "${DAILY_BACKUP_DIR}/backup_${DATE}.tar.gz.gpg" "${WORK_DIR}/backup_${DATE}.tar.gz"
# Step 4: 删除临时文件
rm "${WORK_DIR}/db_${DATE}.sqlite3" "${WORK_DIR}/backup_${DATE}.tar.gz"
# Step 5: 每月备份逻辑(每月第一天执行)
if [ "$(date +%d)" -eq 1 ]; then
cp "${DAILY_BACKUP_DIR}/backup_${DATE}.tar.gz.gpg" "${MONTHLY_BACKUP_DIR}/"
fi
# Step 6: 保留最近的30份每日备份
cd "${DAILY_BACKUP_DIR}"
ls -tp | grep -v '/$' | tail -n +$((${DAILY_BACKUP_RETENTION}+1)) | xargs -I {} rm -- {}
# Step 7: 保留最近12个月的备份
cd "${MONTHLY_BACKUP_DIR}"
ls -tp | grep -v '/$' | tail -n +$((${MONTHLY_BACKUP_RETENTION}+1)) | xargs -I {} rm -- {}
修改备份脚本权限。因为包含加密密钥,需要取消其他用户及组任何权限,同时保证当前用户有执行权限。
chmod 700 /path/to/backup.sh
创建定时任务每天凌晨2点自动备份。
0 2 * * * /path/to/backup.sh
可以手动运行一次,去onedrive目录看备份文件是否如预期生成。如果服务器重启注意看一下rclone是否正常挂载网盘。