Trunk 是运营商判定你的设备可以发送和接收哪些通话的边界。如果你有 PBX(为你的通话做路由的企业电话系统)、会话边界控制器、呼叫中心平台或任何其他 SIP 客户端,trunk 就是它的通话到达外部世界以及外部通话到达它的通道。会话边界控制器是守护语音网络边缘的设备。
第一个问题通常是你到底需不需要 trunk,答案是需要。不同的只是你在它后面放什么。
我真的需要 trunk 吗?
需要。不同配置之间的区别在于你这一侧的客户端,而不是是否存在 trunk。
往返电话网络的每一通电话都会经过 trunk,因为 trunk 是平台决定是否接受该通话的地方。常见的有两种形态:
- 你有电话系统。 PBX、软交换或呼叫中心平台已经在处理通话,需要一条通往公共网络的路由。它作为对等方连接,通常来自固定地址,由它自己的拨号计划(路由通话的规则)来进行呼叫控制。
- 你有应用代码。 你希望你的软件在不运行电话基础设施的情况下发起或接收通话。你仍然需要一个 trunk,与它通信的东西可以很小:软电话、浏览器、CLI,或者语音代理运行时。它使用短期会话凭证(为 SIP 客户端生成的临时用户名和密码)进行认证,而不是从已知地址的设备进行连接。
区别在于呼叫控制放在哪里,而不在于规模,两种形态都不能跳过 trunk。轻量客户端帮你省去的是运行电话系统,而不是连接本身。Bird 自身的工具就说明了这一点:仪表板的电话和 CLI 的测试呼叫都是 SIP 客户端,通过你的某个 trunk 发起真实通话。
Trunk 也不是 API 的替代品,因为没有任何端点能直接向你选择的目的地发起呼叫。什么是语音 API介绍了配置部分和信令部分如何分工。
Trunk 到底做什么?
它为你的设备提供一个发送通话的地址,并决定接受哪些通话。
Bird 为每个 trunk 分配一个固定的 SIP 域名,你将其填入电话系统,使通话能够关联到该 trunk。你的设备通过三种传输方式之一向该域名发送:5060 上的 UDP 或 TCP,或者 5061 上的 TLS(当你希望信令在传输中加密时)。
新创建的 trunk 会拒绝每一通电话。 两个方向默认关闭,也没有已授权的发送方。这是刻意的默认行为,而不是不完整的配置。一个刚创建就接受通话的 trunk 等于敞开大门,而话费欺诈会迅速让代价变得高昂。
为什么出站和入站要分开配置?
因为它们是不同的问题,有不同的故障模式,trunk 独立承载每个方向。
出站是你的电话系统通过 Bird 发起通话。在启用之前,trunk 会拒绝每一次出站尝试,不论凭证是否正确,因此即使认证通过的通话在方向关闭时也会失败。
入站是 Bird 将指向该 trunk 的号码的来电投递到你的电话系统。仅启用入站是不够的:启用了入站但没有配置投递网关的 trunk 会拒绝其号码上的每一通来电。将号码指向 trunk 的操作是在号码上而不是在 trunk 上完成的,这是人们经常遗漏的另一半。
关闭入站会将指向该 trunk 的每个号码恢复为拒绝状态,重新打开入站也不会恢复它们。 删除 trunk 效果相同。所以撤销不是对称的:如果你为了测试而关闭入站,请准备好之后重新将每个号码指向 trunk,并检查号码状态,而不要假设开关已经恢复了它们。
Trunk 如何决定谁可以向它发送通话?
IP 允许列表、API 密钥认证和会话凭证共同决定。它们可以组合使用,每一种在有了第一个条目后就会生效。
IP 允许列表。 添加你的设备向 SIP 发送时使用的公网地址。列表中有了第一个条目后过滤就会开始,此后只有列出的地址范围才能发送通话。对于在 NAT 后面的设备,这里填的是路由器的公网地址,而不是电话系统的私有地址。来自未列出地址的通话会在 SIP 层被拒绝,通常不会出现在通话日志中。因此空日志是这种情况的症状,而不是没有尝试过的证据。
API 密钥认证。 Bird 对通话发起质询,你的系统用密码的哈希值而不是密码本身来应答。哈希值会与一个拥有语音写入权限的 Bird API 密钥进行验证。在你的 PBX 中,用户名始终是 bird,密码是该密钥的 secret。与 IP 列表一样,一旦允许了一个密钥,它就变为排他性的。
由此产生两个运维细节。移除密钥的语音权限会立即阻止其认证。该密钥会保留在 trunk 的允许列表中并带有标记,这样列表就不会显示为可用而实际上不可用。恢复权限后无需其他更改即可恢复。吊销或删除密钥会立即对所有允许了该密钥的 trunk 生效,且不可逆。轮换密钥的方法是:先将新密钥添加到 trunk,再将设备切换过来,最后吊销旧密钥。
会话凭证。 短期的 SIP 用户名和密码,通过相同的质询应答机制完成认证,避免暴露长期密钥。新创建的 trunk 默认关闭会话凭证,且凭证属于工作区而非单个 trunk。密码仅在生成时返回一次。
开启会话凭证不会改变允许列表中设备的连接方式。来自已列出地址的通话,在 trunk 没有允许任何 API 密钥的情况下,仍然无需密码质询即可接入。如果你本打算让凭证作为门槛,IP 列表其实仍在悄悄充当门槛。
为什么我的浏览器或软电话认证失败?
几乎总是摘要算法的问题。它是唯一一个会以看起来像凭证问题的方式失败的设置。
默认情况下 Bird 先提供 SHA-256,其次是 MD5,你的设备选择它支持的第一个来应答。Trunk 只接受它所提供的算法,因此缩小提供范围就会缩小可连接的设备范围。
陷阱在浏览器:浏览器只会用 MD5 应答,别无其他。仅提供 SHA-256 的 trunk 会拒绝所有浏览器通话,包括仪表板自带的电话。因此,在任何你打算从浏览器发起通话的 trunk 上保留 MD5 提供选项;仅在 PBX 无法正确处理以 SHA-256 开头的质询时才切换到仅 MD5。API 密钥兼容两种算法,更改提供选项时无需重新签发。
那我应该配置什么?
- 一个 trunk,无论你属于哪种形态。 每一通电话都会经过 trunk,所以这一步不可省略。
- 一个对等方,如果你运行电话系统。 将 PBX 或呼叫中心平台从固定地址连接,由其拨号计划控制通话。
- 一个轻量客户端,如果你有应用代码。 软电话、浏览器、CLI 或代理运行时,使用短期会话凭证而非已知地址进行认证。
- 一条发送方规则,无论你选择了哪种方式。 IP 允许列表、已允许的 API 密钥或会话凭证,注意每一种在有了第一个条目后就会变为排他性的。
- 在摘要提供选项中保留 MD5,适用于任何你打算从浏览器发起通话的 trunk。
SIP trunks介绍每项设置及其位置。SIP 客户端介绍如何连接单个客户端而非电话系统,语音故障排查帮助你排查未到达的通话。
简而言之
通往电话网络的每一条路径都会经过 trunk。
区别在于你这一侧的客户端:作为对等方连接的电话系统,或者更轻量的 SIP 客户端(如浏览器或使用短期凭证的 CLI)。
新创建的 trunk 会拒绝一切。
两个方向默认都是关闭的,在你添加之前没有任何已授权的发送方。这是刻意设计,而不是可以跳过的配置步骤。
每个方向单独启用,入站需要网关。
启用了入站但没有配置投递网关的 trunk 会拒绝其号码上的每一通来电。
关闭入站不会干净地撤销。
指向该 trunk 的每个号码都会回到拒绝状态,重新打开入站也不会恢复它们。你需要自己重新将每个号码指向 trunk。