Bitwarden启用Websocket及加固指南
2021年之前我一直使用的LastPass做为我的首要密码管理工具,当时被他的浏览器拓展吸引,搭配这个插件可以做到自动填充,使用起来十分愉快。不过因为LastPass后台一直没有中文语言,且21年期间还出现了国内偶发性打不开网页的问题(刚刚查资料还发现2022年12月爆发过一次安全事故,不过算是躺锅)。
知名密码管理器 LastPass 此前因 Authy 员工被钓鱼而出现安全事故,这话听着有点绕口,大概是这么个情况:多因素认证器 Authy 员工收到钓鱼邮件后泄露了密码,黑客入侵了 Authy 的服务器窃取了 LastPass 工程师账户的 2FA,当然估计黑客也提前通过其他方式获取了这名工程师的账号密码,最终结果就是 LastPass 被黑了。
那之后我就在V2ex上寻求替代产品,基于Selfhost的理念我最终选了Bitwarden作为自己的密码管理软件,并撰文 docker 自建 bitwarden 服务 记录了搭建过程,一直愉快的使用至今。
不过使用期间发现了一些问题,如:
- 所有平台增加完密码记录后如果想所有平台都同步的话,需要先在该平台手动同步密码库,且其他需要使用的平台也要手动同步密码库才能收到更新。
- 浏览器端、桌面端的「使用设备登录」功能无法使用,虽然开启了该功能,但是手机上始终接受不到登录请求。
- 无法使用webauth功能。
我之前猜测是自己的那里设置没有弄对,期间也查阅过资料,但是都无果而终。
好在最近偶然间查阅Bitwarden版本更新信息时发现了提到「移除以前关于Websocke变量设置」的关键字,便对方面进行了相关资料查询,发现果然是自己的搭建出了问题,Nginx的WebSocket功能没有正常启用,自然相关的实时同步、使用设备登录等功能都无法使用,今天摸索一番后终于修复了该问题。
确认WebSocket是否开启
根据 6.启用 WebSocket 通知 所述,检查WebSocket是否启用的方式有2种
- 打开浏览器的开发人员工具,转到网络选项卡然后筛选
WS
/WebSockets
。注销或刷新页面并再次登录,您应该会看到升级后的 WebSocket 连接的 101 响应。如果您单击该行,您应该能够看到消息。如果您没有在/notifications/hub
上获得状态代码 101,则表示某些配置不正确。消息将显示在浏览器的控制台窗口中:[2023-12-01T00:00:00.000Z] Information: WebSocket connected to wss://HOST_NAME/notifications/hub?access_token=eyJ0eX......
- 2.打开两个不同的浏览器或隐身/隐私窗口。在两个浏览器上登录您的帐户。创建一个新的条目,或者重命名一个条目,在另一个浏览器中应该会立即收到更改。
我当时根据第一项检查就发现结果是400还是多少来着,完全就没通。所以我查找了一些资料,最终通过修改Nginx配置正确启用了WebSocket
- 定义header要用到的参数词典(个人理解,类似定义变量)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
- 修改bitwarden在nginx中location内的设置,增加如下配置
# websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
最终完整配置如下
运行 nginx -s reload
重载Nginx配置即可,现在可再根据前面的方法测试是否开启成功。
安全加固
同时,我在该wiki中找到了一篇 安全强化指南 ,虽然自己之前也有做过一些安全强化,但是还有不足的地方,遂重新根据该指南做了强化,并挑了几条我做了的作为展示。
高强度主密码
一定要使用一个你从来没在互联网上使用过的密码,大小写符号都带上,长度最好在12位以上。
随机子域名或隐藏在子目录下
- 随机子域名:也就是没有固定含意的子域名,如:
https://fjisjfasjfois.yourdomain.com
,这个比较简单,更改域名绑定即可。 - 隐藏在子目录下:你可以在随机子域名的情况下再隐藏在子目录,如:
https://fjisjfasjfois.yourdomain.com/ofjiosnvoxz
,这有个官方的caddy示例,nginx的可以自己找找。
mysubdomain.example.com {
route {
reverse_proxy /my-custom-path/* 10.0.0.150:8083 {
header_up X-Real-IP {remote_host}
}
handle /* {
abort
}
}
}
禁用新用户注册&邀请注册
如果是自己使用则完全可以禁用掉这两个选项,避免居心叵测的人注册后做一些渗透行为。在docker-compose文件中增加环境变量 SIGNUPS_ALLOWED: "false"
即可。或增加在run命令中 -e SIGNUPS_ALLOWED=false
。
禁用显示密码提示
Vaultwarden 在登录页面上显示密码提示,以适应没有配置 SMTP 的小型/本地部署,这可能被攻击者滥用,以方便对服务器上的用户进行密码猜测攻击。可以在管理面板中通过取消勾选 Show password hints
选项或使用环境变量来禁用它。
以非 root 用户运行
Vaultwarden Docker 镜像被配置为默认以 root 用户的身份运行容器进程。
这允许 Vaultwarden 读取/写入 bind-mounted 到容器中的任何数据,而无需权限问题,即使这些数据是由另一个用户(例如,你在 Docker 主机上的用户账户)拥有的。默认配置在安全性和可用性之间取得了很好的平衡——在一个非特权 Docker 容器中以 root 身份运行,本身就提供了合理的隔离级别,同时也让那些不是非常精通如何在 Linux 上管理所有权/权限的用户更容易进行设置。
然而,作为通用策略,从安全的角度来说,以所需的最低权限运行进程是更好的;对于用 Rust 等内存安全语言编写的程序来说,这一点就不那么重要了,但请注意,Vaultwarden 也使用了一些用 C 语言编写的库代码(例如 SQLite、OpenSSL、MySQL、PostgreSQL 等)。
要在 Docker 中以非 root 用户 (uid/gid 1000) 的身份运行容器进程 (vaultwarden):
docker run -u 1000:1000 [...other args...] vaultwarden/server:latest
在 docker-compose
中类似操作:
version: '3'
services:
vaultwarden:
container_name: vaultwarden
image: vaultwarden/server:latest
restart: always
user: 1000:1000
ports:
- 521514:80
environment:
DOMAIN: "https://yourdomain.com"
WEBSOCKET_ENABLED: "true" #是否开启WebSocket
SIGNUPS_ALLOWED: "false" #是否开启注册,自用的话自己搭建好注册后改成false
WEB_VAULT_ENABLED: "true" #是否开启Web客户端
volumes:
- /home/data/vaultwarden/:/data/
此时你需要执行 docker exec -it vaultwarden bash 进入容器内部,再进入根目录中的 /data 目录中,执行 chown -R 1000:1000 改更文件所属用户。
使用2FA
推荐一定要使用2FA做两步验证,避免暴力破解,并且,我在这里希望大家所有的重要服务最好都能开启2FA,这能极大程度的增加你的账户安全性。如果你不知道什么工具,可以参考我这篇 AuthenticatorPro 开源的本地两步验证工具使用教程
当不使用双重身份验证时,(理论上)有可能对用户的密码进行暴力破解,从而获得对其账户的访问权限。缓解此问题的一种相对简单的方法是设置 fail2ban,设置后,在过多的失败登录尝试后将阻止访问者的 IP 地址。但是在许多反向代理(例如 cloudflare)后面使用此功能时,应格外注意。参阅:Fail2Ban 设置。
End
至此基本上我们能做的都做完,目前市面上的这些数据库密码管理程序都是加密对数据做存储的,只要能保证你的主密码不泄露,即便是密码库被拿走了也不用担心数据泄露的问题。
加入评论