免费解锁Bitwarden所有功能,自建Vaultwarden过程

发布于 2026-10-25 11:11 更新于 2026-10-25 12:12 4602 字 24 min read

记录一次从源码编译 Vaultwarden、制作 SUSE BCI 运行镜像、使用 Podman kube 部署、限制容器出站网络,并用 7z 实现自动异地备份的完整过程。

本文记录的是一次实际部署过程。最终环境为:Vaultwarden 1.37.3、Web Vault 2026.7.0、SUSE BCI 16.0、Podman、Nginx、SQLite,并通过 nftables 禁止 Vaultwarden 容器主动访问互联网。

Vaultwarden 保存的是账号密码、TOTP 密钥和 Passkey 等高敏感数据。本文配置适合个人自托管,但不代表“使用某个基础镜像”就自动获得绝对安全。及时更新、强主密码、独立二步验证、可靠备份和恢复演练仍然是核心。

一、为什么选择自托管 Vaultwarden

我希望统一管理以下内容:

  • 网站账号与密码;
  • Google、GitHub 等网站每 30 秒变化一次的 TOTP 验证码;
  • 支持 Passkey 的网站凭据;
  • 浏览器扩展、桌面端和手机 App 之间的同步。

Bitwarden 的客户端生态比较完整,而 Vaultwarden 是兼容 Bitwarden 客户端协议的轻量服务端实现。对个人使用来说,它比完整 Bitwarden 官方服务端更容易部署,也更适合资源有限的 VPS。

这次部署的整体结构如下:

Bitwarden 浏览器扩展 / 手机 App
                │
                │ HTTPS
                ▼
        Nginx(宿主机 443)
                │
                │ HTTP 0.0.0.0:7443
                ▼
       Podman 端口映射与独立网络
                │
                ▼
 Vaultwarden 1.37.3(容器内 8080)
                │
                ▼
      /anmiao/vaultwarden/data

容器允许被宿主机 Nginx 访问,但禁止主动连接互联网。

二、为什么使用 SUSE BCI 16.0

BCI 是 SUSE 提供的基础容器镜像体系。这次使用它主要有以下原因,而不是 Debian/Alpine。

SUSE BCI(SUSE Linux Base Container Images)是 SUSE 官方维护的一套企业级基础容器镜像,底层继承自 SUSE Linux Enterprise(SLE)。它的定位并不是提供某一个具体应用,而是为开发者提供一个经过维护、可用于构建自定义容器镜像的基础环境。SUSE Registry 中的 BCI 镜像会持续接收更新和安全修复,并沿用 SLE 的软件包质量控制与 CVE 处理机制,因此相比随意选择一个第三方基础镜像,更适合作为长期运行服务的底座。

BCI 的另一个优势是镜像层次划分非常清晰。SUSE 提供 Base、Minimal、Micro 等不同规格,也提供 GCC、Python、Node 等面向开发场景的 Development Stack 镜像。这样可以在多阶段构建中使用功能完整的开发镜像负责源码编译,再将最终二进制复制到更精简的 Minimal 镜像中运行。对于 Vaultwarden 这类 Rust 应用,我采用 bci/gcc:15 作为 Builder,通过 SUSE 官方仓库直接安装 Rust 和 Cargo,再使用 BCI Minimal 作为最终运行环境,从而避免把 GCC、Cargo、Rust 编译器等大量开发工具带入生产镜像。

此外,SUSE BCI 具有较好的可审计性和可维护性。镜像保留 RPM 数据库,可以追踪文件来自哪个 RPM 软件包及其具体版本,这对漏洞扫描和依赖审计比较有价值;同时 BCI 可以在普通 Linux、Podman、Docker 和 Kubernetes 环境中运行,并不要求宿主机本身必须是 SUSE。BCI 镜像还允许自由分发基于其构建的自定义镜像,比较适合自行维护应用镜像或私有镜像仓库的场景。

对我这次 Vaultwarden 部署而言,选择 SUSE BCI 的核心原因并不是追求极限的小体积,而是希望获得一条更清晰的构建链:使用 SUSE 提供的 GCC、Rust RPM 和企业级基础环境完成编译,再将最终程序部署到精简的 BCI Minimal 中。这样既能控制运行镜像中的组件数量,又保留了明确的软件来源、更新渠道和长期维护路径。

1. 构建环境与运行环境可以明确分离

编译阶段使用:

registry.suse.com/bci/gcc:15

运行阶段使用:

registry.suse.com/bci/bci-minimal:16.0

GCC 镜像负责提供编译工具,最终镜像只保留 Vaultwarden 二进制、Web Vault 静态文件和必要运行环境,不包含 Rust、Cargo、GCC 或源码。

2. 可以直接通过 Zypper 安装 Rust 和 Cargo

Vaultwarden 1.37.3 需要 Rust 1.98.1。SUSE BCI 仓库中可以直接安装预编译 RPM:

zypper --non-interactive install --no-recommends -y \
  rust1.98 \
  cargo1.98

实际版本为:

rustc 1.98.1
cargo 1.98.1

这意味着不需要执行 rustup 安装脚本,也不是在镜像中“编译 Rust”。真正需要编译的是 Vaultwarden 本身。

3. BCI Minimal 更适合作为最终运行镜像

BCI Minimal 保留了 glibc 和基本运行环境,但移除了大量开发工具和软件管理组件。相比编译镜像,它的攻击面和磁盘占用都更小。

不过,镜像更小并不等于运行内存一定更低,也不代表天然更安全。更重要的是:

  • 最终镜像不包含编译工具;
  • 使用非 root 用户运行( 嫌弃麻烦没有在用,而且我已经仅限于内网使用);
  • 固定应用版本;
  • 正确配置网络与权限;
  • 持续更新和验证恢复流程。

三、为什么选择自己编译

直接使用 Vaultwarden 官方镜像最省事,而自己编译的好处是可以明确控制:

  • Vaultwarden 版本;
  • Rust/Cargo 版本;
  • Web Vault 版本;
  • SQLite 功能;
  • OpenSSL 构建方式;
  • 容器目录结构;
  • 最终运行用户;
  • 基础镜像与构建链。

本次只启用 SQLite,并使用 vendored OpenSSL:

cargo build \
  --release \
  --locked \
  --no-default-features \
  --features sqlite,vendored_openssl

缺点也很明确:升级 Vaultwarden 时,需要自行重新构建、测试客户端兼容性、检查 Web Vault 版本,并维护整个镜像供应链。

四、版本与路径约定

项目版本或路径
Vaultwarden1.37.3
Web Vault2026.7.0
Rust / Cargo1.98.1
构建镜像registry.suse.com/bci/gcc:15
运行镜像registry.suse.com/bci/bci-minimal:16.0
Vaultwarden 二进制/anmiao/vaultwarden
数据目录/anmiao/data
Web Vault/anmiao/web-vault
容器监听端口8080
宿主机映射端口7443
对外域名https://xxxxxx.anmiao.moe

五、完整 Dockerfile

本次构建服务器为 8 核 16 GB,云厂商为华为云地点为雅加达。选用原因是半夜方便付款,而且一个小时比较相对便宜

将以下文件保存为 /build/Vaultwarden/Dockerfile

FROM --platform=linux/amd64 docker.io/vaultwarden/web-vault@sha256:ba8bab66d4330ab9dbafa8f245bcbe99cf6ee3f2c8ce9b5fbb10e9c49658451c AS web

FROM registry.suse.com/bci/gcc:15 AS Build

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

RUN set -eux; \
    zypper --gpg-auto-import-keys -vv refresh --force; \
    zypper --non-interactive install --no-recommends -y \
      rust1.98 cargo1.98 perl pkgconf-pkg-config ca-certificates

ENV CARGO_INCREMENTAL=0 

WORKDIR /anmiao/build

COPY ./vaultwarden/ .

WORKDIR /anmiao/build/vaultwarden

ARG VW_VERSION=1.37.3
ENV VW_VERSION=${VW_VERSION}

RUN echo "===== Vaultwarden build =====" && \
    echo "Version: ${VW_VERSION}" && \
    echo "CPU jobs: ${CARGO_BUILD_JOBS}" && \
    echo && \
    cat /anmiao/build/rust-toolchain.toml && \
    echo && \
    rustc --version && \
    cargo --version

RUN cargo build \
        --release \
        --locked \
        --no-default-features \
        --features sqlite,vendored_openssl && \
    mkdir -p /output && \
    install \
        -m 0755 \
        /anmiao/build/target/release/vaultwarden \
        /output/vaultwarden

RUN echo "===== Binary validation =====" && \
    test -x /output/vaultwarden && \
    /output/vaultwarden --help >/dev/null && \
    ls -lh /output/vaultwarden


FROM registry.suse.com/bci/bci-minimal:16.0
LABEL maintainer="闇喵 <anmiao@am.moe>"

ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'

