kamailio TOPOH 模块
Kamailio topoh 模块分析
概述
topoh 模块是Kamailio中的一个拓扑隐藏(Topology Hiding)模块,其主要功能是隐藏SIP消息中暴露服务器拓扑结构的路由头信息,从而保护SIP代理服务器的内部网络架构不被外部知晓。
核心功能
- 拓扑信息隐藏:对SIP消息中的路由头信息(如Record-Route, Route)进行编码和解码,隐藏真实的服务器地址和路径。
- 无状态兼容:模块设计不受服务器是无状态(stateless)还是有状态(stateful)的影响。
- 脚本透明性:对SIP消息的编码/解码对Kamailio脚本解释器是透明的,脚本中接收到的SIP消息始终是解码后的完整内容,所有功能正常可用。
- 无缝重启:SIP服务器重启不会影响正在进行的通话。重启后,服务器能继续编码/解码拓扑信息,确保通话不中断。
- 集群支持:通过使用相同的
mask_key,多个SIP服务器(如负载均衡后的服务器群)可以共享解码能力。
依赖要求
必需模块
- rr 模块:必须在
topoh模块之前加载。服务器必须执行record_routing操作,以确保对话内请求(in-dialog requests)能够被正确编码和解码。
外部依赖
- 无外部库或应用程序依赖。
核心参数详解
1. 安全与编码参数
mask_key(str): 用于编码/解码头部信息的密钥(关键词)。- 默认值:
_static_value_ - 重要性: 这是拓扑隐藏的核心。所有需要相互解码的服务器必须使用相同的
mask_key。 - 示例:
modparam("topoh", "mask_key", "some secret here")
- 默认值:
mask_ip(str): 用于构建编码后SIP URI的IP地址。- 默认值:
127.0.0.8 - 说明: 可以是任何IP(包括私有IP、非真实IP),但不应是客户端可能使用的地址。该IP不用于实际SIP路由。
- 示例:
modparam("topoh", "mask_ip", "192.168.0.1")
- 默认值:
mask_callid(integer): 是否对Call-ID:头部进行编码。- 默认值:
0(不编码) - 注意: 如果启用且使用
dialog模块终止通话,必须设置dialog模块的lreq_callee_headers参数包含TH: dlh\r\n。
- 默认值:
2. 编码格式参数
uparam_name(str): 存储编码值的URI参数名称。- 默认值:
line
- 默认值:
uparam_prefix(str): 编码URI参数前添加的前缀。- 默认值:
sr-
- 默认值:
vparam_name(str): 存储编码值的Via头参数名称。- 默认值:
branch
- 默认值:
vparam_prefix(str): 编码Via头参数前添加的前缀。- 默认值:
z9hG4bKsr-
- 默认值:
callid_prefix(str): 编码Call-ID头部前添加的前缀。- 默认值:
!!:
- 默认值:
3. 安全与验证参数
sanity_checks(integer):- 默认值:
0(不绑定) - 功能: 如果设置为1,模块将绑定
sanity模块,对接收到的SIP请求执行格式检查,确保请求格式正确后再进行编码/解码。
- 默认值:
uri_prefix_checks(integer):- 默认值:
0(不检查) - 功能: 如果设置为1,模块在解码前会检查URI是否匹配预期的前缀(由
mask_ip和uparam_prefix组成),避免尝试解码非本模块编码的URI。 - 警告: 如果SIP设备会修改Contact或Record-Route头中的URI(如添加端口5060或插入新参数),则不应启用此选项。
- 默认值:
4. 事件回调参数
event_callback(str):- 默认值: 空(不执行函数)
- 功能: 指定KEMI配置文件(如Lua, Python脚本)中要执行的函数名,代替
event_route[...]块。 - 参数: 该函数接收一个字符串参数,表示触发的事件名称。
- 示例:
modparam("topoh", "event_callback", "ksr_topoh_event")
event_mode(int):- 默认值:
3(执行两个事件路由) - 功能: 位掩码控制执行哪些
event_route块:1: 执行event_route[topoh:msg-outgoing]2: 执行event_route[topoh:msg-sending]3: 执行两者(默认)
- 默认值:
事件路由 (Event Routes)
1. event_route[topoh:msg-outgoing]
- 触发时机: 在对出站SIP消息进行拓扑隐藏处理之前。
- 目的: 允许在早期决定是否跳过拓扑隐藏。
- 关键变量:
$sndto(ip),$sndto(port),$sndto(proto)指向目标地址。 - 消息状态: 不是最终要发送的消息,而是一个内部生成的简化消息。这样设计是为了避免对不需要处理的消息进行完整解析,提高性能。
- 控制: 如果在此路由中执行
drop,则模块将跳过拓扑隐藏处理。 - 示例:
1
2
3
4
5event_route[topoh:msg-outgoing] {
if($sndto(ip)=="10.1.1.10") {
drop; // 对此目标不进行拓扑隐藏
}
}
2. event_route[topoh:msg-sending]
- 触发时机: 在
event_route[topoh:msg-outgoing]之后,对即将发送的SIP消息进行拓扑隐藏处理之前。 - 目的: 允许在发送前对消息进行最终检查或决策。
- 关键变量:
$sndto(ip),$sndto(port),$sndto(proto)指向目标地址。 - 消息状态: 这是最终要发送的完整SIP消息。
- 控制: 如果在此路由中执行
drop,则模块将跳过拓扑隐藏处理。 - 示例:
1
2
3
4
5event_route[topoh:msg-sending] {
if(is_request() && $fU=="alice") {
drop; // 对用户alice的请求不进行拓扑隐藏
}
}
topoh 与 topos 模块对比
| 特性 | topoh 模块 |
topos 模块 |
|---|---|---|
| 存储机制 | 无状态,不依赖数据库或外部存储。通过密钥和算法直接编码/解码。 | 有状态,依赖数据库或Redis存储对话和分支信息。 |
| 重启影响 | 无缝,重启后仍能解码旧消息,通话不中断。 | 可能中断,如果存储数据丢失或未共享,可能无法正确还原拓扑。 |
| 复杂性 | 简单,配置少,易于部署。 | 复杂,需要配置存储后端和过期时间等。 |
| 适用场景 | 适合简单的拓扑隐藏需求,对性能要求高,希望避免外部依赖的场景。 | 适合需要更复杂拓扑管理、需要持久化状态的场景。 |
| 主要参数 | mask_key, mask_ip |
storage, db_url, branch_expire, dialog_expire |
总结
topoh 模块是一个轻量级、无状态、高性能的拓扑隐藏解决方案。它通过密码学方法直接在消息中编码拓扑信息,无需外部存储,非常适合需要简单、可靠且对重启不敏感的拓扑隐藏场景。其核心优势在于简单性和鲁棒性,配置只需关注 mask_key 和 mask_ip 等少数几个关键参数即可。








