news 2026/5/2 5:08:17

Kamailio 怎样使用 STIR/SHAKEN

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kamailio 怎样使用 STIR/SHAKEN

AI 产生的文章,仅供参考

Kamailio 使用 STIR/SHAKEN 的流程相对复杂,因为它需要与外部的 STIR/SHAKEN 服务(例如 Secure Telephone Identity (STI) 证书颁发机构 (CA) 和验证服务)进行集成。Kamailio 本身不执行 STIR/SHAKEN 的签名和验证过程,而是充当一个信令代理,将相关信息传递给这些外部服务。

下面是一个详细的 Kamailio 集成 STIR/SHAKEN 的流程概述,并解释了每个步骤中 Kamailio 的作用:

STIR/SHAKEN 概述

在深入 Kamailio 流程之前,先简要回顾一下 STIR/SHAKEN 的核心概念:

  • STIR (Secure Telephone Identity Revisited):定义了如何使用数字证书对 SIP 呼叫的 From 字段(即主叫号码)进行签名,以证明其合法性。
  • SHAKEN (Signature-based Handling of Asserted information using toKENs):定义了如何将 STIR 签名作为 SIP P-Asserted-Identity (PAI) 头的一部分进行传递和验证。

STIR/SHAKEN 流程涉及的角色:

  1. Originating Service Provider (OSP):发起呼叫的运营商。负责生成 STIR 签名。
  2. Terminating Service Provider (TSP):接收呼叫的运营商。负责验证 STIR 签名。
  3. STI-CA (Secure Telephone Identity Certificate Authority):颁发用于签名的证书。
  4. STI-VS (Secure Telephone Identity Verification Service):提供签名验证服务。

Kamailio 集成 STIR/SHAKEN 的详细流程

一、 呼叫发起方 (Originating Service Provider) 的 Kamailio 配置

在呼叫发起方,Kamailio 的主要任务是将 SIP 呼叫路由到外部的 STIR/SHAKEN 签名服务,并将签名后的结果(SHAKEN 身份声明)重新插入到 SIP 消息中。

  1. Kamailio 收到发起呼叫的 INVITE 消息。
  2. Kamailio 识别需要签名的呼叫:Kamailio 需要通过某种逻辑(例如,基于主叫号码、被叫号码或特定的路由规则)来判断哪些呼叫需要进行 STIR/SHAKEN 签名。
    • Kamailio 模块:可以使用droutingdispatcher或自定义脚本逻辑来实现。
  3. Kamailio 将呼叫信息发送到外部 STIR/SHAKEN 签名服务:
    • 如何发送:这通常通过 SIP INVITE 的 REFER 方法、HTTP 请求(如果签名服务提供 REST API)或专门的 Kamailio 模块与外部服务进行交互。
      • 使用 REFER:Kamailio 可以向签名服务发送一个 REFER 消息,其中包含需要签名的 SIP INVITE 的相关信息。签名服务收到 REFER 后,进行签名,然后将签名后的 INVITE 返回给 Kamailio。
      • 使用 HTTP 模块:如果签名服务提供 HTTP/REST API,Kamailio 可以使用htablejson模块构造 HTTP 请求,将相关呼叫数据发送给签名服务,并解析签名服务返回的响应。
      • 自定义模块/脚本:编写一个 Kamailio C 模块或使用lua模块与签名服务进行更复杂的交互。
    • 发送的内容:主要包括主叫号码 (From Header)、被叫号码 (To Header) 和其他必要的 SIP 头信息。
  4. 外部 STIR/SHAKEN 签名服务的工作流程:
    • 接收到 Kamailio 发送的呼叫信息。
    • 向 STI-CA 请求证书(如果尚未缓存)。
    • 使用私钥和从 STI-CA 获取的证书对呼叫信息进行数字签名。
    • 将生成的 SHAKEN 身份声明(通常是一个 JSON Web Token (JWT))封装在 SIP P-Asserted-Identity (PAI) 头中,或者作为新的 SIP 头(例如Identity头)返回给 Kamailio。
  5. Kamailio 接收签名结果:
    • Kamailio 接收来自签名服务的响应(例如,新的 SIP INVITE 消息或包含 SHAKEN 声明的 HTTP 响应)。
  6. Kamailio 将 SHAKEN 身份声明插入 SIP 消息:
    • Kamailio 解析接收到的 SHAKEN 身份声明。
    • Kamailio 将其作为Identity头字段(通常在 SIP INVITE 消息中)添加到原始的 SIP INVITE 消息中。
      Identity: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdHRlc3QiOiJBIiwib3JpZyI6eyJ0ZWwiOiIrMSAxMTExNTU1MTIxMiJ9LCJkZXN0Ijp7InRlbCI6WyIrMSAxMTExNTU1MTIyMiJdfSwiaW ...
    • Kamailio 函数:可以使用insert_hf()append_hf()函数来添加Identity头。
  7. Kamailio 将带有签名的 INVITE 消息转发到下一个跳。

