
說(shuō)明,因為本文重點(diǎn)是介紹opensips中ACL配置,所以忽略了Asterisk和網(wǎng)關(guān)配置的流程。在本文章中,筆者已經(jīng)假設用戶(hù)安裝好了opensips,其控制界面,asterisk和網(wǎng)關(guān)設備。如果讀者沒(méi)有安裝此環(huán)境,請按照歷史文檔中的介紹安裝OpenSIPS,控制界面和asterisk以及網(wǎng)關(guān)配置。
1opensips cfg文件配置
如果用戶(hù)要實(shí)現opensips呼叫媒體服務(wù)器進(jìn)行落地處理的話(huà),需要添加配置文件,修改必要的設置。首先,添加權限模塊:
loadmodule "permissions.so"
modparam("permissions", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips")
loadmodule "group.so"
modparam("group", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips")
添加了權限模塊和組模塊的處理以后,用戶(hù)需要在撥號規則中對呼出號碼進(jìn)行判斷來(lái)決定媒體服務(wù)器的動(dòng)作或者是否有權限呼出的規則設置。注意,這里的通配符是一個(gè)示例的通配符,用戶(hù)需要根據自己本地號碼和國際長(cháng)途的設置來(lái)進(jìn)行處理,包括前綴號碼設置等。在這里處理了這些流程以后,此呼叫抵達媒體服務(wù)器以后就無(wú)需再進(jìn)行判斷驗證。當然,如果用戶(hù)仍然想在媒體服務(wù)器做號碼處理,也可以根據自己的業(yè)務(wù)邏輯在媒體服務(wù)器進(jìn)行處理。這里,在主路由邏輯中添加一個(gè)簽權認證的流程:
## 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 呼叫,國際長(cháng)途呼叫和號碼格式的判斷:
if ($rU=~"^[5-9][0-9]{6}$") { // 是否是本地號碼,用戶(hù)根據本地號碼位數做調整。
if (db_is_user_in("credentials","local")) {
prefix("0075"); // 前綴是0755 或者其他的號碼前綴
route(to_pstn);
} else {
send_reply(403, "No permissions for local calls");
exit;
}
}
國內長(cháng)途的判斷,通過(guò)區號加號碼位數判斷:
# 長(cháng)途電話(huà)區號+號碼位數,具體位數修改通配符設置
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;
}
國際長(cháng)途呼叫是否符合E164的號碼格式的判斷,例如呼叫日本長(cháng)途電話(huà),或者其他的國家號碼,具體號碼位數需要自己修改。
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的模塊中添加一個(gè)呼叫媒體服務(wù)器的路由規則。保存配置文件以后,然后重新啟動(dòng)OpenSIPS服務(wù)器。
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"); // 這里也可以是媒體服務(wù)器的IP地址。
t_relay();
exit;
}
2通過(guò)opensips 操作界面添加媒體服務(wù)器
完成了cfg文件的配置以后,在opensips的控制界面添加一個(gè)路由規則。

3修改opensips 操作界面的配置
因為OpenSIPS作為一個(gè)運營(yíng)級的軟交換,它要實(shí)時(shí)處理幾千或者上萬(wàn)次的呼叫,每一個(gè)呼叫都要經(jīng)過(guò)呼叫簽權認證。為了控制呼叫的認證流程,OpenSIPS使用ACL來(lái)對呼叫認證進(jìn)行管理。ACL本身可以支持非常快速的實(shí)時(shí)處理流程。在A(yíng)CL管理的模塊中修改配置文件,支持grp表的配置設置。用戶(hù)然后修改control panel的PHP代碼,增加本地呼叫,長(cháng)途呼叫和國際長(cháng)途的規則設置。
讀者使用ACL時(shí)要注意,前面筆者已經(jīng)說(shuō)明。OpenSIPS作為一個(gè)運營(yíng)級的平臺,它可以支持上千或者上萬(wàn)的呼叫并發(fā)。而且一個(gè)SIP用戶(hù)如果需要執行ACL的話(huà),賬號本身可能涉及多個(gè)SQL 查詢(xún)流程。因此,ACL可能會(huì )引起數據庫查詢(xún)帶來(lái)的效率問(wèn)題,ACL頻繁訪(fǎng)問(wèn)會(huì )使得數據庫負載增加,從而會(huì )一致影響OpenSIPS的性能。為了提高ACL的執行性能,ACL模塊引入了group的概念,通過(guò)ACL grp來(lái)提高查詢(xún)用戶(hù)的速度和優(yōu)化ACL的查詢(xún)性能。具體語(yǔ)法如下:

4添加ACL 控制組
通過(guò)控制界面,修改ACL的呼叫權限控制。針對不同的SIP 賬號做不同的處理設置。ld表示僅支持長(cháng)途呼叫,local表示僅支持本地呼叫,int表示僅支持國際長(cháng)途呼叫。