RUN mkdir -p /anmiao/{data,web-vault}

COPY --from=Build --chown=0:0 --chmod=0755 /output/vaultwarden /anmiao/vaultwarden
COPY --from=web --chown=0:0 /web-vault/ /anmiao/web-vault/

ENV ROCKET_PROFILE=release \
    ROCKET_ADDRESS=0.0.0.0 \
    ROCKET_PORT=8080 \
    DATA_FOLDER=/anmiao/data \
    WEB_VAULT_FOLDER=/anmiao/web-vault \
    WEB_VAULT_ENABLED=true

WORKDIR /anmiao

EXPOSE 8080
ENTRYPOINT ["/anmiao/vaultwarden"]

构建镜像流程

mkdir -p /build/Vaultwarden && cd /build/Vaultwarden
git clone --depth 1 --branch 1.37.3 https://github.com/dani-garcia/vaultwarden.git

cd /build/Vaultwarden

docker build . -t vaultwarden:v1.37.3-amd64

PS: 克隆指定 Tag 后出现 detached HEAD 是正常现象,因为当前检出的是固定版本标签,不影响构建。

验证镜像

在镜像编译完成之后使用以下命令验证

docker run --rm vaultwarden:v1.37.3-amd64 --version

预期输出:

Vaultwarden 1.37.3
Web-Vault 2026.7.0

六、部署流程准备

宿主机创建相关目录

mkdir -p /anmiao/vaultwarden/data

七、Podman kube Pod YAML

我将镜像上传到了自己的镜像仓库( 已设为公开 ),因此部署服务器从远端拉取:

swr.cn-southwest-2.myhuaweicloud.com/anmiao/vaultwarden:v1.37.3-amd64

保存为 /anmiao/vaultwarden/vaultwarden.yaml:

---
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: anmiao-vaultwarden
  name: anmiao-vaultwarden
spec:
  restartPolicy: Always
  securityContext: 
    seccompProfile: 
      type: RuntimeDefault
  containers: 
  - env:
    - name: UMASK
      value: '022'
    - name: TZ
      value: Asia/Hong_Kong
    - name: DOMAIN
      value: 'https://passwd.anmiao.moe'
    - name: ROCKET_ADDRESS
      value: 0.0.0.0
    - name: ROCKET_PORT
      value: 8080
    - name: DATA_FOLDER
      value: /anmiao/data
    - name: WEB_VAULT_FOLDER
      value: /anmiao/web-vault
## 第一次使用时,临时改为: true,先注册一个专属自己账号
    - name: SIGNUPS_ALLOWED
      value: false
    - name: INVITATIONS_ALLOWED
      value: false
    - name: WEB_VAULT_ENABLED
      value: true
## 禁止 Vaultwarden 后端主动下载网站图标
    - name: DISABLE_ICON_DOWNLOAD
      value: true
    - name: PUSH_ENABLED  ##你目前计划不使用 Bitwarden Push
      value: false
#    - name: ADMIN_TOKEN
#      value: 
    image: swr.cn-southwest-2.myhuaweicloud.com/anmiao/vaultwarden:v1.37.3-amd64
    name: poi
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
    ports:
    - name: http
      containerPort: 8080
      hostPort: 7443
      protocol: TCP
    volumeMounts:
    - mountPath: /anmiao/data
      name: vaultwarden-data
    - mountPath: /tmp
      name: vaultwarden-tmp
    readinessProbe:
      httpGet:
        path: /alive
        port: 8080
        scheme: HTTP
      initialDelaySeconds: 11
      periodSeconds: 30
      timeoutSeconds: 5
      failureThreshold: 3
    livenessProbe:
      httpGet:
        path: /alive
        port: 8080
        scheme: HTTP
      initialDelaySeconds: 21
      periodSeconds: 60
      timeoutSeconds: 5
  dnsConfig:
    nameservers:
    - 100.96.0.3
    - 100.96.0.2
  volumes:
  - hostPath:
      path: /anmiao/vaultwarden/data
      type: Directory
    name: vaultwarden-data
  - emptyDir:
      sizeLimit: 256Mi
    name: vaultwarden-tmp

DOMAIN 必须填写用户实际访问的 HTTPS 地址,而不是 127.0.0.1:7443 或容器内部地址。

第一次创建账户时,可以临时把:

- name: SIGNUPS_ALLOWED
  value: "true"

账户创建完成后立即改回 false 并重建 Pod。

八、创建 Podman 专用网络