二、 呼叫接收方 (Terminating Service Provider) 的 Kamailio 配置

在呼叫接收方,Kamailio 的主要任务是接收带有 SHAKEN 身份声明的 SIP 呼叫,将其路由到外部的 STIR/SHAKEN 验证服务,并根据验证结果决定如何处理呼叫。

  1. Kamailio 收到带有Identity头的 INVITE 消息。
  2. Kamailio 识别需要验证的呼叫:Kamailio 需要通过检查 SIP 消息中是否存在Identity头来判断该呼叫是否需要进行 STIR/SHAKEN 验证。
    • Kamailio 函数:is_present_hf("Identity")
  3. Kamailio 将呼叫信息发送到外部 STIR/SHAKEN 验证服务:
    • 如何发送:同样可以通过 REFER、HTTP 请求或专门的 Kamailio 模块与外部验证服务进行交互。
      • 使用 REFER:Kamailio 向验证服务发送 REFER 消息,包含 SIP INVITE 的相关信息(特别是Identity头)。验证服务进行验证,然后将验证结果(例如,验证通过/失败,Attestation Level 等)返回给 Kamailio。
      • 使用 HTTP 模块:Kamailio 构造 HTTP 请求,将Identity头的内容发送给验证服务。
    • 发送的内容:主要包括Identity头的内容、主叫号码、被叫号码等。
  4. 外部 STIR/SHAKEN 验证服务的工作流程:
    • 接收到 Kamailio 发送的呼叫信息和Identity头。
    • 解析Identity头中的 JWT。
    • 从 JWT 中提取证书信息。
    • 向 STI-CA 验证证书的有效性。
    • 验证签名是否正确,以及主叫号码是否与签名信息匹配。
    • 根据验证结果,生成一个验证报告(例如,Attestation Level A, B, C 或 FAILED)。
    • 将验证结果(例如,Attestation Level 和/或详细的错误信息)返回给 Kamailio。
  5. Kamailio 接收验证结果:
    • Kamailio 接收来自验证服务的响应。
  6. Kamailio 根据验证结果处理呼叫:
    • Kamailio 变量:将验证结果存储在 Kamailio 伪变量中,例如$var(stir_shaken_status)
    • 决策逻辑:Kamailio 根据$var(stir_shaken_status)的值来决定下一步操作:
      • 验证通过 (Attestation A/B/C):正常路由呼叫。可以在 SIP 消息中添加额外的头(例如X-Attestation-Level: A)以便下游系统识别。
      • 验证失败 (Attestation FAILED):
        • 拒绝呼叫 (e.g.,sl_send_reply("403", "Forbidden"))。
        • 将呼叫路由到语音邮件。
        • 将呼叫路由到欺诈检测系统。
        • 对呼叫进行降级处理(例如,播放警告音)。
        • 记录详细的日志。
      • 没有Identity头或无法联系验证服务:视为未验证,根据运营商策略进行处理(例如,路由,但标记为低信任度)。
    • Kamailio 函数:使用if()语句和route()函数进行条件路由。

Kamailio 配置示例(伪代码,仅供参考,实际配置会更复杂):

呼叫发起方 (OSP) Kamailio.cfg 片段:

