Vaultwarden自托管实战:用cpolar内网穿透搭建密码管理器
2026/9/24 19:11:40 网站建设 项目流程

自己搭一个密码管理器,其实是把“数据掌控权”从别人手里拿回来的过程。Bitwarden 是目前公认的开源密码管理方案,而自托管的 Vaultwarden(Bitwarden 服务端的社区实现)又解决了官方服务端太重、太吃资源的问题。不过自托管之后会立刻撞上一个门槛:你家宽带没有固定的公网 IP,出门在外根本连不回家里那台服务器。我当初就是卡在这一步,最后用 cpolar 把内网服务安全地映射了出去,才真正把这套密码系统跑通。这篇文章就把整套流程拆开来讲,包括为什么这么选、每一步怎么操作、会遇到哪些坑,以及跑起来之后怎么维护。

适用对象很明确:有一台 NAS、旧电脑、云服务器或者树莓派,想彻底掌控自己密码数据,同时不愿意每年为密码管理服务付费的用户。不需要你有很强的网络基础,只要会敲几条命令、看得懂简单的 Docker 配置,就能跟着做完。

1. 为什么要用 Vaultwarden 自托管,而不是直接用官方云服务

1.1 密码管理器自托管的底层逻辑

密码管理器的核心职责,是把你所有的账号密码、支付信息、安全笔记加密存储,并在需要的时候通过主密码解密。所有的加密解密都在客户端本地完成,服务器只保存密文。这也是 Bitwarden 客户端敢于开源的原因——就算服务器被脱库,攻击者拿到的也只是一堆无法解密的乱码。

但这套逻辑成立的前提,是服务器代码本身没后门、加密实现正确。官方云服务当然可信,但“可信”和“可控”是两码事。自托管意味着你可以审计服务端代码、决定数据存储位置、控制备份策略,甚至完全断外网在局域网里用。对于把全部数字生活密钥都放在一个地方的工具来说,这种掌控感我觉得值回折腾成本。

还有一个非常现实的原因:官方云服务端需要.NET运行时加 SQL Server,内存占用轻松上 GB。对家里那台 2GB 内存的 NAS 来说根本跑不动。Vaultwarden 用 Rust 重写了服务端,内存占用常年维持在几十 MB,SQLite 单文件存储,备份就是复制一个文件的事。

1.2 Vaultwarden 与官方服务器端的功能差异

Vaultwarden 并非 Bitwarden 官方出品,而是一个社区逆向工程实现。它兼容 Bitwarden 官方客户端(浏览器插件、桌面端、iOS/Android App)的 API,所以客户端不需要做任何修改。

实测下来绝大多数核心功能都可用:密码库同步、组织共享、附件存储、TOTP 两步验证、紧急访问等。但有一点要注意,Vaultwarden 毕竟是兼容实现,官方新增的功能会有延迟,比如某些新的硬件密钥绑定的前端交互。对你日常使用影响不大,但心里要有数——如果有一天某个官方新功能对你特别重要,先确认 Vaultwarden 是否已跟上版本。

另外还有一个决策点:既然叫“密码管理器”,一旦运行起来它就会成为你的“唯一钥匙”,所以服务稳定性直接影响你能否登上其他网站。这一点决定了自托管方案必须做好两件事:备份要自动化、访问链路要尽量稳定。这也是我坚持用 cpolar 而不是手动改路由器的原因——后面细说。

2. Docker 部署 Vaultwarden:参数解析与数据目录规划

2.1 部署前的环境准备

建议系统为 Ubuntu 20.04/22.04 或 Debian 11/12,2GB 内存以上。如果你的设备是 NAS,群晖/威联通系统本身带 Docker,也可以直接操作,但命令路径和权限管理略有差异,下文以 Linux 服务器终端为准。

安装 Docker 顺手把 compose 插件也装上,现在推荐用 docker compose 管理:

sudo apt update sudo apt install docker.io docker-compose-v2 -y sudo systemctl enable --now docker

注意 Ubuntu 的 docker-compose-v2 插件包和 pip 安装的旧版 docker-compose 不是同一个东西,下文全部以docker compose子命令为准。

2.2 用 docker compose 定义 Vaultwarden

先建一个目录,专门放 Vaultwarden 的配置和数据:

mkdir -p /opt/vaultwarden cd /opt/vaultwarden

创建docker-compose.yml

services: vaultwarden: image: vaultwarden/server:latest container_name: vaultwarden restart: always environment: DOMAIN: "https://yourdomain.example.com" SIGNUPS_ALLOWED: "false" ADMIN_TOKEN: "请生成一个足够长的随机字符串" volumes: - ./vw-data:/data ports: - "8080:80"

