解决群晖 Vaultwarden WebSocket的问题

更新时间:2023年7月29日00点30分


Vaultwarden可以在服务端与客户端实时同步,通过持久的WebSocket连接实现[1],因此仅限于浏览器插件和桌面软件,移动端的同步则需要在APP上手动刷新。

v1.29.0 升级说明

Vaultwarden 升级到 v1.29.0以上版本后 WebSocket 通过 Rocket 连接(默认启用),将不再需要单独的端口。旧的实现在v1.29.0中仍然可用,但这将在未来被删除。
可以在配置文件“.env”中“WEBSOCKET_ENABLED=false”关闭旧的 WebSocket 连接。

Nginx反代仍然需要设置Upgrade、Connection。以下配置方式Vaultwarden不再需要,不过可以作为群晖自定义Nginx配置的示例。

配置步骤

想要启用WebSocket通知,首先在.env或环境变量中设置字段:WEBSOCKET_ENABLED=true,如果通过Dcoker 桥接,将WEBSOCKET_PORT端口映射到外部环境(默认为3012),并在路由器上转发。

然后配置反向代理,官方WIKI[2]上展示了一些配置示例,然而群晖自带的ngnix服务器是魔改版,无法在UI上对主机根目录以外进行设置,网上找的脚本[3]或配置方式[4]在DSM 7.1-42661上实测已失效。

群晖用户设置的ngnix规则,存于/usr/local/etc/nginx/sites-available/这个目录,并软链接到/etc/nginx/sites-enabled//usr/local/etc/nginx/sites-enabled/中,每次系统重启或者网站设置发生变化时,里面的配置都将根据模板重置,对文件的修改会丢失,解决的方法之一是用定时脚本自动添加;或者修改默认模板,下面介绍一种对系统文件改动最小同时又一劳永逸的办法(部分参考[5]),这也将方便导入其他ngnix手动配置文件。

  1. 在NAS存储库目录中创建目录,以docker为例,路径如:/volume1/docker/nginxCustomConf,并创建子目录conf.dbackup,分别用于存放自定义配置和备份,如果需要导入证书,则再创建一个目录ssl

  2. conf.d目录下新建配置文件Vaultwarden.conf,粘贴以下内容并替换其中的参数:

server {
    listen PROXY_PORT ssl;
    listen [::]:PROXY_PORT ssl;
    server_name your_domain;
    ## 这表示限定入站的主机名,可不写。
    # if ( $host !~ "(^your_domain$)" ) { return 404; }
    
	## SSL配置
    #ssl_certificate /path/to/certificate/letsencrypt/live/vaultwarden.example.tld/fullchain.pem;
    #ssl_certificate_key /path/to/certificate/letsencrypt/live/vaultwarden.example.tld/privkey.pem;
    #ssl_trusted_certificate /path/to/certificate/letsencrypt/live/vaultwarden.example.tld/fullchain.pem;

    add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload" always;
    proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    location / {
        proxy_connect_timeout 60;
        proxy_read_timeout 60;
        proxy_send_timeout 60;
        proxy_intercept_errors off;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Connection "";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://localhost:ROCKET_PORT;
    }
    location /notifications/hub {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
        proxy_set_header Host $host;
        proxy_set_header Forwarded $remote_addr;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://localhost:WEBSOCKET_PORT;
    }
    location /notifications/hub/negotiate {
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://localhost:ROCKET_PORT;
    }
    error_page 403 404 500 502 503 504 /dsm_error_page;
    location /dsm_error_page {
        internal;
        root /usr/syno/share/nginx;
        rewrite (.*) /error.html break;
        allow all;
    }
}
  • PROXY_PORT:反向代理的https端口。
  • ROCKET_PORT:Vaultwarden映射后的web端口。
  • WEBSOCKET_PORT:Vaultwarden映射后的socket端口。
  • your_domain:你的域名。
  • SSL配置:参考sites-enabled目录下的server.ReverseProxy.conf,复制其中的证书配置,或者手动导出的证书存放位置:
    ssl_certificate /volume1/NginxCustomConf/ssl/xxx.crt;
    ssl_certificate_key /volume1/NginxCustomConf/ssl/xxx.key;
  1. 如果已经在DSM控制面板中设置了Vaultwarden的反向代理,务必删除。

  2. SSH登录到Synology系统,切换到超级管理员,跳转到ngnix配置模板所在的目录/usr/syno/share/nginx/,备份后修改nginx.mustache模板,命令:

