解决自托管 Bitwarden + CloudFront 不能登录问题
用EC2上自托管Bitwarden 有一段时间了,处于安全性考虑,打算使用 AWS CloudFront 作为 Bitwarden 自托管实例的 SSL 卸载和 CDN 网络加速,用户访问路径变成这样:
但是通过 Cloudfront 绑定的自定义域名访问时遇到了登录失败的问题,用任何用户尝试登录时会收到这个报错:
An error has occurred.
can't access property "toLowerCase", e.message is undefined
在浏览器控制台查看到 WebSocket 连接失败的日志:
[SignalR] Failed to start the connection: Error: WebSocket failed to connect.
The connection could not be found on the server, either the endpoint may not be a SignalR endpoint,
the connection ID is not present on the server, or there is a proxy blocking WebSockets.
问题分析
经过多次尝试,排查了密码错误,数据库连接问题,API 接口问题,最后聚焦在分析 WebSocket 连接失败的原因:
- Bitwarden 使用 SignalR 进行实时通信(推送通知、多设备同步等)
- CloudFront 默认不支持 WebSocket 连接转发
- WebSocket 连接失败导致整个登录流程异常
解决方案:配置 CloudFront 支持 WebSocket
1. 登录 CloudFront 控制台配置
首先进入 CloudFront 控制台,找到 your.custom.domain
对应的分配,点击分配 ID,然后编辑 Behavior:
- 点击 Behaviors 标签
- 选择默认行为(通常是 *),点击 Edit
关键配置更改:
Cache key and origin requests 部分:
• **Cache policy**: 选择 CachingDisabled
• **Origin request policy**: 选择 CORS-S3Origin
2. 或者通过 AWS CLI 配置
首先查找目标分配:
aws cloudfront list-distributions --query 'DistributionList.Items[?Aliases.Items[0]==`your.custom.domain`].[Id,Status]'
获取当前配置:
aws cloudfront get-distribution-config --id EXXXXXXXXXXXXX
更新配置以支持 WebSocket:
aws cloudfront update-distribution \
--id EXXXXXXXXXXXXX \
--if-match ETAGEXAMPLE123 # 匹配当前ETag版本\
--distribution-config '{
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"OriginRequestPolicyId": "216adef6-5c7f-47e4-b989-5492eafa07d3",
...其他配置
}'
关键配置说明:
Cache Policy: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad
(CachingDisabled)
- 禁用缓存,确保 WebSocket 连接的实时性
Origin Request Policy: 216adef6-5c7f-47e4-b989-5492eafa07d3
(CORS-S3Origin)
- 转发所有必要的 WebSocket 头部:
Connection
Upgrade
Sec-WebSocket-Key
Sec-WebSocket-Version
Sec-WebSocket-Protocol
3. 测试 WebSocket 连接
# 检查 CloudFront 分配状态
aws cloudfront get-distribution --id EXXXXXXXXXXXXX --query 'Distribution.Status'
通过以上配置 CloudFront 的 Cache Policy 和 Origin Request Policy,可以解决 Bitwarden 自托管实例的 WebSocket 连接问题,最终修复了登录问题。