真诚友善团结专业,共建你我引以为荣之社区。《常见问题解答》
❤️ 再忍不住,也不要做这种事啊 ❤️
阅读时间 6 分钟
1 / 80
2024 年 10月

在ChatGPT的辅助下完成了自建vaultwarden,多次修改后终于有个能用的了,具体操作有:

  • 容器采用目录挂载方式启动,这样方便备份和更新
  • 保留90天备份,将整个挂载目录压缩加密备份,每天5点自动备份到onedrive
  • 备份使用GPG加密存储
    • 其实本地密码文件本身是加密存储的,但是配置文件会泄露一点信息,故我再次加密
  • 每天自动检测vaultwarden镜像是否有更新,有的话自动更新并启动(有佬推荐使用watchower自动更新镜像)

  • 实现这些需要的:
    • 一台vps
    • 一个域名,这个域名解析到你的vps上, 本文假设域名为 my.com

  • 服务器或VPS挂了怎么办:
    • vaultwarden支持离线使用,密码在本地会存一份,即使bitwarden插件现在连不上VPS也可以继续使用密码
    • 本地存的那份密码可以导出

  • bitwarden官方不是有自己的镜像吗? 为什么要使用vaultwarden?
    • bitwarden官方占用比vaultwarden大,如果你的VPS空间紧张,那vaultwarden很适合你


目录结构

为组织脚本和相关文件,建议使用以下目录结构:

/vaultwarden_backup/ ├── admin_token_hash ├── backup │ ├── backup_2024-10-19.tar.gz.gpg │ ├── backup_2024-10-20.tar.gz.gpg │ ├── backup_2024-10-21.tar.gz.gpg │ ├── backup_2024-10-22.tar.gz.gpg │ └── backup_2024-10-24.tar.gz.gpg ├── backup.log ├── backup_update_script.sh └── gpg_passphrase_file
文件名 描述
admin_token_hash 保存 Vaultwarden 后台密码 Hash
backup 存放每天自动备份文件
backup.log 存放脚本 backup_update_script.sh 执行时输出的日志
backup_update_script.sh 自动备份和镜像更新脚本
gpg_passphrase_file GPG 加密文件

环境准备

1. 必要工具

确保您的系统已经安装以下工具:

  • Docker:用于运行 Vaultwarden。
  • Rclone:用于将备份文件上传到 OneDrive。
  • GPG:用于加密备份文件。
  • Argon2:用于生成 ADMIN_TOKEN 的哈希值。
  • Cron:用于定时执行备份和更新脚本。
sudo apt update sudo apt install docker.io rclone gpg argon2 sudo systemctl start docker sudo systemctl enable docker

在远程Linux服务器上安装并配置rclone (配置rclone流程我记不清了,这个是我找的)

1 安装rclone

如果你的Linux服务器还没有安装rclone,可以按照以下步骤安装:

  1. 通过SSH连接到你的远程Linux服务器。

  2. 运行以下命令来下载并安装rclone

    curl https://rclone.org/install.sh | sudo bash
  3. 安装完成后,可以通过以下命令确认安装是否成功:

    rclone version