sudo -i
cd /usr/syno/share/nginx
cp nginx.mustache /volume1/docker/nginxCustomConf/backup
vi nginx.mustache
  1. 在模板倒数第二行添加一行:
# Copyright (c) 2000-2017 Synology Inc. All rights reserved.
    ......
    ......
    include conf.d/http.*.conf;
    include sites-enabled/*;
    # 下面一行为我们添加的内容
    include /volume1/docker/nginxCustomConf/conf.d/*;
}
  1. 重启系统,注意仅重启nginx并不会生效(也许是DSM系统命令的问题,DSM 7的nginx重启命令为synosystemctl restart nginx,重新导入synosystemctl reload nginx)。

  2. 重启后测试下实时同步是否生效。此后其他主机的自定义配置都可以在conf.d目录下添加。

注:此办法在系统升级后会失效,需要重新在nginx.mustache模板添加行,解决方式有两种:

  1. 方式一:使用触发式脚本自动重写nginx.mustache
  • 在群晖控制面板——任务计划中新增触发的任务——用户定义的脚本;

  • 用户账号选择root,选开机事件:

  • 在用户设置中粘贴以下脚本,它会检查nginx.mustache是否包含用户自定义的规则目录,如果没有则插入,并重启Nginx以生效。
#!/bin/sh
FIND_FILE="/usr/syno/share/nginx/nginx.mustache"
FIND_STR="    include /volume1/docker/nginxCustomConf/conf.d/*"
# 判断匹配函数,匹配函数为0,则不包含给定字符
if [ `grep -c "$FIND_STR" $FIND_FILE` -eq '0' ];then
    cp /usr/syno/share/nginx/nginx.mustache /volume1/docker/nginxCustomConf/backup
    sed -i '$i\    include /volume1/docker/nginxCustomConf/conf.d/*;'  $FIND_FILE
    # nginx重启,注:此命令适用于DSM7.0以上,DSM6改为:synoservice -restart nginx
    synosystemctl restart nginx
    # nginx重载
    synosystemctl reload nginx
fi
exit 0
  • 此任务可手动运行,或重启系统检查下是否生效。

2.方式二:使用Nginx Proxy Manager(NPM)替代群晖自带的反向代理工具,安装教程参考老苏的博客[6],在此不赘述,只提醒下注意事项:

  • NPM无法像群晖自带的nginx那样侦听多个入站端口,所有的外网访问或通过frp内网穿透或通过路由器上的端口转发到NPM的443端口才能被代理;
  • NPM的代理主机域名也不支持用域名+端口,尽管可以填入,但是并不会生效。
  • 因上两条,NPM只能用不同的子域名来访问内网不同端口下的服务,也就是说你需要拥有自己的顶级域,此种方式不适用于群晖上可以免费申请的二级域名。

配置成功后来看下实时同步演示:

Vaultwarden实时同步演示

附述:

Vaultwarden是一个优秀的第三方替代Bitwarden API的项目,可完美兼容Bitwarden全平台客户端,和官方服务端相比少了与移动客户端实时同步和一些组织的功能[7],但安装所需的系统环境门槛更低,运行消耗资源更少。这个项目已趋于成熟,没踩什么坑,除了这个socket配置略显麻烦(主要是群晖系统带来的),还有就是要在环境变量中设置TZ参数,否则可能会在某些网站上因为时区不一致没法设置2FA & TOTP两步验证。

值得注意的是,Vaultwarden相比Bitwarden缺乏严格、专业的代码审计,这意味着每次更新都需谨慎;另一方面,Bitwarden具有可持续的盈利方式,可以不断地更新迭代,而Vaultwarden不能保证跟上,虽然目前来说完全够用,在GitHub上的Star数也超过了Bitwarden,但无法肯定能否成为长期托管方案,现在的主要目的是为了减少服务器的开销。


  1. Enabling WebSocket notifications · dani-garcia/vaultwarden Wiki (github.com) ↩︎

  2. Proxy examples · dani-garcia/vaultwarden Wiki (github.com) ↩︎

  3. Synology Bitwarden_rs Websocket setup without SSH (github.com) ↩︎

  4. vaultwarden (bitwarden) nginx configuration on synology NAS (DSM 7 compatible) using synology docker (Supporting bitwardens LiveSync with Websocket configuration) (github.com) ↩︎

  5. 群晖使用自有 Nginx自定义配置 - LoveXu (lox.im) ↩︎

  6. 反向代理服务器nginx-proxy-manager ↩︎

  7. Home · dani-garcia/vaultwarden Wiki (github.com) ↩︎