13611180126
基于OpenSIPS实现电话录音解决方案探讨
发表时间:2017-11-07 05:30

电话录音是很多商业环境中必不可少的功能,政府机构,热线服务,银行,安全监管机构,呼叫中心等行业必须支持的通信功能。基于硬件的或者软件的电话录音解决方案也都有各自的局限性,同时部署成本也非常高。

  很多厂家对电话录音解决方案的问题也非常头疼,因为录音不单单是一个电话录音本身,还要涉及管理,安全,备份,存储问题,媒体服务器负载等等相关的技术解决方案。
  开源软交换平台OpenSIPS及时感觉到了用户的痛点,在本身交换的能力上,对电话录音和媒体处理做了处理调度,通过OpenSIPS加一个第三方开源录音服务器实现对电话的录音。现在,我们通过官方文档的安装指导,首先解读一下安装配置的设置,然后分析一下关于此录音解决方案和其他第三方解决方案,最后,我们介绍了关于SIPREC标准之间的冲突或容易引起歧义的地方。
  关于SIPREC标准介绍
  SIPREC是一个对SIP录音标准的协议规范。它使用非干预的外部录音服务器对媒体进行实时录音,不影响真正的RTP语音流。根据RFC3245的定义,它主要的两个核心模块是:
  Session Recording Server (SRS),它是一个SIP 录音服务器,接收forked 过来SRC,存储在SRS服务器。这里的SRS是OrecX-开源的录音服务器。
  Session Recording Client (SRC),它负责在SIP session 路径上触发录音服务。这里的SRC就是OpenSIPS。
  录音实现架构
  现在,让我们看看如何通过OpenSIPS结合第三方开源录音服务器实现录音的实现原理。
  在这个SIP开源录音服务器的实现架构中:
  1. OpenSIPS工作方式是SRC,提供SIP呼叫的所需metadata,这些metadata 会保存到录音服务器,以方便将来对录音的文件的匹配和管理。

  2. Oreka对forked的呼叫进行录音,执行录音服务。

  3. RTPProxy将会分拆RTP语音流量到录音服务器。

  根据以上的架构图,我们可以看出,两个SIP分机直接可以互相呼叫,现在本身终端没有任何录音功能支持。正常情况下,终端会发生SIP信令到OpenSIPS,然后RTPProxy负责创建一个媒体流。
  在我们的案例中:
  • 当发起一个呼叫以后,OpenSIPS需要通知SRS,并且对SRS启动一个SIPREC会话,在SDP中提供双方的metadata 描述,媒体消息描述。通过SDP描述,SRS决定是否对此呼叫启动录音。

  • 如果需要录音,则发送200 OK消息,消息中包含一个fork的消息,通知在什么地方分拆媒体流

  • 当OpenSIPS收到消息以后,它通知RTPProxy把客户端的RTP语音流分拆给SRS服务器,对分拆出来的语音进行录音。

  • 当通话结束后,OpenSIPS SIPREC结束会话,然后结束录音。

  配置方法
  此案例不会列出如何安装OpenSIPS,如何安装RTPProxy和Oreka,请用户按照文档的提示什么自行安装。
  这里需要说明的是,根据RFC7245的规定,B2BUA可以支持SRC,终端也可以实现SRC,但是SIP Proxy不能实现SRC,因为它不能访问媒体流。因此,这里的OpenSIPs需要加载b2b模块。
  以下流程图解释了B2BUA如何配合SRS实现录音的过程。终端录音的实现方式有所不同,我们这里不做讨论。
  为了实现OpenSIPS对呼叫进行录音的调度,用户必须首先加载所需的模块,这些模块包括:
  loadmodule "dialog.so"  // 对会话确认
  loadmodule "b2b_entities.so" // 设置为B2B模式支持,管理SIPREC Session。
  loadmodule "siprec.so" // 设置SIPREC模块
  loadmodule "rtpproxy.so"// 设置RTP引擎模块
  其次,确认对接RTP 引擎的接口:
  modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7899")
  最后修改INVITE消息检测,执行INVITE的以后的流程处理。这里,假设所有用户录音。
  # account only INVITEs
  if (is_method("INVITE")) { // 如果是INVITE
  create_dialog(); // 创建dialog来管理呼叫。
  rtpproxy_engage();// 启动RTP引擎,创建语音流
  siprec_start_recording("sip:127.0.0.1:5090"); // 启动SIPREC 录音
  do_accounting("log");// 记录log日志。
  }
  这里我们仅列出需要关注的配置选项部分,因为OpenSIPS的配置文件比较长,不宜与在这里全部展现,请读者访问参考资料的链接获取。
  高级配置
  高级配置选项里面可以支持几个选项的配置:
  修改UDP传输支持TCP传输。一般情况下,如果使用RTP传输还能承受数据的负载,实现轻量级的传输。如果通过SIPREC添加比较大的数据 payload,或者metadata XML数据,则可能超过最大传输单元MTU的限制(不能大于1500字节),这样可能导致数据丢失或者数据受损。关于使用UCP还是TCP的传输方式,我们在以前的讨论中也做过介绍。以下图例是SIP消息中的xml数据。
  以上这些数据都会加大数据流量。对于UDP传输则可能出现很多问题,TCP传输则避免了类似的问题。为了解决这个问题,用户可以通过修改传输方式来支持TCP传输而不使用UDP传输。
  当然,用户首先需要加载TCP模块:
  loadmodule "proto_tcp.so"
  然后监听TCP端口,最后配置模块参数。
  listen = tcp:127.0.0.1:5060
  最后,修改SRC URL:
  siprec_start_recording("sip:127.0.0.1:5090;transport=tcp");
  第二种配置选项就是修改特别指定接口和SRS进行通信,强制使用此接口。
  force_send_socket(tcp:127.0.0.1:5060);
  siprec_start_recording("sip:127.0.0.1:5060;transport=tcp");
  force_send_socket(udp:127.0.0.1:5060); #这里必须强制发送 restore the initial interface
  第三种高级设置是支持对指定用户组进行录音。通常来说,RTP引擎一般对所有用户进行录音,如果用户需要对某些特定组进行录音时,可以使用以下设置方式,通过可信任的SDP中的IP地址进行分组管理:
  rtpproxy_offer(,,"5");
  siprec_start_recording("sip:127.0.0.1:5060;transport=tcp",,,,"5");
  注意,这里的组都是5。
  第四种高级设置,修改呼叫参与方的metadata支持更多业务需求。在默认配置中,OpenSIPS仅支持from头和to头。在实际应用环境中,用户可能还需要收到的DID号码,用户别名等消息。用户可以开启另外两个传输支持传输其他的metadata内容:
  $var(caller) = "\"John Doe\" <sip:john@opensips.org>\r\n";
  $var(callee) = "\"Jane Doe\" <sip:jane@opensips.org>\r\n";
  siprec_start_recording("sip:127.0.0.1:5060;transport=tcp",, "$var(caller)", "$var(callee)");
  通过参数3和参数4支持了呼叫方和被呼叫方的号码信息。此功能也支持呼叫分组的功能,根据rfc7865的定义添加一个标签(第二个参数):
  siprec_start_recording("sip:127.0.0.1:5060;transport=tcp", "regular", "$var(caller)", "$var(callee)");
  语法规则:
  • srs - a comma-separated list of SRS URIs. These URIs are used in the order specified. See siprec_srs_failover for more information.

  • group (optional) - an opaque values used by the SIPREC protocol to group calls in certain profiles.

  • caller (optional) - a nameaddr header containing information about the caller. If absent, the From header is used.

  • callee (optional) - a nameaddr header containing information about the callee. If absent, the To header is used.

  • rtpproxy_set (optional) - the RTPProxy set used for this call. If absent, the default set provisioned in the rtpproxy module is used.

  SRS 录音服务器逃生设置
  通信系统一般都是全天候工作,如果出现任何的故障都会导致整个通信系统或者公司日常业务不能正常工作。所以,部署一套可靠的系统支持逃生处理是非常重要的任务。SRC录音可以支持多台录音服务器进行调度。使用方式如下:
  siprec_start_recording("sip:127.0.0.1:5060;transport=tcp, sip:127.0.0.1:5060");
  这里假设第一台录音服务器使用的是TCP的传输方式,如果第一台服务器不能正常工作,则自动启动第二台服务器,第二台录音服务器默认使用的是UDP传输方式。
  这里需要大家注意,默认的录音服务器之间的切换是通过SRS的协商响应来实现的。在实际生产环境中,用户可以自定义其他的响应消息来实现响应的逃生处理。
  在以上标注的红色的逃生处理中,只有收到5xx或者6xx才执行逃生。
  SIPREC模块更多讨论
  SIPERC是一个比较大的技术范畴,不仅仅局限于SRC或SRS,这里还要涉及安全问题,转码问题,和录音控制等问题。
  SIPREC模块局限性的问题,根据OpenSIPS官方的解释,目前SIPREC模块仍然存在两个方面的局限性:
  1. 不支持对被呼叫方播放语音提示音。根据很多国家的相关法律规定,如果电话系统需要对用户录音时,必须首先对用户播放录音提示,否则,视为违法。所以在一般的商业环境中,如果需要对通话进行录音时,系统必须提前对被呼叫方提示,例如,你的通话将被录音等类似的提示。

  2. 不能支持由SRS 录音服务器发起的录音会话。如果录音服务器突然在会话中途开启录音的话,这是不能支持的。此局限性和RFC 7245中的规定有差距。

  根据RFC 7245的规定,SRC或SRS(May)可能可以支持录音暂停或重启。笔者在官方的模块文档和SRS Oreka录音服务器中还没有发现如何设置此功能。
  根据RFC标准的规定,可以通过SRS录音转码,Oreka满足了这一要求。
  SIPREC模块的局限性中提到,它本身不能支持有SRS发起的录音,但是在RFC 7245中规定了由SRS发起录音的相关流程规定,所以这个功能有待于进一步提高。
  SIPREC的模块中,没有提到关于关于安全方面的设置。根据RFC 7866的规定,应该支持TLS。同时,RFC7866规定,SRC和SRS应该同时支持同样的安全策略。
  关于认证和签权的设置,在RFC7866中规定,SRC和SRS必须使用TLS,但是在内网环境中,RFC7866则允许使用其他的认证策略。在这一点上,SIPREC模块似乎可以满足用户的需求。
  通过对OpenSIPS结合第三方开源录音服务器Oreka的介绍,读者可以了解了如何通过OpenSIPS,TTPProxy和Oreka的录音功能,笔者在本讨论中也探讨了录音环境下的一些参数优化,最后讨论了一些和RFC规定相关的技术要求。总体来说,这个方案可以基本满足通过OpenSIPS对接第三方的录音服务器的要求,但是更多对支持RFC的功能还要有待进一步的完善。
  另外,除了我们正在讨论的使用OpenSIPS加第三方录音以外,基于其他开源的媒体服务器或者结合录音服务器也可以实现电话录音功能,但是不一定满足SIPREC 标准,例如:
  1. Asterisk+Oreka方式,使用Asterisk作为媒体服务器,通过Oreka实现录音服务器功能。

  2. FreeSWITCH+Oreka方式,使用FreeSWITCH作为媒体服务器,通过Oreka实现电话录音功能。

  3. 直接通过抓包的方式来实现电话录音的获取,这样的优势在于不涉及媒体服务器,部署简单。笔者朋友也提供了类似的解决方案,用户可以下载测试。

  以上前两种方式,都是通过一个Oreka模块,通过IP地址和端口来监听语音流,然后添加需要的自定义的metadata实现对每个呼叫的号码对应,通过是否混音来通知服务器混音处理。
  关于SIPREC模块的配置,OpenSIPS官方有非常详细地的说明,笔者引用了部分的文档内容,结合RFC标准对此解决方案进行的探讨。


地址:北京市海淀区中关村大街18号    电话:13611180126    QQ:927571438  优化支持:云客网