# ... 其他 Kamailio 配置 ... loadmodule "xhttp.so" # 假设使用 HTTP 与签名服务交互 loadmodule "json.so" loadmodule "htable.so" route { # 假设你的签名服务是 http://stir_shaken_signer.example.com/sign if (is_from_local_domain() && $rU =~ "^\+1") { # 仅对本地域的E.164号码进行签名 # 构建发送给签名服务的 JSON 请求 # 注意:这里需要你根据签名服务的API来构建请求体 $var(request_body) = "{ \"from\": \"" + $ruri + "\", \"to\": \"" + $fU + "\" }"; # 发送 HTTP POST 请求到签名服务 if (xhttp_post("http://stir_shaken_signer.example.com/sign", "application/json", $var(request_body), "$var(response_code)", "$var(response_body)")) { if ($var(response_code) == "200") { # 解析签名服务返回的 JSON 响应,获取 Identity 头内容 if (json_get("$.identity_header", "$var(identity_value)", $var(response_body))) { # 将 Identity 头添加到 SIP INVITE 消息中 append_hf("Identity: " + $var(identity_value) + "\r\n"); } else { xlog("L_ERR", "STIR/SHAKEN signer: Failed to parse identity_header from response.\n"); } } else { xlog("L_WARN", "STIR/SHAKEN signer: HTTP POST failed with code $var(response_code).\n"); } } else { xlog("L_ERR", "STIR/SHAKEN signer: HTTP POST failed.\n"); } } # 继续路由呼叫 route(NATDETECT); route(RELAY); }

呼叫接收方 (TSP) Kamailio.cfg 片段:

# ... 其他 Kamailio 配置 ... loadmodule "xhttp.so" loadmodule "json.so" loadmodule "htable.so" route { # 假设你的验证服务是 http://stir_shaken_verifier.example.com/verify if (is_method("INVITE")) { if (is_present_hf("Identity")) { # 提取 Identity 头内容 $var(identity_header_value) = $hdr(Identity); # 构建发送给验证服务的 JSON 请求 $var(request_body) = "{ \"identity_header\": \"" + $var(identity_header_value) + "\", \"from\": \"" + $fU + "\", \"to\": \"" + $rU + "\" }"; # 发送 HTTP POST 请求到验证服务 if (xhttp_post("http://stir_shaken_verifier.example.com/verify", "application/json", $var(request_body), "$var(response_code)", "$var(response_body)")) { if ($var(response_code) == "200") { # 解析验证服务返回的 JSON 响应,获取验证结果 if (json_get("$.attestation_level", "$var(attestation_level)", $var(response_body))) { xlog("L_INFO", "STIR/SHAKEN verification result: $var(attestation_level)\n"); if ($var(attestation_level) == "A" || $var(attestation_level) == "B" || $var(attestation_level) == "C") { # 验证通过,正常路由 append_hf("X-Attestation-Level: " + $var(attestation_level) + "\r\n"); # 可选:添加自定义头 route(RELAY); } else if ($var(attestation_level) == "FAILED") { xlog("L_WARN", "STIR/SHAKEN verification failed for call from $fU to $rU.\n"); sl_send_reply("403", "Forbidden - STIR/SHAKEN Failed"); exit; } else { xlog("L_WARN", "STIR/SHAKEN unknown attestation level: $var(attestation_level).\n"); # 默认处理,例如继续路由或拒绝 route(RELAY); } } else { xlog("L_ERR", "STIR/SHAKEN verifier: Failed to parse attestation_level from response.\n"); route(RELAY); # 继续路由,但标记为未验证 } } else { xlog("L_WARN", "STIR/SHAKEN verifier: HTTP POST failed with code $var(response_code).\n"); route(RELAY); # 继续路由,但标记为未验证 } } else { xlog("L_ERR", "STIR/SHAKEN verifier: HTTP POST failed.\n"); route(RELAY); # 继续路由,但标记为未验证 } } else { xlog("L_INFO", "No Identity header found for call from $fU to $rU. Routing as unverified.\n"); route(RELAY); # 没有 Identity 头,直接路由 } } # ... 其他路由逻辑 ... }