最初尝试过 --internal 网络,但在当前环境中,它会导致宿主机通过 hostPort 访问容器失败。因此最终选择普通 bridge 网络,再用 nftables 单独限制出站流量。

创建固定子网:

podman network create \
  --driver bridge \
  --subnet 10.89.50.0/24 \
  nat

启动 Pod:

podman kube play \
  --network vaultwarden-net \
  /anmiao/vaultwarden/vaultwarden.yaml

检查:

podman pod ps
podman ps
podman port anmiao-vaultwarden-poi

不同 Podman 版本生成的容器名可能略有差异,以 podman ps 为准。

检查实际发布地址:

podman port anmiao-vaultwarden-poi

理想情况下应显示:

8080/tcp -> 0.0.0.0:7443

部分 Podman 版本或 kube 转换路径可能仍显示:

8080/tcp -> 0.0.0.0:7443

这意味着 7443 可能同时监听公网地址。此时不能只依赖 Nginx,应在宿主机防火墙或云安全组中禁止公网访问 7443。可在现有 table inet filter 的 input 链中加入:

iifname "lo" tcp dport 7443 accept
tcp dport 7443 drop

规则应放在任何宽泛的 TCP accept 规则之前。这样 Nginx 仍可通过 127.0.0.1:7443 访问,而公网不能直接绕过 Nginx 连接 Vaultwarden。

PS: 我的云服务器为火山云,所以我在云安全组没有开放7443端口

宿主机测试:

curl -i http://127.0.0.1:7443/alive

预期返回:

HTTP/1.1 200 OK

九、Nginx 反向代理配置

因为 Nginx 已经监听 0.0.0.0:443,Vaultwarden 通过独立域名与其他站点共享 443。

在 Nginx 的 http 作用域中加入 WebSocket 映射:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

我的站点 server 部分配置:

    server {
        listen                10.8.8.1:443 ssl;
        listen                [fd00::1]:443 ssl;  ##开启IPv6
        http2                 on;

        server_name           xxxxxx.anmiao.moe;

        charset               utf-8;

        ssl_trusted_certificate   /ssl/anmiao_moe.crt;  ##证书信任

        ssl_certificate        /ssl/anmiao_moe.pem;
        ssl_certificate_key    /ssl/anmiao_moe.key;

        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  5m;
        ssl_buffer_size 4k;  # 防御BEAST攻击
        ssl_session_tickets  off;

        ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;

        ssl_prefer_server_ciphers  on;
        ssl_protocols  TLSv1.2 TLSv1.3;

        location / {
            # rewrite ^/i(.*) /$1 break;
            add_header         X-Served-By         $host;
            proxy_set_header   Host                $host;
            proxy_set_header   X-Forwarded-Scheme  $scheme;
            proxy_set_header   X-Forwarded-Proto   $scheme;
            proxy_set_header   X-Forwarded-Host    $http_host;
            proxy_set_header   X-Forwarded-For     $proxy_add_x_forwarded_for;
            proxy_set_header   X-Real-IP           $remote_addr;
            # proxy_method       POST;               # 确保 POST 方法被正确转发
            proxy_method       $request_method;    # 请求方式移交后端处理
            proxy_set_header   If-Range            $http_if_range;
            proxy_set_header   Upgrade             $connection_upgrade;
            proxy_set_header   Connection          $http_connection;
            proxy_pass_request_headers             on;    ## 确保所有请求头部都被转发

            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
            proxy_set_header    X-Content-Type-Options    "nosniff";
            proxy_set_header   X-Frame-Options   "SAMEORIGIN";
            proxy_ssl_verify off;

            proxy_buffering off;  ## 关闭缓冲意味着Nginx会直接将从后端服务器接收到的数据流式传输给客户端,而不进行缓存。这对于处理大文件或需要实时传输的场景非常有用
            proxy_redirect off;  ## 对发送给客户端的URL进行修改
            proxy_buffers 8 16k;
            proxy_buffer_size 8k;
            proxy_headers_hash_max_size  51200;
            proxy_headers_hash_bucket_size  6400;
            proxy_pass http://vaultwarden/;
            proxy_http_version 1.1;
        }
    }

    server {
        listen                80;
        listen                [::]:80;  ##开启IPv6

        server_name           xxxxxx.anmiao.moe;

        rewrite ^(.*)$ https://$host$1;

        location / {
            index index.html index.htm;
        }
    }

检查并重载:

nginx -t
systemctl reload nginx.service

