IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Bitwarden启用Websocket及加固指南

    1900发表于 2023-12-30 23:57:12
    love 0

    2021年之前我一直使用的LastPass做为我的首要密码管理工具,当时被他的浏览器拓展吸引,搭配这个插件可以做到自动填充,使用起来十分愉快。不过因为LastPass后台一直没有中文语言,且21年期间还出现了国内偶发性打不开网页的问题(刚刚查资料还发现2022年12月爆发过一次安全事故,不过算是躺锅)。

    知名密码管理器 LastPass 此前因 Authy 员工被钓鱼而出现安全事故,这话听着有点绕口,大概是这么个情况:多因素认证器 Authy 员工收到钓鱼邮件后泄露了密码,黑客入侵了 Authy 的服务器窃取了 LastPass 工程师账户的 2FA,当然估计黑客也提前通过其他方式获取了这名工程师的账号密码,最终结果就是 LastPass 被黑了。

    那之后我就在V2ex上寻求替代产品,基于Selfhost的理念我最终选了Bitwarden作为自己的密码管理软件,并撰文 docker 自建 bitwarden 服务 记录了搭建过程,一直愉快的使用至今。

    不过使用期间发现了一些问题,如:

    1. 所有平台增加完密码记录后如果想所有平台都同步的话,需要先在该平台手动同步密码库,且其他需要使用的平台也要手动同步密码库才能收到更新。
    2. 浏览器端、桌面端的「使用设备登录」功能无法使用,虽然开启了该功能,但是手机上始终接受不到登录请求。
    3. 无法使用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

    1. 定义header要用到的参数词典(个人理解,类似定义变量)
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
    1. 修改bitwarden在nginx中location内的设置,增加如下配置
    # websocket support
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    最终完整配置如下

    # 定义参数
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      "";
    }
    
    
    server {
        listen 443 ssl http2;
        server_name mybitwarden.com;
        
        # ssl配置
        include snippets/ssl-params.conf;
        
        location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host:$server_port; 
            proxy_set_header X-Forwarded-Host $server_name;
            proxy_pass http://127.0.0.1:123123;
    
            # webscoket配置
    	    proxy_http_version 1.1;
    	    proxy_set_header Upgrade $http_upgrade;
    	    proxy_set_header Connection $connection_upgrade;
        }
        location ~ /.well-known {
            allow all;
        }
        client_max_body_size 50m;
    }

    bitwarden的nginx配置文件

    运行 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/
    
    ⚠️
    请注意,这里我踩了一个坑:如果你之前已经运行过一次了,那么生成的数据库文件权限默认是root账户,此时如果你再更改用户,则在登录时会出现 Error saving device 的错误提示。
    此时你需要执行 docker exec -it vaultwarden bash 进入容器内部,再进入根目录中的 /data 目录中,执行 chown -R 1000:1000 改更文件所属用户。

    使用2FA

    推荐一定要使用2FA做两步验证,避免暴力破解,并且,我在这里希望大家所有的重要服务最好都能开启2FA,这能极大程度的增加你的账户安全性。如果你不知道什么工具,可以参考我这篇 AuthenticatorPro 开源的本地两步验证工具使用教程

    当不使用双重身份验证时,(理论上)有可能对用户的密码进行暴力破解,从而获得对其账户的访问权限。缓解此问题的一种相对简单的方法是设置 fail2ban,设置后,在过多的失败登录尝试后将阻止访问者的 IP 地址。但是在许多反向代理(例如 cloudflare)后面使用此功能时,应格外注意。参阅:Fail2Ban 设置。

    End

    至此基本上我们能做的都做完,目前市面上的这些数据库密码管理程序都是加密对数据做存储的,只要能保证你的主密码不泄露,即便是密码库被拿走了也不用担心数据泄露的问题。



沪ICP备19023445号-2号
友情链接