关键考虑事项和注意事项:

  • 外部 STIR/SHAKEN 服务的选择:Kamailio 本身不提供 STIR/SHAKEN 签名或验证功能,你需要选择一个或多个符合标准的外部服务提供商或部署自己的 STIR/SHAKEN 签名/验证服务器。
  • API 接口:确保 Kamailio 能够与外部 STIR/SHAKEN 服务的 API 进行通信。HTTP/REST API 是最常见的选择,Kamailio 的xhttpjson模块可以很好地支持。
  • 性能:STIR/SHAKEN 签名和验证过程会增加呼叫设置的延迟。确保你的外部服务具有足够的处理能力,并且 Kamailio 与其通信是高效的。
  • 错误处理和降级:必须考虑当 STIR/SHAKEN 签名/验证服务不可用或返回错误时如何处理呼叫。通常会有一个降级机制,例如将呼叫标记为“未验证”并继续路由,或者在特定情况下直接拒绝。
  • 证书管理:无论是签名方还是验证方,都需要妥善管理 STI 证书。这通常由 STIR/SHAKEN 服务自动处理,但需要了解其工作原理。
  • Attestation Level (A/B/C):
    • A (Full Attestation):运营商可以验证主叫号码和发起呼叫的客户。最高信任度。
    • B (Partial Attestation):运营商可以验证客户,但无法完全验证主叫号码。
    • C (Gateway Attestation):运营商仅验证呼叫是否来自其网络。最低信任度。
    • Kamailio 在接收方应根据这些级别来制定不同的呼叫处理策略。
  • SIP 头修改:除了Identity头,有时还会涉及其他 SIP 头,例如P-Attestation-Info或自定义的X-头,用于传递额外的 STIR/SHAKEN 相关信息。
  • 日志和监控:详细记录 STIR/SHAKEN 签名和验证的成功与失败情况,以及 Attestation Level,对于故障排除和合规性审计至关重要。
  • 测试:在生产环境中部署之前,进行严格的测试,包括正常流程、错误情况和性能测试。

总而言之,Kamailio 在 STIR/SHAKEN 架构中扮演着重要的集成点角色。它负责将 SIP 信令流与外部的 STIR/SHAKEN 签名和验证服务连接起来,并根据这些服务的输出进行智能的呼叫路由和处理决策。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 4:42:40

基于matlab的凸轮轮廓的设计计算与绘图 计算此结构的最优化参数,根据其原理输出推程和回程的...

基于matlab的凸轮轮廓的设计计算与绘图 计算此结构的最优化参数,根据其原理输出推程和回程的最大压力角、最小曲率半径等相关结果。 程序已调通,可直接运行。打开MATLAB的脚本编辑器,迎面扑来的是熟悉的蓝色界面。咱们今天要折腾的这个凸轮设…

作者头像 李华
网站建设 2026/4/27 17:54:51

经验失灵:当IT老手在AI时代求职遇冷

在科技行业,经验曾是求职时最坚实的后盾。然而,不少拥有多年工作经历的IT人,却在最近的求职季中遭遇了意想不到的挑战:他们引以为傲的经验,在面对“是否熟悉AIGC工具”、“能否用AI重构工作流”等问题时,显…

作者头像 李华
网站建设 2026/5/1 3:58:11

单元测试的10个最佳实践

在软件开发的生命周期中,单元测试是确保代码健壮性和可维护性的基石。随着敏捷开发和持续集成的普及,高效的单元测试已成为测试从业者的必备技能。本文针对软件测试从业者,总结了10个经过验证的最佳实践,涵盖测试设计、执行到维护…

作者头像 李华
网站建设 2026/4/30 13:32:31

虫害预警怎样更及时?虫情测报仪夜间自动诱捕拍照,助力植保提前规划

虫害的发生往往具有隐蔽性和突发性,等到田间出现明显为害症状时再防治,有时可能已造成一定影响。如何更早地发现害虫出现迹象,实现植保工作的提前部署,是种植管理中希望改善的环节。虫情测报仪在害虫监测预警方面提供了一种技术手…

作者头像 李华