PS: 我在DNS服务商侧解析我的域名内WireGuard内网地址,证书是使用正经申请到的。仅使用内网还有一个好处就是不需要备案,只要连上你的WireGuard内网就使用Vaultwarden就跟使用普通网站一样且公网隔离安全性直接拉高。

十、禁止 Vaultwarden 容器连接互联网

为什么要禁止出站连接

Vaultwarden 保存的是最敏感的一类数据。禁止容器主动访问互联网,可以降低以下风险:

  • 应用漏洞被利用后主动向外传输数据;
  • SSRF 访问外部站点;
  • 被植入恶意代码后主动建立外联;
  • 不必要的图标下载、版本检查和推送连接。

这不是绝对防护。攻击者仍可能通过正常 HTTP 响应把数据返回给已经连入 Vaultwarden 的恶意客户端,因此仍然需要及时更新、限制访问来源和保护宿主机。

nftables 规则

在现有持久化配置的:

table inet filter
└── chain forward

中加入:

ip saddr 10.89.50.0/24 oifname "eth0" counter drop comment "Block Vaultwarden egress"

示意:

table inet filter {
    chain forward {
        type filter hook forward priority filter;
        policy accept;

        # 放在任何“允许整个 Podman 子网出网”的宽泛 accept 规则之前。
        ip saddr 10.89.50.0/24 oifname "eth0" counter drop comment "Block Vaultwarden egress"
    }
}

其中 eth0 必须替换为服务器实际公网出口接口:

ip route get 223.6.6.6

如果服务器还有其他公网出口或 IPv6,需要为对应接口和 IPv6 网络补充规则。

重新加载:

nft -f /etc/nftables.conf

验证隔离结果

宿主机访问 Vaultwarden 应成功:

curl -fsS --max-time 5 \
  http://127.0.0.1:7443/alive

查看 nftables 计数器:

nft list chain inet filter forward

触发容器外联后,规则的 packets 和 bytes 应增加。

Vaultwarden 管理面板的 Diagnostics 页面也可以验证:

https://passwd.anmiao.moe/admin/diagnostics

实际结果为:

Internet access: No
Server Latest: Unknown
Web Latest: Unknown
NTP: Unable to fetch NTP time

DNS 可能仍显示正常,因为容器可以访问宿主机或 Podman 提供的 DNS 解析器,但无法继续连接公网 TCP/HTTPS。这不影响隔离结论。

要临时开启管理面板,可以生成 Argon2 管理口令:

podman run --rm -it \
  vaultwarden:v1.37.3-amd64 \
  hash

然后临时配置 ADMIN_TOKEN。检查完成后建议移除该变量,让 /admin 重新关闭。

断网后受影响的功能

以下功能会受影响:

  • Bitwarden Push Relay;
  • 外部 SMTP 发信;
  • 网站图标下载;
  • 在线版本检查;
  • 后端主动调用的外部服务。

以下核心功能不受影响:

  • 密码保存与同步;
  • TOTP 六位验证码生成;
  • Passkey 保存与调用;
  • Web Vault 和 Bitwarden 客户端登录。

TOTP 依赖系统时间,因此宿主机仍应使用 systemd-timesyncd、Chrony 或其他方式保持时间准确。容器共享宿主机内核时钟,不需要自己连接 NTP。

十一、正式使用前的检查

podman pod logs anmiao-vaultwarden

日志应包含:

Private key '/anmiao/data/rsa_key.pem' created correctly
Rocket has launched from http://0.0.0.0:8080

健康检查:

curl -i http://127.0.0.1:7443/alive
curl -I https://xxxxxx.anmiao.moe

还应实际测试:

  • 创建测试账号;
  • 保存一条测试密码;
  • 保存一个测试 TOTP 密钥;
  • 使用手机 App 与浏览器插件同步;
  • 保存并调用一个测试 Passkey;
  • 重建 Pod 后确认所有数据仍然存在。

十二、使用 7z 自动打包并异地备份

Vaultwarden 使用 SQLite。直接在程序运行期间压缩整个数据目录,可能复制到不一致的 db.sqlite3、WAL 和 SHM 文件。

为了简单可靠,这里采用:

短暂停止 Vaultwarden
        ↓
完整打包 /anmiao/vaultwarden/data
        ↓
启动 Vaultwarden
        ↓
校验备份
        ↓
通过 SSH/rsync 发送到异地服务器

个人实例通常可能会中断几分钟。

安装工具

按系统实际包名安装 7-Zip、rsync 和 flock。例如 Debian 系统可先查询:

apt update
apt install 7zip rsync util-linux

某些发行版的软件包名可能是 p7zip-full。

准备备份目录与密码文件

mkdir -p /anmiao/backup/vaultwarden
chmod 700 /anmiao/backup/vaultwarden

install -m 600 /dev/null /root/.vaultwarden-backup-password
nano /root/.vaultwarden-backup-password

密码文件只写一行强密码,不要添加其他内容。

说明:自动化调用 7z 时,密码最终会作为 7z 进程参数出现。单用户服务器通常可接受,但更严格的环境建议改为“7z 压缩 + age 公钥加密”,避免在自动任务中传递口令。

自动备份脚本

保存为 /anmiao/vaultwarden-backup.sh:

#! /bin/bash
set -Eeuo pipefail
umask 077

## 停止Vaultwarden服务
podman kube play --down /anmiao/vaultwarden/vaultwarden.yaml 
sleep 2s

## 打包并加密加密码
7z a -t7z -mx=9 -mhe=on -p123456 ~/vaultwarden-backup-$(date '+%Y-%m-%d_%H-%M').7z /anmiao/vaultwarden 
sleep 2s

## 启动Vaultwarden服务
podman kube play --network nat /anmiao/vaultwarden/vaultwarden.yaml
sleep 2s

## 找出超过30天的备份文件并删掉
find /anmiao/vaultwarden -type f -name "vaultwarden-backup*.7z" -mtime +30 -delete

设置权限:

chmod 700 /anmiao/vaultwarden-backup.sh

首次手动运行:

/anmiao/vaultwarden-backup.sh

异地传输

PS: 备份方式多多,比如WebDAV 、FTP、SFTP等,这里不展开。

备份目标最好位于另一台 VPS、NAS 或对象存储,不要只把备份保存在 Vaultwarden 同一块磁盘上。

配置 Cron 时间任务

每天凌晨 04

执行:

crontab -e

加入:

17 04 * * * /anmiao/vaultwarden-backup.sh

使用非整点时间可以减少与其他定时任务同时运行的概率。

十三、恢复备份

先停止 Vaultwarden:

podman kube down /anmiao/vaultwarden/vaultwarden.yaml

将旧数据目录移走:

mv /anmiao/vaultwarden/data \
   /anmiao/vaultwarden/data.broken.$(date +%s)

mkdir -p /anmiao/vaultwarden/data

解压到临时目录:

mkdir -p /tmp/vaultwarden-restore

7z x \
  -p'你的备份密码' \
  /anmiao/backup/vaultwarden/vaultwarden-YYYY-MM-DD_HH-MM-SS.7z \
  -o/tmp/vaultwarden-restore

由于归档中包含完整路径层级,先检查:

find /tmp/vaultwarden-restore -maxdepth 5 -type f | head

再将实际数据内容复制回去,并恢复权限:

cp -a \
  /tmp/vaultwarden-restore/anmiao/vaultwarden/data/. \
  /anmiao/vaultwarden/data/

重新启动:

podman kube play \
  --network nat \
  /anmiao/vaultwarden/vaultwarden.yaml

检查:

curl -i http://127.0.0.1:7443/alive
podman pod logs --tail=100 anmiao-vaultwarden

建议在正式保存大量账号前,至少进行一次完整的“备份—删除测试实例—恢复”演练。没有实际恢复验证过的备份,只能算备份文件,不能算可靠的恢复方案。

十四、最终结果

最终得到的部署具备以下特点:

  • 使用 SUSE BCI GCC 15 编译 Vaultwarden;
  • Rust/Cargo 通过 SUSE RPM 安装,不使用 rustup;
  • 最终运行环境为 SUSE BCI Minimal 16.0;
  • 数据持久化到宿主机 /anmiao/vaultwarden/data;
  • 由 Nginx 提供 HTTPS 与 WebSocket 反向代理;
  • 使用 Podman kube YAML 管理 Pod;
  • 宿主机能够访问 Vaultwarden;
  • Vaultwarden 容器不能主动连接互联网;
  • TOTP、密码同步和 Passkey 功能仍可正常使用;
  • 每日自动停机数秒,使用 7z 加密打包并上传异地。

自托管密码管理器并不是“部署完成就结束”。后续还需要持续关注 Vaultwarden 与 Web Vault 的新版本、安全公告、客户端兼容性、宿主机补丁,以及备份恢复是否仍然有效。

PS: 本次记录使用的路径、域名、加密密码等均使用了加密处理,仅提供借鉴。

随机文章

加载中...