解释几个关键参数,这些不是随便写的:

  • DOMAIN:告诉 Vaultwarden 你最终对外访问的地址,影响两步验证、邮件链接、WebAuthn 等功能的 URL 生成。这个参数必须和用户实际访问的地址一致,否则会出现“客户端连接失败”这类诡异问题。
  • SIGNUPS_ALLOWED:部署期间先设成true,注册完自己的账号后必须改成false,否则你的实例会被全网扫描,任何人都能注册账号并在你的服务器上存密文。
  • ADMIN_TOKEN:管理后台的访问口令,必须设置。没有它你没法打开/admin页面,也没法发邀请链接、查日志。
  • ports:把容器内的 80 端口映射到宿主机的 8080。之所以不用默认 80,是因为 cpolar 和反向代理通常也需要占用端口,错开能少很多麻烦。

关于版本号,不要在自托管服务上用latest之外的选择,但也别完全不管更新。我的习惯是每两个月跑一次docker compose pull && docker compose up -d,小版本更新随更随用,因为密码管理器涉及到安全漏洞修复。

2.3 首次启动与账号注册

执行:

docker compose up -d docker logs -f vaultwarden

看到日志里出现类似Starting server on 0.0.0.0:80的输出就说明服务起来了。浏览器访问http://服务器IP:8080,应该能看到 Bitwarden 的 Web 登录界面。

这时先不要注册账号,而是设置ADMIN_TOKEN并用它登录/admin页面,确认管理后台可用后,再回到首页注册你的账号。Vaultwarden 有一个机制:第一个注册的账号会成为管理员(前提是 SIGNUPS_ALLOWED 开启),这个账号不能轻易删除,否则整个实例的管理权限就丢了。

注册完立刻去改配置:

nano /opt/vaultwarden/docker-compose.yml # 将 SIGNUPS_ALLOWED 改为 "false" docker compose up -d

到这里局域网内的密码管理服务已经可用了。但你的客户端仍然无法“出门在外”连回来,这正是下一章要解决的问题。

3. cpolar 隧道配置:从内网地址到公网访问的完整链路

3.1 为什么选择 cpolar 而不是手动端口映射

传统做法是去路由器后台做端口映射,把公网 IP 的 443 端口转发到服务器的 8080。但只适用于两种情况:宽带有公网 IP,且运营商没封 443 端口。现在很多家宽拿到的都是大内网 IP,路由器 WAN 口地址是 100.64.x.x 这种共享网段,从公网根本路由不进来。

就算有公网 IP,443 端口也常常被运营商封禁,你不得不用高位端口,而高位端口会被手机流量、公司网络的各种防火墙拦截。

cpolar 这类内网穿透工具解决的正是“无公网 IP + 端口受限”这个场景。它在你的服务器上跑一个客户端,主动向外部的 cpolar 服务器建立长连接,外部用户访问 cpolar 分配的域名时,流量会经由这条隧道转发到你的内网服务。

这类工具市面上很多,frp 和 ngrok 生态也成熟,但 cpolar 胜在三个点:隧道配置有 Web 后台管理,不用手动编辑 frpc.ini;免费套餐提供 HTTP/HTTPS 隧道,能满足密码管理器的证书需求;国内访问速度整体优于 ngrok 官方线路。免费版隧道域名随机变化,这符合密码管理器吗?我建议用付费固定域名,原因在第 4 章讲证书时会说清楚。

3.2 安装 cpolar 与认证

在 Vaultwarden 所在服务器上安装:

curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash

安装完成会多出一个cpolar命令。先注册 cpolar 账号,登录后台拿到一个认证 token,然后执行:

cpolar authtoken <你的token>

这个命令会把认证信息写入~/.cpolar/cpolar.yml。注意,如果你用 root 用户安装,那么认证信息在/root/.cpolar下;如果用普通用户再 sudo,那么路径可能在普通用户 home 下,不同用户切过去可能找不到凭据,日志报 401 时先查这个。

3.3 创建第一个 HTTP 隧道

先用一条命令快速验证链路通不通:

cpolar http 8080

终端会显示随机分配的域名,类似https://xxxxx.cpolar.top。浏览器访问这个域名,如果看到 Vaultwarden 登录页,说明隧道已经通了。

但注意,这个功能没有持久化,关掉终端隧道就断了。正确做法是在 cpolar Web 后台配置固定隧道。