2 初始化rclone配置

  1. 运行rclone config命令启动配置过程:

    rclone config
  2. 输入n来创建一个新的remote。

  3. 输入remote的名称(例如onedrive

  4. 继续按提示操作,直到要求进行OAuth认证的步骤。

在这一步,通常rclone会自动打开浏览器来完成OAuth认证,但由于我们是在远程服务器上,这就需要在本地的Windows机器上进行认证。

在本地Windows机器上完成OAuth认证

1 获取认证URL

  1. rclone提示你需要在浏览器中打开一个URL来完成认证时,它会输出一个类似于下面的链接:

    https://accounts.google.com/o/oauth2/auth?client_id=XXXXXXX&response_type=code&scope=XXXXX
  2. 复制这个链接,你需要将它复制到本地的机器。

2 在Windows机器上打开浏览器并完成认证

  1. 在本地Windows电脑上,打开浏览器,并粘贴刚才从远程服务器上复制的OAuth认证URL。

  2. 按照浏览器中的指示进行登录,并授权rclone访问你的云存储账户。

  3. 完成认证后,浏览器将返回一个包含认证代码的页面。这时候会显示一段长的代码。

3 将认证代码粘贴回远程Linux服务器

  1. 复制认证完成后页面中显示的授权代码。

  2. 回到你连接远程Linux服务器的终端,在rclone提示你输入认证代码的地方,粘贴该代码并按回车。

完成rclone配置

  1. 继续完成后续的配置。通常是选择默认值(除非你有其他自定义需求),然后保存并退出。

  2. 你可以通过以下命令测试配置是否成功(以Google Drive为例):

    rclone lsd onedrive:vaultwarden_backup

    如果能够列出你的云存储目录结构,说明配置成功。
    如果目录不存在,可以手动创建:

    rclone mkdir onedrive:vaultwarden_backup

配置GPG

1:生成一个随机密码

我们可以使用 opensslpwgen 生成一个强密码:

# 使用 openssl 生成随机密码 openssl rand -base64 32 > /vaultwarden_backup/gpg_passphrase_file # 确保文件权限是 600 chmod 600 /vaultwarden_backup/gpg_passphrase_file

这样会在 /vaultwarden_backup/gpg_passphrase_file 中生成一个 32 字节的随机密码,并设置为仅当前用户可读。


2:安装 GPG

如果你的系统上还没有 GPG,请进行安装:

sudo apt update sudo apt install gnupg -y

3:使用 GPG 创建加密测试文件

你可以测试一下这个 GPG 密码文件是否正常工作:

# 读取生成的密码到变量 GPG_PASSPHRASE=$(< /vaultwarden_backup/gpg_passphrase_file) # 创建一个测试文件 echo "This is a test backup file." > test_file.txt # 使用 GPG 加密测试文件 gpg --batch --yes --symmetric --cipher-algo AES256 --passphrase "$GPG_PASSPHRASE" -o test_file.txt.gpg test_file.txt # 检查是否生成了加密文件 ls test_file.txt.gpg

4:解密文件测试

确保可以使用相同的密码文件解密:

# 解密文件 gpg --batch --yes --passphrase "$GPG_PASSPHRASE" -o decrypted_test_file.txt -d test_file.txt.gpg # 检查解密结果 cat decrypted_test_file.txt

5:清理测试文件

如果一切正常,可以删除测试文件:

rm test_file.txt test_file.txt.gpg decrypted_test_file.txt

注意事项

  1. 文件权限:确保 /vaultwarden_backup/gpg_passphrase_file 的权限是 600,以保证安全:
    chmod 600 /vaultwarden_backup/gpg_passphrase_file
  2. 备份密码文件:将该密码文件妥善保存(例如在安全的地方备份),因为如果丢失,将无法解密备份文件。可以存到onedrive的保险库中.

生成 ADMIN_TOKEN 的哈希值

Vaultwarden 官方推荐使用 argon2 生成 ADMIN_TOKEN 的哈希值。请按照以下步骤操作:

生成哈希值并保存

使用以下命令生成 ADMIN_TOKEN 的哈希值,并将其保存到 /vaultwarden_backup/admin_token_hash 文件中:

# 替换 "123456789" 为您实际的管理员密码 echo -n "123456789" | argon2 "$(openssl rand -base64 32)" -e -id -k 65540 -t 3 -p 4 > /vaultwarden_backup/admin_token_hash # 设置文件权限,确保只有授权用户可以读取 sudo chmod 600 /vaultwarden_backup/admin_token_hash

示例输出(保存在 /vaultwarden_backup/admin_token_hash 文件中):

$argon2id$v=19$m=65540,t=3,p=4$bXBGMENBZUVzT3VUSFErTzQzK25Jck1BN2Z0amFuWjdSdVlIQVZqYzAzYz0$T9m73OdD2mz9+aJKLuOAdbvoARdaKxtOZ+jZcSL9/N0

注意:将 "123456789" 替换为您的实际管理员密码,确保密码足够强壮。

备份和镜像更新脚本

1. 设置备份目录和权限

确保备份目录存在,并设置正确的权限:

sudo mkdir -p /vaultwarden_backup sudo chmod -R 700 /vaultwarden_backup

2. 完整备份与更新脚本

将以下脚本保存为 /vaultwarden_backup/backup_update_script.sh,并赋予可执行权限。

#!/bin/bash # ================== 配置部分 ================== BACKUP_DIR="/vaultwarden_backup/backup" # 本地备份存储路径 SOURCE_DIR="/VM_data" # 需要备份的源目录 REMOTE="onedrive:vaultwarden_backup" # rclone 远程 OneDrive 目录 DATE=$(date +"%Y-%m-%d") # 当前日期 BACKUP_FILE="backup_$DATE.tar.gz" # 备份文件名 GPG_FILE="$BACKUP_FILE.gpg" # 加密后的备份文件名 GPG_PASSPHRASE_FILE="/vaultwarden_backup/gpg_passphrase_file" # GPG 加密密码文件 RETENTION_DAYS=90 # 保留的天数 LOG_FILE="/vaultwarden_backup/backup_update_script.log" # 日志文件 # Docker 配置 IMAGE_NAME="vaultwarden/server:latest" # 镜像名称 CONTAINER_NAME="vaultwarden" # 容器名称 # 日志函数 log() { echo "$(date +"%Y-%m-%d %H:%M:%S") - $1" | tee -a $LOG_FILE } # 检查 GPG 密码文件是否存在 if [ ! -f "$GPG_PASSPHRASE_FILE" ]; then log "GPG 密码文件不存在,备份终止" exit 1 fi # 读取 GPG 密码 GPG_PASSPHRASE=$(< "$GPG_PASSPHRASE_FILE") # 创建备份 log "开始备份" if tar -czf "$BACKUP_DIR/$BACKUP_FILE" -C "$SOURCE_DIR" .; then log "备份文件已创建: $BACKUP_FILE" else log "备份失败" exit 1 fi # GPG 加密 if gpg --batch --yes --passphrase "$GPG_PASSPHRASE" -c "$BACKUP_DIR/$BACKUP_FILE"; then log "备份文件已加密: $GPG_FILE" else log "加密失败,备份终止" exit 1 fi # 删除未加密的文件 rm "$BACKUP_DIR/$BACKUP_FILE" log "未加密的备份文件已删除" # 同步到 OneDrive if rclone copy "$BACKUP_DIR/$GPG_FILE" "$REMOTE"; then log "已同步到 OneDrive: $GPG_FILE" else log "同步到 OneDrive 失败" exit 1 fi # 清理本地和远程超过保留期的备份 find "$BACKUP_DIR" -name "backup_*.tar.gz.gpg" -type f -mtime +$RETENTION_DAYS -delete rclone delete --min-age ${RETENTION_DAYS}d "$REMOTE" log "超过 $RETENTION_DAYS 天的旧备份已删除" log "备份完成" # ================== Docker 镜像更新 ================== log "开始检查 Docker 镜像更新" # 拉取最新镜像 if docker pull $IMAGE_NAME; then log "拉取最新镜像成功: $IMAGE_NAME" else log "拉取镜像失败" exit 1 fi # 获取最新镜像的 ID LATEST_IMAGE_ID=$(docker inspect --format='{{.Id}}' $IMAGE_NAME) # 获取当前运行容器的镜像 ID CURRENT_IMAGE_ID=$(docker inspect --format='{{.Image}}' $CONTAINER_NAME) # 检查是否有更新 if [ "$LATEST_IMAGE_ID" != "$CURRENT_IMAGE_ID" ]; then log "有新镜像,更新容器..." # 停止并移除旧容器 if docker stop $CONTAINER_NAME && docker rm $CONTAINER_NAME; then log "旧容器已停止并移除" else log "停止或移除旧容器失败" exit 1 fi # 重新启动容器 if docker run -d --name $CONTAINER_NAME \ -v /VM_data:/data \ -e ADMIN_TOKEN="$(cat /vaultwarden_backup/admin_token_hash)" \ -e INVITATIONS_ALLOWED=false \ -p 80:80 \ --restart unless-stopped \ $IMAGE_NAME; then log "容器已更新并重新启动" else log "容器启动失败" exit 1 fi else log "镜像没有更新,不执行操作" fi log "Docker 镜像检查完成"

3. 设置脚本执行权限

确保脚本具有可执行权限,并设置正确的所有者和权限:

sudo chmod +x /vaultwarden_backup/backup_update_script.sh sudo chown your_backup_user:your_backup_group /vaultwarden_backup/backup_update_script.sh

注意:将 your_backup_useryour_backup_group 替换为实际的用户和组,确保只有授权用户可以执行和修改脚本。我使用的是chown vaultwarden:vaultwarden /vaultwarden_backup/backup_update_script.sh

4. 配置定时任务(Cron)

使用 cron 定期执行备份和更新脚本。以下示例将脚本设置为每天凌晨2点执行。

  1. 编辑 Crontab

    sudo crontab -e
  2. 添加以下行

    # 每天凌晨5点执行备份与更新脚本 0 5 * * * /vaultwarden_backup/backup_update_script.sh >> /vaultwarden_backup/backup.log 2>&1
  3. 保存并退出

5. 验证脚本

在首次运行脚本之前,建议手动执行一次以确保一切正常:

sudo /vaultwarden_backup/backup_update_script.sh

检查日志文件 /vaultwarden_backup/backup.log 以确保所有步骤顺利完成。

bitwarden配置

1. 选自托管

2. 填解析到这个vps的域名

3. 注册第一个用户,第一个注册用户就是管理员

4. 进入后台管理,关闭新用户注册,因为这只是我们自己用

后台网址为 https://域名/admin, 这里密码填上面使用 argon2中的密码(例子中为123456789)

安全提示

  • 密码安全:确保 /vaultwarden_backup/gpg_passphrase_file/vaultwarden_backup/admin_token_hash 文件的权限为 600,且仅限授权用户访问。
  • 脚本权限:确保脚本拥有适当的执行权限,并且只有授权用户可以修改。
  • 定期检查:定期检查备份日志,确保备份和更新过程正常运行。
  • 套CDN: 给解析到VPS的域名套上CDN,防止泄露VPSIP,这个可以在Cloudcone中打开
  • 开防火墙: 注意放行443和80端口

至此,已经结束,下面都是一些佬推荐的,不属于上面教程的一部分,感兴趣的可以看看


其他佬倾情推荐

docker compose一把梭, 注意他使用的是alpine系统镜像

services: vault: image: vaultwarden/server:alpine container_name: vault network_mode: host restart: always volumes: [ "./data/:/data" ] environment: # Vault - DOMAIN=https://vault.xxx.com - SIGNUPS_ALLOWED=false - SIGNUPS_VERIFY=true - INVITATIONS_ALLOWED=false # Rocket - ROCKET_ADDRESS=127.0.0.1 - ROCKET_PORT=3018 # Websocket - WEBSOCKET_ENABLED=true - WEBSOCKET_ADDRESS=127.0.0.1 - WEBSOCKET_PORT=3019 # SMTP - SMTP_HOST=smtp.gmail.com - SMTP_PORT=587 - SMTP_SECURITY=starttls - [email protected] - [email protected] - SMTP_PASSWORD=xxx
阅读时间 6 分钟
上次访问

fufu 好厉害哟

你是做个人密码管理器用的吗?感觉有点重

对的,做个人密码管理器,通用性号,不需要来回导入导出密码.
另外,还用这个VPS科学上网,一机两用,省钱王 :tieba_025:

算了,还是继续10u一年吧

可以的佬!!!
我挂了个 SD 卡,每隔几天自动打包备份到卡上
有空了手动再备份一下到移动硬盘

插个眼,后面有时间搞一下做个自动备份
我现在就是单纯在用vaultwarden做密码记录,其他的啥也没搞,就是怕服务器出问题了,密码没了就完蛋.

不用担心,他这个密码在本地浏览器中还有一份,即使你VPS挂了,还可以把浏览器中密码导入 :tieba_095:

直接基于官方的 docker 镜像构建一个内置 rclone 和备份计划任务的镜像,使用不同的参数启动就行了

不是说官方的,是 vaultwarden 官方的,你可以把 rclone / 初始化脚本 / 备份脚本 / 计划任务。。。这些都构建到你自己的镜像中,在启动镜像的时候通过参数的形式启动,用起来更方便

那这个更方便了,不需要我这么繁琐的操作了

等等,关闭新用户注册,那你怎么注册呢? :face_with_monocle:

容器部署的时候,先开注册,等自己账户注册完毕之后再加上环境变量关闭注册,而且有了docker compose之后很方便的

分享一个我的docker-compose.yml

services: vault: image: vaultwarden/server:alpine container_name: vault network_mode: host restart: always volumes: [ "./data/:/data" ] environment: # Vault - DOMAIN=https://vault.xxx.com - SIGNUPS_ALLOWED=false - SIGNUPS_VERIFY=true - INVITATIONS_ALLOWED=false # Rocket - ROCKET_ADDRESS=127.0.0.1 - ROCKET_PORT=3018 # Websocket - WEBSOCKET_ENABLED=true - WEBSOCKET_ADDRESS=127.0.0.1 - WEBSOCKET_PORT=3019 # SMTP - SMTP_HOST=smtp.gmail.com - SMTP_PORT=587 - SMTP_SECURITY=starttls - [email protected] - [email protected] - SMTP_PASSWORD=xxx

关于自动更新映像,可以试试 watchtower ,通过docker部署,可以自动更新docker映像。

自建的vaultwarden,高可用是个大麻烦
万一中心节点歇菜了,浏览器插件上面就不能添加新密码了:cry:

这个真不建议自动更新,因为曾经遇到过更新后无法登录的情况。

实际上没必要做备份,每个client都有一份

刚刚发现1panel能链接很多网盘做备份也能添加备份计划,在计划任务里再加个run_watchtower去更新容器

感谢大佬分享,watchtower这个也可以自动更新镜像

面板安装很快,刚刚加了备份到cf r2和七牛云,watchtower就把镜像拉下来,然后加个计划任务,定时执行一下就行了
shell脚本如下

#!/bin/bash docker run --rm --name watchtower -v /var/run/docker.sock:/var/run/docker.sock dockerpull.com/containrrr/watchtower --cleanup --run-once

放心试
然后把里面 /data 目录映射出来

然后更新确实是有必要的,久久一次可能会有非向下兼容更新,客户端自动更新了,server端没更新,导致登录失败

简单的搞法就是

  1. 用 1panel 面板
  2. 用内建的应用商店安装
  3. 设定里新增 onedrive 号
  4. 计画任务 添加应用备份,本机一份 onedrive 一份

需要这么复杂么,直接存GitHub上自动同步不好了

9 天后

大佬,您那边是有自己的 ssl 证书吗?选的是灵活模式还是严格模式呀

哇,可以整一个,我nas上搭建了一个,一直苦于没有公网的ipv4地址

感谢大佬的教学,目前 Vaultwarden 已稳定运行大概 1 个多月了。
不知为何怎么那么刚好啊,之前还在这机子玩过 Alist + Cloudreve + Rclone + Navidrome。

VPS 中竟然只差自动加密与备份环节了,晚点照大佬的教程把备份搞上 :bili_110:

最近换到官网服务,感觉跟自建使用体验没差

9 天后

今天发现备份失败了,看了一下日志,发现是备份时文件变动导致的。建议tar可以加一个 --warning=no-file-changed,防止备份失败。
贴一个修改后代码:

创建备份

log “开始备份”
if tar --warning=no-file-changed -czf “$BACKUP_DIR/$BACKUP_FILE” -C “$SOURCE_DIR” .; then
log “备份文件已创建: $BACKUP_FILE”
else
log “备份失败”
exit 1

谢谢帮忙优化,现在这个帖子我已经编辑不了了,如果有遇到问题的翻翻评论区就能看到你了,谢谢优化 :tieba_095: :tieba_095:

2 个月后

在苹果上能实现我登录完app自动降账户密码添加么?自带的密码可以

牛,我也试着弄一个,谢谢分享

3 个月后

143 个未读话题 和 132 个新话题, 或浏览文档共建中的其他话题