Repository navigation
控制面统一鉴权,以及原生客户端需要的接口 #134
Replies: 7 comments
|
你好,谢谢你写得这么细,提 PR 前先来讨论这个做法很好。下面说说我的想法,供参考。 1. 统一鉴权现状你说得没错:两个 WebSocket 端点各自调用
2. iOS 客户端需要的接口我觉得分成独立 PR 进来挺好。下面是我想到的几点,供你设计时参考:
顺序上,我的想法大致是:鉴权第 1、2 步 → 设备令牌(含授权与审计)→ 响铃查询 → Call-Id → APNs。仅供参考,你按实际开发节奏调整也完全可以。 关于接手客户端仓库:非常感谢你的信任。坦白说,我这边暂时没有条件测试 CallKit 和 PushKit,担心接过来后维护不好,反而对用户不负责。我的想法是仓库先留在你那边,发布可用版本后我在 README 里链接过去,并注明它是社区项目。以后如果情况变了,我们再聊。 3. 关于 #102 / TURN内置 coturn 这个方向,我目前还是有些顾虑,改成默认关闭也一样。我担心的主要不是"开没开",而是它会改到本来就会执行的路径:
我的一个想法是改做 "外部 TURN 服务器"设置:用户在网关里填自己的 TURN 地址和凭据(可以是自建的 coturn,也可以是任何 TURN 服务),网关通过接口把 另外,离开局域网时也可以走 Tailscale 或 WireGuard,不需要 TURN,这个我会在文档里补充说明。 以上都只是我的想法,欢迎继续讨论,再次感谢! |
|
@MddIdd 谢谢详细的回复。这里先把 #102 的来龙去脉说清楚。 为什么需要中继 我们在做 iOS 客户端,客户端不能靠 VPN 接入内网:来电时 App 是被推送临时唤醒的,要在很短时间内直接连上网关,CallKit 才能正常响铃和接通。iOS 同一时间只能有一个 VPN,也无法保证唤醒那一刻 VPN 已经连上。所以网关必须能从公网直接访问。 信令走 HTTPS/WSS,一个端口就够了;难的是通话媒体。不用中继的话,就要把每条线路 12–60 个 RTP 端口都转发到公网:端口数量随线路增减而变,公网上任何人都能直接向 Asterisk 的 RTP 端口发包,客户端所在的网络也常常拦截高位 UDP 端口。中继让网关对外只开一个固定端口,只有拿到网关签发的临时凭据的客户端才能使用,还可以回退到 TCP/TLS。外部 TURN 在容器运行环境下访问不到内部网络上的引擎,所以需要网关自带。 为什么 #102 改了网络、加了防火墙 中继对公网开放,它就是外部进入内部的入口,必须限制它只能碰到引擎的通话媒体。 针对你的三点顾虑:
我们建议中继默认开启:开启后引擎不再需要对外发布 RTP 端口段,所有外部媒体都只能经过一个需要凭据的入口,这本身就是一次权限收紧。 中继不可达时的提示 #102 里已经实现了:浏览器连不上中继,8 秒内结束呼叫并说明原因。这也顺带解决了现在的一个假象:VoWiFi 显示已注册,但 RTP 端口不可达时没有任何提示,用户只看到通话失败,不知道问题出在哪。 提 PR 前我们会在测试机上验证注册、重新接入和通话。 你看这个方向可以的话,我们就关掉 #102,按这个范围重新提。 |
|
谢谢解释得这么清楚,推送唤醒和 VPN 冲突这一点我之前确实没考虑到,远程媒体需要一个公网可达的入口,这点我认同。 在决定具体做法之前,想和你一起把几种可能的方案比较一下,看看哪种对客户端和对网关用户都比较合适。 先补充一个情况: 现在引擎的 RTP 端口本来就发布在主机上( 我目前想到的几种:
我现在的初步想法是,可以先从方案 2 开始(顺带把方案 1 的公网地址设置做了):改动小,不引入新组件,iOS 客户端先用起来,也能积累真实的使用反馈;以后如果发现很多用户部署 TURN 有困难,再考虑把中继内置进网关。那时现有的接口(凭据下发、 当然,你们实际做了客户端,对使用场景比我了解,所以想先听听你们的意见:
另外,不管最后选哪种方案,既然网关要对公网提供服务,我觉得 #134 里鉴权的第 1、2 步最好先合入,你觉得呢? 再次感谢! |
|
@MddIdd 谢谢把几种方案列得这么清楚。你说得对,局域网内的 TURN 是能访问到引擎的,我们之前那句说法不准确。 我们倾向方案 3(内置中继)。 理由主要是两点: 外部部署拿不到 Docker 原生部署的安全边界。 中继只要被拿到凭据,就能替人访问它能到达的地址。内置时,中继只在一个 internal 的媒体网络上,只看得到引擎。外部 TURN 最多只能限制到"只能转发到网关主机",端口级的限制 coturn 本身做不到,只能由用户在 TURN 所在机器上手写防火墙,并随线路增减手动维护,配错就是一个通往局域网的开放中继。 我们考虑在方案3的基础上增加两种模式的选择: 网关增加一个媒体模式设置,默认是直连,也就是现在的行为,代码路径完全不变。启用中继后,按中继的前提把直连需要的补丁都去掉: 引擎不再发布任何端口; 切换 切换由安装脚本完成,WebUI 上只显示当前模式和中继状态。因为端口发布在创建容器时就定了,切换需要重建所有引擎,线路会重新注册;另外还涉及建网络、拉镜像、放行端口,这些本来就是安装脚本的事。 启用时先准备、验证,再切换:创建媒体网络、拉取镜像、生成密钥、启动中继并通过健康检查,全部成功后才写入设置并依次重建引擎。任何一步失败都会清理掉已做的部分,保持直连模式,报出原因后退出,不会留下半套中继。关闭时反过来,删除中继、恢复端口发布。线路原有的端口分配一直保留,切回直连不需要重新分配。 降级 更新时: 只有启用了中继才拉取中继镜像。拉取失败就继续用旧镜像,更新照常完成,并提示没有拿到新版本。 另外两点:媒体网络设为 internal,不指定网段,由 Docker 分配;目前我手头没有 Pi,无法在 Pi 上实测资源占用。根据预估,中继模式不会带来太多资源占用,可以并行测试一段时间的之后,再考虑两种模式的去留。 关于鉴权: 第 1 步已经提交在 #178,第 2 步(凭据来源表)会在它之后提交。中继和客户端的接口都排在这两步后面。 再次感谢! |
|
谢谢,这版设计很清楚。"直连 / 中继"两种模式各走各的代码路径,默认直连、行为不变,切换时先准备、验证,失败就清理,这几点我都很认同。方向上我没有问题,可以按这个思路来做。#178 我会尽快看。 下面几点想法,供实现时参考: 1. 防火墙放在哪一侧 我的想法是把规则放在引擎一侧:引擎本来就有 2. ICE 候选和 IMS 那条腿 3. 切换脚本 4. 资源实测 顺序上就按你说的来:#178 → 凭据来源表 → 设备令牌 → 中继和客户端接口。再次感谢! |
Uh oh!
There was an error while loading. Please reload this page.
你好,想在提 PR 之前先确认两个方向。
1. 鉴权与授权集中到一处
require_admin_session默认保护所有/api/*,这个做法是对的。但有几处可以收紧:/ws和softphone/ws各自调用auth.session(...)。新增的 WebSocket 端点如果忘了检查,就是默认开放的。提议拆成几个小 PR:
principal(scope)统一回答"这是谁"。authorize(principal, method, path):现有权限保持不变,未声明的路由一律拒绝。如果你认可,我们就按这个顺序逐个提交 PR。
2. 原生 iOS 客户端
我们在做一个原生 iOS 客户端(CallKit、PushKit、WebRTC、原生短信彩信界面),放在独立仓库,只通过网关的 HTTP/WebSocket 接口通信,不是外部 SIP 账号。
它不上架、不提供 TestFlight,需要的人自己构建。免费 Apple ID 构建的版本只能在前台使用;锁屏来电需要构建者自己的付费开发者账号,并在自己的网关里填入自己的 APNs 密钥。
客户端需要网关提供:
Authorization: Bearer发送(即第 1 节凭据来源表里的一条)。UNIQUEID(X-MDD-Call-Id),让被唤醒的手机认出是同一通来电。想请教两点:
请看看这两个方向是否合适,谢谢。
All reactions