登录 cpolar 后台,进入“预留”页面。如果是付费套餐,先在“保留域名”里添加一个自定义域名(比如vw.yourname.cpolar.top),然后添加隧道时选择这个保留域名,本地地址填127.0.0.1:8080,协议选 HTTP。

为什么隧道地址填127.0.0.1?因为 cpolar 客户端就运行在 Vaultwarden 同一台机器上,直接走回环接口,避免经过外部交换机,也顺便绕开防火墙引流的麻烦。cpolar 默认自动为 HTTP 隧道附加 HTTPS 支持,这是关键点,下一章展开。

编辑 cpolar 配置文件(通常在~/.cpolar/cpolar.yml)时,手动声明隧道名可以更清晰:

tunnels: vaultwarden: proto: http addr: 8080 domain: vw.yourname.cpolar.top

然后重启 cpolar 服务:

sudo systemctl restart cpolar

此时 cpolar 的免费套餐和付费套餐差异会直接影响后续使用:免费套餐的隧道域名带动态路径,证书不好配;付费套餐支持自定义子域名和保留域名,证书链完整。密码管理器场景建议上付费套餐,一个月一杯咖啡的钱换稳定的访问入口。

4. HTTPS 证书与移动端实测:自托管密码库真正可用的最后一环

4.1 为什么必须启用 HTTPS

浏览器有一个安全策略:在 HTTPS 页面请求 HTTP 资源会被拦截,反过来也一样。如果用户通过https://vw.yourname.cpolar.top访问 Vaultwarden,但 Vaultwarden 返回的静态资源和 API 响应全是 HTTP,浏览器控制台会刷满 mixed content 报错,密码库根本加载不出来。

更重要的一点:密码管理器的传输链路不可信,等于密码明文在网上裸奔。虽然客户端加密后传输,但 TLS 层仍然必不可少——它是防止窃听和中间人攻击的第一道防线。

cpolar 的 HTTP 隧道默认有一个好行为:它会自动为首选域名申请 Let's Encrypt 证书,并托管 TLS 终结。也就是说,你不用在 Vaultwarden 容器里配证书,也不用在后端 Nginx 里写证书路径,cpolar 到用户浏览器这一段落了 HTTPS,cpolar 到本机回环接口这一段走明文 HTTP。这个链路模型是可接受的,因为回环接口上没有任何中间设备。

4.2 客户端连接配置:以 iOS/Android 和浏览器为例

这步是大多数教程不细讲、但新手最容易懵的地方。Bitwarden 客户端默认连接的是官方服务器,你必须把服务器 URL 改成自己的地址。

浏览器扩展:

  • 安装 Bitwarden 浏览器扩展后,点击右上角设置图标
  • 找到“服务器 URL”,选择“自托管”
  • 输入https://vw.yourname.cpolar.top
  • 保存后回到登录页,用你之前注册的邮箱和主密码登录

移动端 App(iOS/Android):

  • 打开 App 后先别急着登录,点右上角或左上角的设置按钮,一般是个齿轮或头像一个
  • 找到“服务器 URL”或“自托管”选项
  • 输入与自己域名一致的地址
  • 保存后 App 会重新加载,再输入邮箱和主密码

这里容易踩的坑:把地址填成了http://服务器IP:8080,或者填了一个带路径的地址。Vaultwarden 的 API 是直接从根路径挂载的,任何路径后缀都会让客户端在请求api/...时拼接出错误 URL。

如果你在用浏览器扩展和手机 App 的时候遇到An error has occurred之类提示,第一件事就是核对 URL 是否以https://开头、有没有多余路径、能不能在浏览器里打开这个域名看到登录页。

4.3 实测常见错误与处理

我把跑通前后遇到的高频问题整理一下,每一条都对应一个明确的处理动作:

现象原因解决
浏览器访问隧道域名显示“不安全”证书未签发或域名被浏览器拦截等待几分钟证书自动申请;检查域名拼写;cpolar 后台确认隧道状态为 active
手机 App 登录提示“连接失败”URL 填错或网络无法触达隧道用手机浏览器先访问一遍域名,确认能打开;再检查 URL 是否多打斜杠
网页能开但登录后一直转圈Vaultwarden 的 DOMAIN 设置与访问地址不一致修改 docker-compose.yml 的 DOMAIN 为最终 HTTPS 域名,重启容器
cpolar 日志提示 401 Unauthorizedtoken 未认证或用户不对重新执行cpolar authtoken,确保和启动 cpolar 服务的用户一致

