Featured image of post 真的香啊!搭建一个私有部署的密码保险箱

真的香啊!搭建一个私有部署的密码保险箱

基于容器技术在自己的家用NAS上部署密码保险箱,再通过内网穿透开放到外网上,手机和电脑都可以访问,关键是数据都在我自己的机器上

背景

一直以来在我个人电脑上我都是使用Safari浏览器自带的密码管理器来管理密码的,在我的办公电脑上公司都使用1Password。 但是随着密码增多,以及浏览器各种Cookie泄露风险上升,使用Safari或者Chrome管理密码不太合适了,我决定使用专业的密码保险箱。

选择

选择一个密码保险箱的出发点毋庸置疑是保密性高和泄漏风险小,所以考虑自己在NAS上建立一个密码保险箱,这样只要我确保NAS存储器数据备份不出意外,我就可以有我自己的足够安全的密码保存方案。

我的选择条件和约束,简单来说:

  1. 要有本地存储方案,不想存在别人的云上,我自己也可以进行内外穿透向外提供专属服务
  2. 要有直接可用的客户端,无需进行二次开发
  3. 使用成本要低,因为我只是个人使用

一通Google之后,BitWarden进入了我的视线。其实本来也知道有这个软件,但是令人激动的是BitWarden提供一个开源的本地化部署方案,并且直接可以使用其全部客户端!

安装

在安装之前,先仔细浏览了Bitwarden的网站和它的github仓库。

再次强调一下,Bitwarden本是也有免费版的,使用其云服务+对应的客户端,无需成本,对于绝大多数用户和场景来说已经足够了,但是如果你和我一样希望把数据留在自己的存储器里,那么接下来就跟着我做吧。

由于Bitwarden官方的server比较复杂,使用了Mysql作为存储,一套下来系统资源消耗较大,今天我用的是一个非官方server,是用RUST实现了所有Bitwarden的Api,它就是 VaultWarden,github仓库在这里:https://github.com/dani-garcia/vaultwarden

运行

VaultWarden使用sqlite3作为存储,并且支持docker安装,那么就按这个方式来安装

首先下载docker镜像,注意运行命令时当前用户,如果提示权限错误拒绝访问等等,要在命令前加上sudo运行

docker pull vaultwarden/server:latest
docker run -d --name vaultwarden --network myhome -v /vw-data/:/data/ --restart always -p 81:80 vaultwarden/server:latest

第二行我解释一下,"-d"表示以daemon方式后台运行,"-v /vw-data/:/data/" 表示将本机的"/vw-data/" 目录映射到 容器的 “/data/“目录,这里的”/vw-data/“可以替换成你自己的保持位置。”–restart always"表示容器会自动重启,"-p 81:80” 表示将本机的81端口映射到容器的80端口,注意冒号左边是本地,冒号右边是容器,本地只能有一个服务占用81端口,因为本机只有65535个端口,而每个容器都可以有65535个端口。注意本地端口不要冲突,否则容器启动会失败。

启动成功后我们就可以在Portainer或者其他容器可视化UI里看到了

顺便我看了下容器的log

配置SSL

VaultWarden需要配置SSL才能使用,而我的NAS是位于家庭主路由器后面,并且我需要在外网能访问我自己的密码保管箱,我使用的是内外穿透nps,我有自己的公网VPC,所以我只需要在我的公网VPC的Nginx上添加SSL并转发给nps再到内网的6666这个端口上即可。

我画了个图,比较丑哈哈

解释一下上图,我进行了必要的简化以便突出本次的主题。

外网的Nginx首先会自动转换80端口到443端口,所有请求都必须走443,再给对应的dns域名配置location,这里就是本机6667端口,为了读者能区分开端口号我特地用了一个不同的。6667端口是什么端口呢,这个是需要在nps里面进行设置的,即增加一条TCP通道,从本机6667到目标地址192.168.8.8:6666,后者是我们在内网的地址,不会搭建TCP隧道的,请参考《内网穿透很简单:搭建nps服务》。在内网这边,因为我的相关服务都是安装在docker里的(这样便于管理),npc就是nps的客户端,安装后就不用管他了。vaultbarden是本次的主角,在docker命令中我设定了6666到80的端口映射。

注意:内网穿透经常会搞错的一个地方是目标地址的ip和端口匹配关系,在上图中,由于npc是在NAS中,docker网络配置为桥接,所以npc本是也是可以访问到192.168网段的,并且6666端口经由vaultwarden容器的80端口就可以到达服务本身。注意如果nps中填写的目标地址的192.168.8.8那么端口号只能是vaultwarden映射出来的6666,如果nps填写的目标地址是172.17.x.x,那么目标端口号必须为60。这里可以把TCP隧道理解为一辆货车把货物运到目标地址去,那么他的货的地址必须是被收货人所接受的地址,否则匹配有问题就会导致请求无法被处理。

完整的流程是,nginx通过匹配dns域名找到对应的配置,反向代理到本机6667端口,6667端口是一条TCP隧道,所以数据被发送到隧道的另一端,即npc所在的子网里,端口号为6666,(上面已经解释了除了192.168.8.8:6666是可以的,还有172.17.x.x:80以及vaultwarden:80这样也是可以),这样就完成了一次请求,我们的内网服务已经可以在外网使用了,并且是ssl的。

参考《容器化安装Nginx》,《内网穿透很简单:搭建nps服务》

客户端下载

虽然服务端我们安装的是vaultbarden,但是客户端我们是可以用BitBarden的,它支持所有平台以及主流浏览器插件,客户端下载地址https://bitwarden.com/download/一网打尽

客户端连接

第一次登录

打开https://vault.mydoman.com, 【注意这个地址是用于教程协作的,并不是我真实的dns】,进行Sign Up或者Create a account,输入email地址,在email框下面有一行小字,可以切换服务器,选择“Self Hosted”即自建的服务器,按照提示输入master password,注意一定要妥善保管主密码,泄露主密码等于把保险箱打开了送人哈哈

使用

客户端支持丰富的多语言,可以切换成中文

由于经常输入主密码很麻烦,我在手机和电脑上都设置了生物检测即指纹识别

后安装事宜

最重要的是取消注册功能,在docker的环境变量中添加SIGNUP_ENABLED=false,并重启vaultbarden容器即可生效

By 大可出奇迹