這里,1000 用戶(hù)可以呼叫本地用戶(hù),呼叫長(cháng)途;1001用戶(hù)可以呼叫本地和國際長(cháng)途電話(huà)。對用戶(hù)ACL設置中,ACL支持了多種用戶(hù)驗證的查詢(xún)方式,cfg腳本可以通過(guò)這幾種方式實(shí)現快速查詢(xún),無(wú)需通過(guò)數據庫訪(fǎng)問(wèn)來(lái)實(shí)現查詢(xún),所以,這些查詢(xún)方式可能更加高效。它們都可以通過(guò)avpops,aaa_radius, 和ldap模塊實(shí)現支持。首先,ACL支持了binary code方式,使用一個(gè)bit就可以表示用戶(hù)的認證權限,通過(guò)bitmask支持多種呼叫權限的設置。第一個(gè)bit表示賬號停用,第二個(gè)bit表示允許voip呼叫,第三個(gè)bit表示允許PSTN國內呼叫,第四個(gè)bit表示允許國際呼叫。在cfg中對avp操作實(shí)現ACL流程的處理:

相當于binary code來(lái)說(shuō),使用access level coding方式,用戶(hù)可能更加容易明白。ACL支持了Level encoding(0,1,2,3),這里0表示賬號停用,1表示使用VOIP呼叫,2表示允許國內PSTN呼叫,3表示允許國際呼叫等。

但是,如果使用binary code或者access level設置呼叫權限的話(huà),它仍然對用戶(hù)來(lái)說(shuō)不是非常友好,畢竟,binary code 相對比較難以理解。具有一定含義的字符串對于大部分用戶(hù)來(lái)說(shuō)是非常易懂的,而且也可以支持腳本執行檢測。使用字符串的ACL 方式中,d表示SIP用戶(hù)停用,v表示允許voip呼叫,n表示允許國內PSTN呼叫,i表示允許用戶(hù)執行國際呼叫。

5媒體服務(wù)器設置以及呼叫測試
這里的媒體服務(wù)器是一個(gè)Asterisk服務(wù)器,通過(guò)IP呼叫到Asterisk以后,Asterisk做路由處理,然后呼叫鼎信的FXO語(yǔ)音網(wǎng)關(guān),最后語(yǔ)音網(wǎng)關(guān)呼叫落地運營(yíng)商的PSTN線(xiàn)路,直到最終用戶(hù)終端。如果用戶(hù)安裝FreePBX作為一個(gè)IPPBX的話(huà),用戶(hù)可以通過(guò)界面直接配置一個(gè)pjsip的IP呼叫 trunk,直接對接到鼎信網(wǎng)關(guān)地址。然后再通過(guò)呼出路由規則做一個(gè)呼出路由就可以實(shí)現完整的通過(guò)OpenSIPS網(wǎng)關(guān)媒體服務(wù)器落地的流程。注意,Asterisk服務(wù)器也可以不經(jīng)過(guò)PSTN落地,呼叫真實(shí)運營(yíng)商的線(xiàn)路,也可以播放一個(gè)語(yǔ)音提示來(lái)做不同呼叫路由的測試。
OpenSIPS的SIP賬號可以首先注冊(使用1000用戶(hù)/1001用戶(hù)分別測試不同號碼)到OpenSIPS服務(wù)器,然后通過(guò)呼叫本地號碼,長(cháng)途號碼和國際長(cháng)途來(lái)實(shí)現測試流程。如果asterisk媒體服務(wù)器設置為一個(gè)偽落地環(huán)境,對SIP 賬號播放語(yǔ)音的話(huà),成功的呼叫就會(huì )聽(tīng)到不同的語(yǔ)音提示音。如果媒體服務(wù)器對接了語(yǔ)音網(wǎng)關(guān)的話(huà),根據號碼位數和格式,運營(yíng)商會(huì )呼叫到本地,國內或者國際用戶(hù)終端。
6總結
OpenSIPS作為一個(gè)運營(yíng)級的軟交換,它本身需要一個(gè)ACL模塊對用戶(hù)呼叫進(jìn)行認證設置。根據不同的用戶(hù)路由到不同的媒體服務(wù)器和落地網(wǎng)關(guān)。本文章通過(guò)OpenSIPS對接Asterisk和網(wǎng)關(guān)的方式說(shuō)明如何在OpenSIPS平臺通過(guò)ACL來(lái)對用戶(hù)進(jìn)行認證流程。其中,ACL通過(guò)界面,組設置和ACL設置實(shí)現SIP賬號呼叫的驗證。在本文章中,筆者介紹了如何修改cfg文件對呼叫做不同的判斷,同時(shí)介紹了通過(guò)OpenSIPS界面做路由和ACL設置。另外,針對ACL策略的設置方式,筆者做了一些深入的分析,包括各種設置方式的優(yōu)缺點(diǎn)。
OpenSIPS用戶(hù)通過(guò)物理終端可以對ACL設置進(jìn)行呼叫測試。通過(guò)撥打不同的號碼來(lái)檢測ACL的正確性。
參考資料:
www.opensips.org
www.freesbc.cn
www.freepbx.org.cn
- 融合通信/IPPBX/FreePBX商業(yè)解決方案:www.hiastar.com
- 最新Asterisk完整中文用戶(hù)手冊詳解:www.asterisk.org.cn
- Freepbx/FreeSBC技術(shù)文檔: www.freepbx.org.cn
- 如何使用免費會(huì )話(huà)邊界控制器-FreeSBC,qq技術(shù)分享群:334023047
- 關(guān)注微信公眾號:asterisk-cn,獲得有價(jià)值的通信行業(yè)技術(shù)分享