还有一类问题不常见但很危险:你用的是免费版的随机域名,域名一旦变化,客户端里保存的服务器 URL 就失效。手机端你可以在 App 里更新,但浏览器扩展如果开了“自动锁定”,而且是靠主密码登录,那倒还好;可如果你开了“记住我”,那么所有设备的登录态都会在域名切换时失效,这是灾难性的体验。而自定义域名永久不变,就彻底绕开了这个坑。

5. 跑起来之后的事:备份体系、常见故障与我的几点使用心得

5.1 建立无脑备份链路

密码管理器没有备份等于定时炸弹。Vaultwarden 的存储核心是 SQLite 数据库文件和config.json,它们都在./vw-data目录里。备份策略极其简单:把整个目录打压缩包,至少保留最近 7 天。

我每天凌晨 3 点跑一次备份,脚本任务如下:

#!/bin/bash BACKUP_DIR=/opt/backups/vaultwarden DATE=$(date +%F) mkdir -p $BACKUP_DIR cd /opt/vaultwarden docker exec vaultwarden sqlite3 /data/db.sqlite3 ".backup '/data/db-backup.sqlite3'" tar czf $BACKUP_DIR/vw-$DATE.tar.gz vw-data find $BACKUP_DIR -name "*.tar.gz" -mtime +14 -delete

sqlite3 .backup而不直接cp db.sqlite3的原因:SQLite 在写入时直接复制数据文件可能拿到损坏的快照,.backup是官方推荐在线备份方式。如果容器里没有 sqlite3 命令,可以先装,也可以接受极小概率的备份不一致——但没必要冒险。

备份文件若只在同一台机器上,硬盘挂了就全没了。建议任何云盘、另一台 NAS、对象存储里放一份。密码库密文即使泄露也不是明文,所以备份传云端的安全等级比裸传文件高得多。

5.2 换了域名或者服务器迁移怎么处理

自托管服务最麻烦的一件事就是迁移。Vaultwarden 的迁移比很多自托管软件简单,因为它把所有状态都存到了vw-data目录:

  1. 停容器
  2. 打包 vw-data 目录
  3. 传到新服务器的相同路径
  4. 改 docker-compose.yml 里的 DOMAIN
  5. docker compose up -d

但如果只是换了 cpolar 隧道域名,不迁移服务器,那么要做两件事:改 Vaultwarden 的 DOMAIN 环境变量,然后重启容器;所有已登录的客户端重新设置服务器 URL 并重新登录。

这里注意一个隐藏行为:Bitwarden 客户端在检测到新设备登录时,会给注册邮箱发一封验证邮件。如果你在局域网环境没配 SMTP,邮件发不出去,登录会卡在“验证邮箱”这一步。解决方式是:在管理后台把新设备登录验证选项关掉,或者干脆配置好 SMTP。验证邮件这个功能一旦卡住,非常容易让人误以为服务挂了,实际只是邮件发不出去。我最初在这里浪费了半个小时。

5.3 一些并不在官方文档里的建议

部署完成后,有几个容易被忽略的安全加固点:

  • 主密码强度是安全链的起点,建议 4 个随机单词加数字和符号,长度不少于 16 位。几乎可以这么说:如果有人能记住你的主密码,那它就太弱了。
  • 开启两步验证:Vaultwarden 自带 TOTP 验证器支持。第一步用密码,第二步用验证码,两层都拿下才进得去。别把验证器和密码存在同一个设备里,用独立的验证器 App。
  • 定期做恢复演练:每季度从备份目录里把 vw-data 恢复到一台临时容器,试着用客户端登录一次。真到数据丢了才想起验证备份可用,往往已经晚了。
  • cpolar 隧道的访问密码:在 cpolar 后台可以给隧道设置访问密码(Basic Auth),前置校验后再进入 Vaultwarden,等于多一层门禁。这个功能对暴露到公网的服务很有价值。

我实际用下来的体感是:Vaultwarden + cpolar 这套组合,稳定运行几个月基本不用管。偶尔看一眼 cpolar 后台看下流量走势,遇到版本更新就 pull 一次镜像。整个系统的复杂度都集中在最初的搭建和第一次客户端连接上,跑通之后就只是日用工具了。

最后分享一个小技巧:Vaultwarden 的 Web 界面本身就是个很好用的密码库查看器,但日常我更推荐直接装官方桌面客户端,配合浏览器扩展的自动填充,体验最顺。手机端打开面容解锁,出门付款、登录各种 App 都能一键填充密码,那种“所有密码都在兜里”的踏实感,是自托管带给我最大的回报。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询