背景
公司打算把freeswitch部署在本地局域网中,让后希望内网的话机以及外网的话机可以注册到该freeswitch上。(目前SBC的概念已经被好多人给乱用了,原本SBC强调的session的边界控制,但现在这些人又分了个i-SBC、a-SBC,后者完全跟SBC不沾边)
方案
经过调研,计划在公网上部署一台proxy服务器,负责sip信令以及媒体流的代理。其中SIP代理选择的是opensips,媒体代理选择的是rtpproxy。本文只展示opensips的配置脚本
网上的方案,基本都是将opensips作为注册服务器,而我的方案中opensips只负责信令消息的代理。
依赖的模块
- path:用来支持Path扩展,在呼叫经过该代理注册到freeswitch的话机时INVITE会经过该代理
- nat_traversal:我原本以为这个模块实施了nat table,但并没有。使用这个模块主要有以下两个作用
- 使用client_nat_test检测请求是否来自NATed主机
- 使用nat_keepalive来保持请求经过的节点的NAT记录
- cachedb_local:用来实施自己的nat table,可以替换成其他的cachedb
- dispatcher:负责out-dialog的非INVITE请求的代理
- ld_balancer:负责out-dialog的INVITE请求的代理
主要思想
- INVITE、REGISTER、SUBSCRIBE请求经过代理是,使用client_nat_test检测NAT,将来源是NATed主机登记到nat table中(目前的nat table很简单,就是NATed地址作为key,外部地址作为value,同时还增加了600秒的生命期)
- 当话机通过该代理进行注册时,通过add_path_received在Path中记录当前代理的地址以及请求的外部地址。(freeswitch-1.10.6存在bug,不能正确的让Path中的received参数生效,master中已经修正了该问题)
- 通过freeswitch呼叫外网的话机时,会将之前的Path作为Route,这样就保证了INVITE请求一定会经过该代理
- 通过loose_route获取转发的目的地
- 若$du非空,则使用$du从nat table中获取记录的外部地址,否则使用$ru进行查找
- 将$du更新成查找到的地址记录
- 转发请求
配置脚本
#
# OpenSIPS loadbalancer script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This script was generated via "make menuconfig", from
# the "Load Balancer" scenario.
# You can enable / disable more features / functionalities by
# re-generating the scenario with different options.
#
# Please refer to the Core CookBook at:
# https://opensips.org/Resources/DocsCookbooks
# for a explanation of possible statements, functions and parameters.
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
log_stderror=yes
log_facility=LOG_LOCAL0
udp_workers=1
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled)