
说明,因为本文重点是介绍opensips中ACL配置,所以忽略了Asterisk和网关配置的流程。在本文章中,笔者已经假设用户安装好了opensips,其控制界面,asterisk和网关设备。如果读者没有安装此环境,请按照历史文档中的介绍安装OpenSIPS,控制界面和asterisk以及网关配置。
1opensips cfg文件配置
如果用户要实现opensips呼叫媒体服务器进行落地处理的话,需要添加配置文件,修改必要的设置。首先,添加权限模块:
loadmodule "permissions.so"
modparam("permissions", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips")
loadmodule "group.so"
modparam("group", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips")
添加了权限模块和组模块的处理以后,用户需要在拨号规则中对呼出号码进行判断来决定媒体服务器的动作或者是否有权限呼出的规则设置。注意,这里的通配符是一个示例的通配符,用户需要根据自己本地号码和国际长途的设置来进行处理,包括前缀号码设置等。在这里处理了这些流程以后,此呼叫抵达媒体服务器以后就无需再进行判断验证。当然,如果用户仍然想在媒体服务器做号码处理,也可以根据自己的业务逻辑在媒体服务器进行处理。这里,在主路由逻辑中添加一个签权认证的流程:
## authenticate and authorize
if (check_source_address(0)) {
# caller is a gateway
} else
if (is_from_local()) {
# caller is local
# authenticate if from local subscriber
# authenticate all initial non-REGISTER request that pretend to be
# generated by local subscriber (domain from FROM URI is local)
if (!proxy_authorize("", "subscriber")) {
proxy_challenge("", "auth");
exit;
}
if (!$au==$fU) {
send_reply(403,"Forbidden auth ID");
exit;
}
consume_credentials();
# caller authenticated
} else {
# if caller is not local, then called number must be local
if (!is_uri_host_local()) {
send_reply(403,"Rely forbidden");
exit;
}
}
然后分别添加local 呼叫,国际长途呼叫和号码格式的判断:
if ($rU=~"^[5-9][0-9]{6}$") { // 是否是本地号码,用户根据本地号码位数做调整。
if (db_is_user_in("credentials","local")) {
prefix("0075"); // 前缀是0755 或者其他的号码前缀
route(to_pstn);
} else {
send_reply(403, "No permissions for local calls");
exit;
}
}
国内长途的判断,通过区号加号码位数判断:
# 长途电话区号+号码位数,具体位数修改通配符设置
if ($rU=~"^[0-9][0-9][0-9][2-9][0-9]{6}$") {
if (db_is_user_in("credentials","ld")) {
prefix("1");
route(to_pstn);
} else {
send_reply(403, "No permissions for long distance");
exit;
}
国际长途呼叫是否符合E164的号码格式的判断,例如呼叫日本长途电话,或者其他的国家号码,具体号码位数需要自己修改。
if ($rU=~"^081[0-9]*$") {
if (db_is_user_in("credentials","int")) {
strip(3);
route(to_pstn);
} else {
send_reply(403, "No permissions for international calls");
exit;
}
}
在路由到PSTN的模块中添加一个呼叫媒体服务器的路由规则。保存配置文件以后,然后重新启动OpenSIPS服务器。
route[to_pstn] {
# routing to the pstn (Use the IP address of the gateway)
# Please use as the IP address one of the gateways provided
sethostport("sip.freesbc.cn:5600"); // 这里也可以是媒体服务器的IP地址。
t_relay();
exit;
}
2通过opensips 操作界面添加媒体服务器
完成了cfg文件的配置以后,在opensips的控制界面添加一个路由规则。

3修改opensips 操作界面的配置
因为OpenSIPS作为一个运营级的软交换,它要实时处理几千或者上万次的呼叫,每一个呼叫都要经过呼叫签权认证。为了控制呼叫的认证流程,OpenSIPS使用ACL来对呼叫认证进行管理。ACL本身可以支持非常快速的实时处理流程。在ACL管理的模块中修改配置文件,支持grp表的配置设置。用户然后修改control panel的PHP代码,增加本地呼叫,长途呼叫和国际长途的规则设置。
读者使用ACL时要注意,前面笔者已经说明。OpenSIPS作为一个运营级的平台,它可以支持上千或者上万的呼叫并发。而且一个SIP用户如果需要执行ACL的话,账号本身可能涉及多个SQL 查询流程。因此,ACL可能会引起数据库查询带来的效率问题,ACL频繁访问会使得数据库负载增加,从而会一致影响OpenSIPS的性能。为了提高ACL的执行性能,ACL模块引入了group的概念,通过ACL grp来提高查询用户的速度和优化ACL的查询性能。具体语法如下:

4添加ACL 控制组
通过控制界面,修改ACL的呼叫权限控制。针对不同的SIP 账号做不同的处理设置。ld表示仅支持长途呼叫,local表示仅支持本地呼叫,int表示仅支持国际长途呼叫。

这里,1000 用户可以呼叫本地用户,呼叫长途;1001用户可以呼叫本地和国际长途电话。对用户ACL设置中,ACL支持了多种用户验证的查询方式,cfg脚本可以通过这几种方式实现快速查询,无需通过数据库访问来实现查询,所以,这些查询方式可能更加高效。它们都可以通过avpops,aaa_radius, 和ldap模块实现支持。首先,ACL支持了binary code方式,使用一个bit就可以表示用户的认证权限,通过bitmask支持多种呼叫权限的设置。第一个bit表示账号停用,第二个bit表示允许voip呼叫,第三个bit表示允许PSTN国内呼叫,第四个bit表示允许国际呼叫。在cfg中对avp操作实现ACL流程的处理:

相当于binary code来说,使用access level coding方式,用户可能更加容易明白。ACL支持了Level encoding(0,1,2,3),这里0表示账号停用,1表示使用VOIP呼叫,2表示允许国内PSTN呼叫,3表示允许国际呼叫等。

但是,如果使用binary code或者access level设置呼叫权限的话,它仍然对用户来说不是非常友好,毕竟,binary code 相对比较难以理解。具有一定含义的字符串对于大部分用户来说是非常易懂的,而且也可以支持脚本执行检测。使用字符串的ACL 方式中,d表示SIP用户停用,v表示允许voip呼叫,n表示允许国内PSTN呼叫,i表示允许用户执行国际呼叫。

5媒体服务器设置以及呼叫测试
这里的媒体服务器是一个Asterisk服务器,通过IP呼叫到Asterisk以后,Asterisk做路由处理,然后呼叫鼎信的FXO语音网关,最后语音网关呼叫落地运营商的PSTN线路,直到最终用户终端。如果用户安装FreePBX作为一个IPPBX的话,用户可以通过界面直接配置一个pjsip的IP呼叫 trunk,直接对接到鼎信网关地址。然后再通过呼出路由规则做一个呼出路由就可以实现完整的通过OpenSIPS网关媒体服务器落地的流程。注意,Asterisk服务器也可以不经过PSTN落地,呼叫真实运营商的线路,也可以播放一个语音提示来做不同呼叫路由的测试。
OpenSIPS的SIP账号可以首先注册(使用1000用户/1001用户分别测试不同号码)到OpenSIPS服务器,然后通过呼叫本地号码,长途号码和国际长途来实现测试流程。如果asterisk媒体服务器设置为一个伪落地环境,对SIP 账号播放语音的话,成功的呼叫就会听到不同的语音提示音。如果媒体服务器对接了语音网关的话,根据号码位数和格式,运营商会呼叫到本地,国内或者国际用户终端。
6总结
OpenSIPS作为一个运营级的软交换,它本身需要一个ACL模块对用户呼叫进行认证设置。根据不同的用户路由到不同的媒体服务器和落地网关。本文章通过OpenSIPS对接Asterisk和网关的方式说明如何在OpenSIPS平台通过ACL来对用户进行认证流程。其中,ACL通过界面,组设置和ACL设置实现SIP账号呼叫的验证。在本文章中,笔者介绍了如何修改cfg文件对呼叫做不同的判断,同时介绍了通过OpenSIPS界面做路由和ACL设置。另外,针对ACL策略的设置方式,笔者做了一些深入的分析,包括各种设置方式的优缺点。
OpenSIPS用户通过物理终端可以对ACL设置进行呼叫测试。通过拨打不同的号码来检测ACL的正确性。
参考资料:
www.opensips.org
www.freesbc.cn
www.freepbx.org.cn
- 融合通信/IPPBX/FreePBX商业解决方案:www.hiastar.com
- 最新Asterisk完整中文用户手册详解:www.asterisk.org.cn
- Freepbx/FreeSBC技术文档: www.freepbx.org.cn
- 如何使用免费会话边界控制器-FreeSBC,qq技术分享群:334023047
- 关注微信公众号:asterisk-cn,获得有价值的通信行业技术分享