本文记录的是一次实际部署过程。最终环境为: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.0GCC 镜像负责提供编译工具,最终镜像只保留 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 版本,并维护整个镜像供应链。
四、版本与路径约定
| 项目 | 版本或路径 |
|---|---|
| Vaultwarden | 1.37.3 |
| Web Vault | 2026.7.0 |
| Rust / Cargo | 1.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-amd64PS: 克隆指定 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-tmpDOMAIN 必须填写用户实际访问的 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.servicePS: 我在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 timeDNS 可能仍显示正常,因为容器可以访问宿主机或 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: 本次记录使用的路径、域名、加密密码等均使用了加密处理,仅提供借鉴。